**Homework 12: File I/O and Error Handling**
**Reed CSCI 121 Spring 2025**
*complete the exercises by 11:59pm on 5/2*
There are only two exercises below. Each are meant to give you a taste of how to handle
some practical aspects of programming. The first exercise on file I/O asks you to write
a simple script that processes a file and produces a similar text output. The other
shows off the feature where your Python program can track and react to errors that might
arise during its execution. Your code can `try` and run some code and handle any
*exceptions* that arise with `except` clauses.
Here, for example, is a simple use of a "try except" block:
~~~ python
success = False
while not success:
try:
x = int(input("Enter an integer: "))
success = True
except:
print("That didn't work. Try again.")
print("You entered "+str(x)+".")
~~~
If, say, the user enters a string that isn't an integer, then a `ValueError`
exception would normally be raised, halting the program after `input` returns
that string. Here, instead, the `except` code catches that error, prints the "Try again."
message, and the loop repeats.
~~~ none
Enter an integer: hello
That didn't work. Try again.
Enter an integer: 45.5
That didn't work. Try again.
Enter an integer: 45
You entered 45.
~~~
Without the error handling, we'd normally see this with the `input`:
~~~ none
Traceback (most recent call last):
File "/Users/jimfix/example.py", line 4, in
x = int(input("Enter an integer: "))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: 'hello'
~~~
(##) `[Hw12 Ex1]` transpose
Consider the contents of a text file that contains a table of integers.
That table consists of a certain number of rows and columns.
The first line of the file contains two numbers, separated by a space, describing the number of rows and the number of columns.
The remaining lines of the file each contain one row of that table, with its columns of numbers separated by commas.
For example, consider the following 3 x 5 table:
| 3 | 1 | 10 | 0 | 17 |
|:--:|:--:|:--:|:-:|:--:|
| -1 | 8 | 33 | 2 | -5 |
| 9 | 12 | 6 | 0 | 0 |
(Please ignore the shading. It is a quirk of this web page's formatting.)
This would be represented as a text file with the contents
~~~
3 5
3,1,10,0,17
-1,8,33,2,-5
9,12,6,0,0
~~~
If read in as a single string on Mac or Linux systems, it would be
~~~
"3 5\n3,1,10,0,17\n-1,8,33,2,-5\n9,12,6,0,0\n"
~~~
(On Windows systems the lines would end with the two special characters `\r\n` instead.)
Write a function `transpose` that takes two strings as parameters.
The first should be the name of a file that contains such a table, one that the function will read.
The second should be the name of a file that it will create and then write into.
It should output the table that results from "flipping" the table over its diagonal,
so that the rows of the input table become the columns of the output table, and vice versa.
For example, it should produce this output for the table above:
~~~
5 3
3,-1,9
1,8,12
10,33,6
0,2,0
17,-5,0
~~~
This corresponds to the table below:
| 3 | -1| 9 |
|:-:|:-:|:-:|
| 1 | 8 | 12|
| 10| 33| 6 |
| 0 | 2 | 0 |
| 17| -5| 0 |
You can assume that the input table has at least one row and one column.
**Note:**
It's okay to use some of the built-in Python functions we've used in other labs for working with strings. For example, you might find `split` and `join` to be very useful here. Another useful one (that I haven't yet explicitly mentioned) is `rstrip`. These are each described below:
* `s.split(c)`: this takes a string `s` and splits it into a list of strings when text in `s` is separated by character `c`. So, for example, `"abe bob dog".split(' ')` gives the list `["abe", "bob", "dog"]`.
* `c.join(sl)`: this takes a list of strings `sl` and builds a single string using character `c` as their separator. So, for example, `','.join(["abe", "bob", "dog"])` gives `"abe,bob,dog"`.
* `s.rstrip()`: gives a string with whitespace characters removed from the end of `s`, if there are any. So `"hello there \n".rstrip()` will be `"hello there"`. This is a platorm-independent way of removing the special line-ending characters on Mac, Linux, and Windows systems.
(##) `[Hw12 Ex2]` function map
Write a function `function_map` that takes a function (say, `f`) as a parameter and an integer (say, `n`) as a parameter.
It should return a list of length `n` describing how that function behaves when given an integer from `0` to `n-1` as input.
If it handles an integer input `i` with no errors, then list item `i` should contain `f(i)`.
If instead `f(i)` leads to an error, the `i`-th item should be `None`.
For example the function fed to `map_function` below divides by 0 when `x` is 2, but gives answers otherwise.
~~~
>>> function_map(lambda x: 10 // (x - 2), 5)
[-5, -10, None, 10, 5]
~~~