Q1

In this question, we'll review the basics of file I/O (file input/output) and the various function calls and modes required (this will draw on material from L14).

A

Write a function read_file_contents which takes a string pathname as an argument, and returns a single string that contains all the contents of the file. Don't import any additional packages.

If I have a file random_text.txt, I'll give the full path to this file to the function: contents = read_file_contents("random_text.txt"), and I should get back a single string contents that contains all the contents of the file.

NOTE: Your function should be able to handle errors gracefully! If an error occurs when trying to read from the file, your function should return None (note the capitalization of the first letter).


In [ ]:


In [ ]:
truth = "This is some text.\nMore text, but on a different line!\nInsert your favorite meme here.\n"
pred = read_file_contents("q1data/file1.txt")
assert truth == pred

In [ ]:
retval = -1
try:
    retval = read_file_contents("nonexistent/path.txt")
except:
    assert False
else:
    assert retval is None

B

This time, write a function read_file that takes two arguments: the first is the path to the file (same as before), and the second is an optional boolean argument as_list that defaults to False. When this flag is False (the default), your function should behave identically to read_file_contents. In fact, if as_list is False, you can just call your previous function.

If as_list is True, instead of returning a single string of the file's contents, return a list of strings, where each item in the list is a line from the file.

NOTE: Your function should be able to handle errors gracefully! If an error occurs when trying to read from the file, your function should return None (note the capitalization of the first letter).


In [ ]:


In [ ]:
truth = "Yo dawg, I heard yo and yo dawg like yo-yos.\nSo we put yo dawg in a yo-yo.\nSo yo can yo-yo yo dawg while yo dawg yo-yos, dawg.\nMaximum ridiculousness reached.\n"
pred = read_file("q1data/file2.txt")
assert truth == pred

In [ ]:
truth = ['Yo dawg, I heard yo and yo dawg like yo-yos.\n',
 'So we put yo dawg in a yo-yo.\n',
 'So yo can yo-yo yo dawg while yo dawg yo-yos, dawg.\n',
 'Maximum ridiculousness reached.\n']
pred = read_file("q1data/file2.txt", as_list = True)
for item in truth:
    assert item in pred
for item in pred:
    assert item in truth

In [ ]:
retval = -1
try:
    retval = read_file("another/nonexistent/path.txt")
except:
    assert False
else:
    assert retval is None

C

In this question, you'll read from one file, perform a simple computation, and write the results to a new file.

Write a function count_lines that takes two arguments: the first is a path to a file to read, the second is the path to an output file. Your function will count the number of lines in the file at the first argument, and write this number to a file at the second argument.

Your function should return True on success, and False if an error occurred.

NOTE: Your function should be able to handle errors gracefully! If an error occurs when trying to read from the file or write to the output file, your function should return False.


In [ ]:


In [ ]:
import os.path
assert count_lines("q1data/file1.txt", "q1data/file1_out.txt")
assert os.path.exists("q1data/file1_out.txt")
assert int(open("q1data/file1_out.txt", "r").read()) == 3

In [ ]:
r1 = None
try:
    r1 = count_lines("yet/another/nonexistent/path.txt", "meaningless")
except:
    assert False
else:
    assert not r1

r2 = None
try:
    r2 = count_lines("q1data/file1.txt", "/this/should/throw/an/error.txt")
except:
    assert False
else:
    assert not r2

D

In this question, you'll write a function acount_lines that performs the same operation as before, except in the case that the output file already exists: in this case, you'll append the line count to the file instead of overwriting it, thus preserving any existing previous line counts.

Each new appended line count should be on its own line in the output file. You may need to manually insert newline characters, which are a backslash followed by the letter n: \n

Your function should return True on success, and False if an error occurred.

NOTE: Your function should be able to handle errors gracefully! If an error occurs when trying to read from the file or write to the output file, your function should return False.


In [ ]:


In [ ]:
if os.path.exists("q1data/out_again.txt"):
    os.remove("q1data/out_again.txt")

assert acount_lines("q1data/file1.txt", "q1data/out_again.txt")
assert os.path.exists("q1data/out_again.txt")
assert int(open("q1data/out_again.txt", "r").read()) == 3

In [ ]:
assert acount_lines("q1data/file2.txt", "q1data/out_again.txt")
assert os.path.exists("q1data/out_again.txt")
assert int("".join(open("q1data/out_again.txt", "r").read().split("\n"))) == 34

In [ ]:
r1 = None
try:
    r1 = acount_lines("yet/another/nonexistent/path.txt", "meaningless")
except:
    assert False
else:
    assert not r1

r2 = None
try:
    r2 = acount_lines("q1data/file2.txt", "/this/should/throw/an/error.txt")
except:
    assert False
else:
    assert not r2