98 lines
3.9 KiB
Markdown
98 lines
3.9 KiB
Markdown
\[ [Index](index.md) | [Exercise 5.4](ex5_4.md) | [Exercise 5.6](ex5_6.md) \]
|
|
|
|
# Exercise 5.5
|
|
|
|
*Objectives:*
|
|
|
|
- Learn more about exception handling and logging
|
|
|
|
*Files Modified:* `reader.py`
|
|
|
|
In the `reader.py` file, there is a central function `convert_csv()` that does
|
|
most of the work. This function crashes if you run it on data with missing or
|
|
bad data. For example:
|
|
|
|
```python
|
|
>>> port = read_csv_as_dicts('Data/missing.csv', types=[str, int, float])
|
|
Traceback (most recent call last):
|
|
File "<stdin>", line 1, in <module>
|
|
File "reader.py", line 24, in read_csv_as_dicts
|
|
return csv_as_dicts(file, types, headers=headers)
|
|
File "reader.py", line 13, in csv_as_dicts
|
|
lambda headers, row: { name: func(val) for name, func, val in zip(headers, types, row) })
|
|
File "reader.py", line 9, in convert_csv
|
|
return list(map(lambda row: converter(headers, row), rows))
|
|
File "reader.py", line 9, in <lambda>
|
|
return list(map(lambda row: converter(headers, row), rows))
|
|
File "reader.py", line 13, in <lambda>
|
|
lambda headers, row: { name: func(val) for name, func, val in zip(headers, types, row) })
|
|
File "reader.py", line 13, in <dictcomp>
|
|
lambda headers, row: { name: func(val) for name, func, val in zip(headers, types, row) })
|
|
ValueError: invalid literal for int() with base 10: ''
|
|
>>>
|
|
```
|
|
|
|
## (a) Catching Exceptions
|
|
|
|
Instead of crashing on bad data, modify the code to issue a warning message
|
|
instead. The final result should be a list of the rows that were successfully
|
|
converted. For example:
|
|
|
|
```python
|
|
>>> port = read_csv_as_dicts('Data/missing.csv', types=[str, int, float])
|
|
Row 4: Bad row: ['C', '', '53.08']
|
|
Row 7: Bad row: ['DIS', '50', 'N/A']
|
|
Row 8: Bad row: ['GE', '', '37.23']
|
|
Row 13: Bad row: ['INTC', '', '21.84']
|
|
Row 17: Bad row: ['MCD', '', '51.11']
|
|
Row 19: Bad row: ['MO', '', '70.09']
|
|
Row 22: Bad row: ['PFE', '', '26.40']
|
|
Row 26: Bad row: ['VZ', '', '42.92']
|
|
>>> len(port)
|
|
20
|
|
>>>
|
|
```
|
|
|
|
Note: Making this change may be a bit tricky because of your previous use of the `map()`
|
|
built-in function. You may have to abandon that approach since there's no easy way to catch
|
|
and handle exceptions in `map()`.
|
|
|
|
## (b) Logging
|
|
|
|
Modify the code so that warning messages are issued using the `logging` module. In
|
|
addition, give optional debugging information indicating the reason for failure.
|
|
For example:
|
|
|
|
```python
|
|
>>> import reader
|
|
>>> import logging
|
|
>>> logging.basicConfig(level=logging.DEBUG)
|
|
>>> port = reader.read_csv_as_dicts('Data/missing.csv', types=[str, int, float])
|
|
WARNING:reader:Row 4: Bad row: ['C', '', '53.08']
|
|
DEBUG:reader:Row 4: Reason: invalid literal for int() with base 10: ''
|
|
WARNING:reader:Row 7: Bad row: ['DIS', '50', 'N/A']
|
|
DEBUG:reader:Row 7: Reason: could not convert string to float: 'N/A'
|
|
WARNING:reader:Row 8: Bad row: ['GE', '', '37.23']
|
|
DEBUG:reader:Row 8: Reason: invalid literal for int() with base 10: ''
|
|
WARNING:reader:Row 13: Bad row: ['INTC', '', '21.84']
|
|
DEBUG:reader:Row 13: Reason: invalid literal for int() with base 10: ''
|
|
WARNING:reader:Row 17: Bad row: ['MCD', '', '51.11']
|
|
DEBUG:reader:Row 17: Reason: invalid literal for int() with base 10: ''
|
|
WARNING:reader:Row 19: Bad row: ['MO', '', '70.09']
|
|
DEBUG:reader:Row 19: Reason: invalid literal for int() with base 10: ''
|
|
WARNING:reader:Row 22: Bad row: ['PFE', '', '26.40']
|
|
DEBUG:reader:Row 22: Reason: invalid literal for int() with base 10: ''
|
|
WARNING:reader:Row 26: Bad row: ['VZ', '', '42.92']
|
|
DEBUG:reader:Row 26: Reason: invalid literal for int() with base 10: ''
|
|
>>>
|
|
```
|
|
|
|
\[ [Solution](soln5_5.md) | [Index](index.md) | [Exercise 5.4](ex5_4.md) | [Exercise 5.6](ex5_6.md) \]
|
|
|
|
----
|
|
`>>>` Advanced Python Mastery
|
|
`...` A course by [dabeaz](https://www.dabeaz.com)
|
|
`...` Copyright 2007-2023
|
|
|
|
. This work is licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)
|