In order to follow the function design recipe, we need to write example calls. Writing these calls using real files would involve creating test files for each of the situations you want to demonstrate. This is fragile, because it means that you can’t just give the program to someone—you need to remember to include the test files in case they want to try your function, and it’s also not optimal because anyone trying to understand the function needs to open the input and output files.
Python provides a class, StringIO, in module io, that can be used as a mock open file. That means that you can read from it using the regular file-reading techniques as if it were a real file. StringIO objects can be used anywhere TextIO are expected.
Here, we create a StringIO object containing the same information as file number_pairs.txt, and read the first line:
| >>> from io import StringIO |
| >>> input_string = '1.3 3.4\n2 4.2\n-1 1\n' |
| >>> infile = StringIO(input_string) |
| >>> infile.readline() |
| '1.3 3.4\n' |
We can also write to StringIO objects as if they were files, and retrieve their contents as a string using method getvalue:
| >>> from io import StringIO |
| >>> outfile = StringIO() |
| >>> outfile.write('1.3 3.4 4.7\n') |
| 12 |
| >>> outfile.write('2 4.2 6.2\n') |
| 10 |
| >>> outfile.write('-1 1 0.0\n') |
| 9 |
| >>> outfile.getvalue() |
| '1.3 3.4 4.7\n2 4.2 6.2\n-1 1 0.0\n' |
We can now provide example calls in our sum_number_pairs function. Notice that we need two backslashes inside the examples because they are part of the docstring (see Using Special Characters in Strings):
| from typing import TextIO |
| from io import StringIO |
| |
| |
| def sum_number_pairs(input_file: TextIO, output_file: TextIO) -> None: |
| """Read the data from input_file, which contains two floats per line |
| separated by a space. output_file for writing and, for each line in |
| input_file, write a line to output_file that contains the two floats from |
| the corresponding line of input_file plus a space and the sum of the two |
| floats. |
| |
| >>> infile = StringIO('1.3 3.4\\n2 4.2\\n-1 1\\n') |
| >>> outfile = StringIO() |
| >>> sum_number_pairs(infile, outfile) |
| >>> outfile.getvalue() |
| '1.3 3.4 4.7\\n2 4.2 6.2\\n-1 1 0.0\\n' |
| """ |
| |
| for number_pair in input_file: |
| number_pair = number_pair.strip() |
| operands = number_pair.split() |
| total = float(operands[0]) + float(operands[1]) |
| new_line = '{0} {1}\n'.format(number_pair, total) |
| output_file.write(new_line) |
| |
| if __name__ == '__main__': |
| with open('number_pairs.txt', 'r') as input_file, \ |
| open('number_pair_sums.txt', 'w') as output_file: |
| sum_number_pairs(input_file, output_file) |