\[ [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 ![](https://i.creativecommons.org/l/by-sa/4.0/88x31.png). This work is licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)