Initial commit
This commit is contained in:
101
Exercises/ex5_3.md
Normal file
101
Exercises/ex5_3.md
Normal file
@@ -0,0 +1,101 @@
|
||||
\[ [Index](index.md) | [Exercise 5.2](ex5_2.md) | [Exercise 5.4](ex5_4.md) \]
|
||||
|
||||
# Exercise 5.3
|
||||
|
||||
*Objectives:*
|
||||
|
||||
- Higher order functions
|
||||
|
||||
*Files Modified:* `reader.py`
|
||||
|
||||
## (a) Using higher-order functions
|
||||
|
||||
At the moment, the `reader.py` program consists of two core functions, `csv_as_dicts()` and
|
||||
`csv_as_instances()`. The code in these two functions is almost identical. For example:
|
||||
|
||||
```python
|
||||
def csv_as_dicts(lines, types, *, headers=None):
|
||||
'''
|
||||
Convert lines of CSV data into a list of dictionaries
|
||||
'''
|
||||
records = []
|
||||
rows = csv.reader(lines)
|
||||
if headers is None:
|
||||
headers = next(rows)
|
||||
for row in rows:
|
||||
record = { name: func(val)
|
||||
for name, func, val in zip(headers, types, row) }
|
||||
records.append(record)
|
||||
return records
|
||||
|
||||
def csv_as_instances(lines, cls, *, headers=None):
|
||||
'''
|
||||
Convert lines of CSV data into a list of instances
|
||||
'''
|
||||
records = []
|
||||
rows = csv.reader(lines)
|
||||
if headers is None:
|
||||
headers = next(rows)
|
||||
for row in rows:
|
||||
record = cls.from_row(row)
|
||||
records.append(record)
|
||||
return records
|
||||
```
|
||||
|
||||
Unify the core of these functions into a single function `convert_csv()` that accepts a user-defined
|
||||
conversion function as an argument. For example:
|
||||
|
||||
```python
|
||||
>>> def make_dict(headers, row):
|
||||
return dict(zip(headers, row))
|
||||
|
||||
>>> lines = open('Data/portfolio.csv')
|
||||
>>> convert_csv(lines, make_dict)
|
||||
[{'name': 'AA', 'shares': '100', 'price': '32.20'}, {'name': 'IBM', 'shares': '50', 'price': '91.10'},
|
||||
{'name': 'CAT', 'shares': '150', 'price': '83.44'}, {'name': 'MSFT', 'shares': '200', 'price': '51.23'},
|
||||
{'name': 'GE', 'shares': '95', 'price': '40.37'}, {'name': 'MSFT', 'shares': '50', 'price': '65.10'},
|
||||
{'name': 'IBM', 'shares': '100', 'price': '70.44'}]
|
||||
>>>
|
||||
```
|
||||
|
||||
Rewrite the `csv_as_dicts()` and `csv_as_instances()` functions in terms of the new `convert_csv()`
|
||||
function.
|
||||
|
||||
## (b) Mapping
|
||||
|
||||
One of the most common operations in functional programming is the `map()` operation that maps a function
|
||||
to the values in a sequence. Python has a built-in `map()` function that does this. For
|
||||
example:
|
||||
|
||||
```python
|
||||
>>> nums = [1,2,3,4]
|
||||
>>> squares = map(lambda x: x*x, nums)
|
||||
>>> for n in squares:
|
||||
print(n)
|
||||
|
||||
1
|
||||
4
|
||||
9
|
||||
16
|
||||
>>>
|
||||
```
|
||||
|
||||
`map()` produces an iterator so if you want a list, you'll need to create it explicitly:
|
||||
|
||||
```python
|
||||
>>> squares = list(map(lambda x: x*x, nums))
|
||||
>>> squares
|
||||
[1, 4, 9, 16]
|
||||
>>>
|
||||
```
|
||||
|
||||
Try to use `map()` in your `convert_csv()` function.
|
||||
|
||||
\[ [Solution](soln5_3.md) | [Index](index.md) | [Exercise 5.2](ex5_2.md) | [Exercise 5.4](ex5_4.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/)
|
||||
Reference in New Issue
Block a user