Compare commits
54 Commits
ac260673ae
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a55856bf89 | ||
|
|
b63b7f6da1 | ||
|
|
510182cb39 | ||
|
|
7c771bd014 | ||
|
|
2d7dfa6718 | ||
|
|
0cfde115ff | ||
|
|
bc3b595cc3 | ||
|
|
1dd925e5b3 | ||
|
|
9e290fd1a8 | ||
|
|
dcf5e16d1f | ||
|
|
97794ae225 | ||
|
|
8471cb3a2f | ||
|
|
3986af80de | ||
|
|
75763875df | ||
|
|
aab6f17470 | ||
|
|
8990494ab4 | ||
|
|
1f6f5566eb | ||
|
|
f2aebe0398 | ||
|
|
1c5c97df36 | ||
|
|
a8e0892301 | ||
|
|
110101705e | ||
|
|
6c742ccf84 | ||
|
|
7a8f6dec0e | ||
|
|
2637086c55 | ||
|
|
a053fa120a | ||
|
|
b865f86b33 | ||
|
|
94e9fdbf52 | ||
|
|
fffcb971e6 | ||
|
|
85c03ffd79 | ||
|
|
48afeb56b5 | ||
|
|
271ed03ff2 | ||
|
|
0eedffd429 | ||
|
|
92d7dc0f93 | ||
|
|
8111013443 | ||
|
|
1d20aaeca8 | ||
|
|
3375d28b4d | ||
|
|
73023e88a1 | ||
|
|
374965dbfb | ||
|
|
a6dd2238a2 | ||
|
|
e414b66f4f | ||
|
|
afec76dd94 | ||
|
|
1e2916e64f | ||
|
|
56dfd08cd6 | ||
|
|
3ac425a715 | ||
|
|
ccfcd4cb9f | ||
|
|
d540e77118 | ||
|
|
397b736762 | ||
|
|
9bb142586b | ||
|
|
558ece5cf5 | ||
|
|
b82efeca2a | ||
|
|
09c35c10df | ||
|
|
c079eb9507 | ||
|
|
393db776e1 | ||
|
|
48df268fa9 |
@@ -152,7 +152,7 @@ The key feature that makes this work is that a defaultdict
|
|||||||
automatically initializes elements for you--allowing an insertion of a
|
automatically initializes elements for you--allowing an insertion of a
|
||||||
new element and an `append()` operation to be combined together.
|
new element and an `append()` operation to be combined together.
|
||||||
|
|
||||||
## (c) Data Analysis Challenge
|
## (d) Data Analysis Challenge
|
||||||
|
|
||||||
In the last exercise you just wrote some code to read CSV-data related
|
In the last exercise you just wrote some code to read CSV-data related
|
||||||
to the Chicago Transit Authority. For example, you can grab the data
|
to the Chicago Transit Authority. For example, you can grab the data
|
||||||
@@ -167,7 +167,7 @@ as dictionaries like this:
|
|||||||
It would be a shame to do all of that work and then do nothing with
|
It would be a shame to do all of that work and then do nothing with
|
||||||
the data.
|
the data.
|
||||||
|
|
||||||
In this exercise, you task is this: write a program to answer the
|
In this exercise, your task is this: write a program to answer the
|
||||||
following three questions:
|
following three questions:
|
||||||
|
|
||||||
1. How many bus routes exist in Chicago?
|
1. How many bus routes exist in Chicago?
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ Watch what happens if you do the for-loop again:
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
>>> for n in squares:
|
>>> for n in squares:
|
||||||
print(n)
|
print(n)
|
||||||
|
|
||||||
>>>
|
>>>
|
||||||
```
|
```
|
||||||
@@ -291,7 +291,7 @@ False
|
|||||||
>>>
|
>>>
|
||||||
```
|
```
|
||||||
|
|
||||||
Here is an subtle use of a generator expression in making comma
|
Here is a subtle use of a generator expression in making comma
|
||||||
separated values:
|
separated values:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ and adding a few more values to it:
|
|||||||
```python
|
```python
|
||||||
>>> row = { 'route': '22', 'date': '01/01/2001', 'daytype': 'U', 'rides': 7354 }
|
>>> row = { 'route': '22', 'date': '01/01/2001', 'daytype': 'U', 'rides': 7354 }
|
||||||
>>> sys.getsizeof(row)
|
>>> sys.getsizeof(row)
|
||||||
>>> sys.getsizeof(row)
|
|
||||||
240
|
240
|
||||||
>>> row['a'] = 1
|
>>> row['a'] = 1
|
||||||
>>> sys.getsizeof(row)
|
>>> sys.getsizeof(row)
|
||||||
@@ -175,7 +174,7 @@ function.
|
|||||||
|
|
||||||
import collections
|
import collections
|
||||||
...
|
...
|
||||||
class RideData(collections.Sequence):
|
class RideData(collections.abc.Sequence):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.routes = [] # Columns
|
self.routes = [] # Columns
|
||||||
self.dates = []
|
self.dates = []
|
||||||
@@ -204,9 +203,9 @@ into 4 separate `append()` operations.
|
|||||||
# readrides.py
|
# readrides.py
|
||||||
...
|
...
|
||||||
|
|
||||||
class RideData(collections.Sequence):
|
class RideData(collections.abc.Sequence):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# Each value is a list with all of the values (a column)
|
# Each value is a list with all the values (a column)
|
||||||
self.routes = []
|
self.routes = []
|
||||||
self.dates = []
|
self.dates = []
|
||||||
self.daytypes = []
|
self.daytypes = []
|
||||||
@@ -297,7 +296,7 @@ the `RideData` class so that it produces a proper slice that
|
|||||||
looks like a list of dictionaries? For example, like this:
|
looks like a list of dictionaries? For example, like this:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
>>> rows = readrides.read_rides_as_columns('Data/ctabus.csv')
|
>>> rows = readrides.read_rides_as_dicts('Data/ctabus.csv')
|
||||||
>>> rows
|
>>> rows
|
||||||
<readrides.RideData object at 0x10f5054a8>
|
<readrides.RideData object at 0x10f5054a8>
|
||||||
>>> len(rows)
|
>>> len(rows)
|
||||||
|
|||||||
@@ -142,7 +142,8 @@ Or, if you wanted to read the CTA data:
|
|||||||
|
|
||||||
## (c) Memory Revisited
|
## (c) Memory Revisited
|
||||||
|
|
||||||
In the CTA bus data, we determined that there were 181 unique bus routes.
|
In [Exercise 2.1](ex2_1.md) we explored memory use and in [Exercise 2.2](ex2_2.md), we
|
||||||
|
determined that there were 181 unique bus routes in Chicago.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
>>> routes = { row['route'] for row in rows }
|
>>> routes = { row['route'] for row in rows }
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ definition?
|
|||||||
|
|
||||||
## (c) Printing a Table
|
## (c) Printing a Table
|
||||||
|
|
||||||
Table the data read in part (b) and use it to make a nicely formatted
|
Take the data read in part (b) and use it to make a nicely formatted
|
||||||
table. For example:
|
table. For example:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ Try it out:
|
|||||||
>>> from tableformat import create_formatter
|
>>> from tableformat import create_formatter
|
||||||
>>> formatter = create_formatter('text')
|
>>> formatter = create_formatter('text')
|
||||||
>>> with redirect_stdout(open('out.txt', 'w')) as file:
|
>>> with redirect_stdout(open('out.txt', 'w')) as file:
|
||||||
tableformat.print_table(portfolio, ['name','shares','price', formatter)
|
tableformat.print_table(portfolio, ['name','shares','price'], formatter)
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
>>> # Inspect the file
|
>>> # Inspect the file
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ kinds of input sources. For example:
|
|||||||
```python
|
```python
|
||||||
>>> import gzip
|
>>> import gzip
|
||||||
>>> import stock
|
>>> import stock
|
||||||
>>> file = gzip.open('Data/portfolio.csv.gz')
|
>>> file = gzip.open('Data/portfolio.csv.gz', 'rt')
|
||||||
>>> port = reader.csv_as_instances(file, stock.Stock)
|
>>> port = reader.csv_as_instances(file, stock.Stock)
|
||||||
>>> port
|
>>> port
|
||||||
[Stock('AA', 100, 32.2), Stock('IBM', 50, 91.1), Stock('CAT', 150, 83.44),
|
[Stock('AA', 100, 32.2), Stock('IBM', 50, 91.1), Stock('CAT', 150, 83.44),
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import stock
|
|||||||
|
|
||||||
class TestStock(unittest.TestCase):
|
class TestStock(unittest.TestCase):
|
||||||
def test_create(self):
|
def test_create(self):
|
||||||
s = Stock('GOOG', 100, 490.1)
|
s = stock.Stock('GOOG', 100, 490.1)
|
||||||
self.assertEqual(s.name, 'GOOG')
|
self.assertEqual(s.name, 'GOOG')
|
||||||
self.assertEqual(s.shares, 100)
|
self.assertEqual(s.shares, 100)
|
||||||
self.assertEqual(s.price, 490.1)
|
self.assertEqual(s.price, 490.1)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
*Files modified:* `structure.py`, `stock.py`
|
*Files modified:* `structure.py`, `stock.py`
|
||||||
|
|
||||||
In the last exercise, you create a class `Structure` that made it easy to define
|
In the last exercise, you created a class `Structure` that made it easy to define
|
||||||
data structures. For example:
|
data structures. For example:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@@ -61,8 +61,9 @@ and class definitions:
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
>>> def _init(locs):
|
>>> def _init(locs):
|
||||||
self = locs.pop('self')
|
self = locs['self']
|
||||||
for name, val in locs.items():
|
for name, val in locs.items():
|
||||||
|
if name == 'self': continue
|
||||||
setattr(self, name, val)
|
setattr(self, name, val)
|
||||||
|
|
||||||
>>> class Stock:
|
>>> class Stock:
|
||||||
@@ -96,8 +97,9 @@ frame hacking. Try this variant of the `_init()` function:
|
|||||||
>>> import sys
|
>>> import sys
|
||||||
>>> def _init():
|
>>> def _init():
|
||||||
locs = sys._getframe(1).f_locals # Get callers local variables
|
locs = sys._getframe(1).f_locals # Get callers local variables
|
||||||
self = locs.pop('self')
|
self = locs['self']
|
||||||
for name, val in locs.items():
|
for name, val in locs.items():
|
||||||
|
if name == 'self': continue
|
||||||
setattr(self, name, val)
|
setattr(self, name, val)
|
||||||
>>>
|
>>>
|
||||||
```
|
```
|
||||||
@@ -135,8 +137,9 @@ class Structure:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def _init():
|
def _init():
|
||||||
locs = sys._getframe(1).f_locals
|
locs = sys._getframe(1).f_locals
|
||||||
self = locs.pop('self')
|
self = locs['self']
|
||||||
for name, val in locs.items():
|
for name, val in locs.items():
|
||||||
|
if name == 'self': continue
|
||||||
setattr(self, name, val)
|
setattr(self, name, val)
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
@@ -160,7 +163,7 @@ class Stock(Structure):
|
|||||||
def cost(self):
|
def cost(self):
|
||||||
return self.shares * self.price
|
return self.shares * self.price
|
||||||
|
|
||||||
def sell(self, nshares):
|
def sell(self, shares):
|
||||||
self.shares -= shares
|
self.shares -= shares
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ class Stock(Structure):
|
|||||||
Stock.create_init()
|
Stock.create_init()
|
||||||
```
|
```
|
||||||
|
|
||||||
The resulting class should work exactly the name way as before:
|
The resulting class should work exactly the same way as before:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
>>> s = Stock(name='GOOG', shares=100, price=490.1)
|
>>> s = Stock(name='GOOG', shares=100, price=490.1)
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
*Objectives:*
|
*Objectives:*
|
||||||
|
|
||||||
- Learn how to define a simple decorator functions.
|
- Learn how to define simple decorator functions.
|
||||||
|
|
||||||
*Files Created:* `logcall.py`
|
*Files Created:* `logcall.py`
|
||||||
|
|
||||||
*Files Modifie:* `validate.py`
|
*Files Modified:* `validate.py`
|
||||||
|
|
||||||
## (a) Your First Decorator
|
## (a) Your First Decorator
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ Calling sub
|
|||||||
|
|
||||||
## (b) A Real Decorator
|
## (b) A Real Decorator
|
||||||
|
|
||||||
In [Exercise 6.6](ex6_6.md), you created a callable class `ValidatedFunction` that
|
In [Exercise 6.5](ex6_5.md), you created a callable class `ValidatedFunction` that
|
||||||
enforced type annotations. Rewrite this class as a decorator function called `validated`.
|
enforced type annotations. Rewrite this class as a decorator function called `validated`.
|
||||||
It should allow you to write code like this:
|
It should allow you to write code like this:
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ class Stock:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Note: This part doesn't involve a lot of code, but there are a lot of low-level
|
Note: This part doesn't involve a lot of code, but there are a lot of low-level
|
||||||
fiddly bits. The solution will look almost the same as for Exercise 6.6. Don't
|
fiddly bits. The solution will look almost the same as for Exercise 6.5. Don't
|
||||||
be shy about looking at solution code though.
|
be shy about looking at solution code though.
|
||||||
|
|
||||||
\[ [Solution](soln7_1.md) | [Index](index.md) | [Exercise 6.5](ex6_5.md) | [Exercise 7.2](ex7_2.md) \]
|
\[ [Solution](soln7_1.md) | [Index](index.md) | [Exercise 6.5](ex6_5.md) | [Exercise 7.2](ex7_2.md) \]
|
||||||
|
|||||||
@@ -165,8 +165,7 @@ a Python reserved word so you have to pick a slightly different name.
|
|||||||
**Discussion**
|
**Discussion**
|
||||||
|
|
||||||
Writing robust decorators is often a lot harder than it looks.
|
Writing robust decorators is often a lot harder than it looks.
|
||||||
Recommended reading:
|
Recommended reading: [How you implemented your Python decorator is wrong](https://github.com/GrahamDumpleton/wrapt/blob/develop/blog/01-how-you-implemented-your-python-decorator-is-wrong.md)
|
||||||
|
|
||||||
|
|
||||||
\[ [Solution](soln7_2.md) | [Index](index.md) | [Exercise 7.1](ex7_1.md) | [Exercise 7.3](ex7_3.md) \]
|
\[ [Solution](soln7_2.md) | [Index](index.md) | [Exercise 7.1](ex7_1.md) | [Exercise 7.3](ex7_3.md) \]
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
# Exercise 1.1 - Solution
|
# Exercise 1.1 - Solution
|
||||||
|
|
||||||
Nothing here. Just follow along with the exercise.
|
Check [here](../Solutions/1_1/art.py)
|
||||||
|
|
||||||
|
|
||||||
[Back](ex1_1.md)
|
|
||||||
|
|||||||
@@ -18,6 +18,15 @@ maps the route name to the total ride count for that route. A `Counter` object
|
|||||||
example, dictionaries of sets, nested dictionaries, etc. You might
|
example, dictionaries of sets, nested dictionaries, etc. You might
|
||||||
need to do this to answer questions 3 and 4.
|
need to do this to answer questions 3 and 4.
|
||||||
|
|
||||||
|
Even though no code is provided, here are some answers to the questions
|
||||||
|
so that you can check your work:
|
||||||
|
|
||||||
|
1. How many bus routes exist in Chicago? (Answer: 181)
|
||||||
|
|
||||||
|
2. How many people rode the number 22 bus on February 2, 2011? (Answer: 5055)
|
||||||
|
|
||||||
|
3. What is the total number of rides taken on each bus route? (Answer: for the top three routes, [('79', 133796763), ('9', 117923787), ('49', 95915008)])
|
||||||
|
|
||||||
|
4. What five bus routes had the greatest ten-year increase in ridership from 2001 to 2011? (Answer: [('15', 2732209), ('147', 2107910), ('66', 1612958), ('12', 1612067), ('14', 1351308)])
|
||||||
|
|
||||||
[Back](ex2_2.md)
|
[Back](ex2_2.md)
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ def read_rides_as_columns(filename):
|
|||||||
# The great "fake"
|
# The great "fake"
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
class RideData(collections.Sequence):
|
class RideData(collections.abc.Sequence):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# Each value is a list with all of the values (a column)
|
# Each value is a list with all of the values (a column)
|
||||||
self.routes = []
|
self.routes = []
|
||||||
|
|||||||
@@ -48,11 +48,10 @@ def read_csv_as_instances(filename, cls, *, headers=None):
|
|||||||
import csv
|
import csv
|
||||||
|
|
||||||
def convert_csv(lines, converter, *, headers=None):
|
def convert_csv(lines, converter, *, headers=None):
|
||||||
records = []
|
|
||||||
rows = csv.reader(lines)
|
rows = csv.reader(lines)
|
||||||
if headers is None:
|
if headers is None:
|
||||||
headers = next(rows)
|
headers = next(rows)
|
||||||
return map(lambda row: converter(headers, row), rows)
|
return list(map(lambda row: converter(headers, row), rows))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,9 @@ class Structure:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def _init():
|
def _init():
|
||||||
locs = sys._getframe(1).f_locals
|
locs = sys._getframe(1).f_locals
|
||||||
self = locs.pop('self')
|
self = locs['self']
|
||||||
for name, val in locs.items():
|
for name, val in locs.items():
|
||||||
|
if name == 'self': continue
|
||||||
setattr(self, name, val)
|
setattr(self, name, val)
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self, name, value):
|
||||||
|
|||||||
@@ -12,8 +12,9 @@ class Structure:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def _init():
|
def _init():
|
||||||
locs = sys._getframe(1).f_locals
|
locs = sys._getframe(1).f_locals
|
||||||
self = locs.pop('self')
|
self = locs['self']
|
||||||
for name, val in locs.items():
|
for name, val in locs.items():
|
||||||
|
if name == 'self': continue
|
||||||
setattr(self, name, val)
|
setattr(self, name, val)
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self, name, value):
|
||||||
|
|||||||
Binary file not shown.
39
README.md
39
README.md
@@ -1,25 +1,33 @@
|
|||||||
# Advanced Python Mastery
|
# Advanced Python Mastery
|
||||||
|
|
||||||
A course by David Beazley (https://www.dabeaz.com)
|
A course by David Beazley (https://www.dabeaz.com)
|
||||||
Copyright (C) 2007-2023
|
Copyright (C) 2007-2024
|
||||||
|
|
||||||
## Synopsis
|
## Synopsis
|
||||||
|
|
||||||
An exercise-driven course on Advanced Python Programming that was
|
An exercise-driven course on Advanced Python Programming that was
|
||||||
battle-tested several hundred times on the corporate-training circuit
|
battle-tested several hundred times on the corporate-training circuit
|
||||||
for more than a decade. Written by David Beazley, author of the
|
for more than a decade. Written by David Beazley, author of the
|
||||||
Python Cookbook, 3rd Edition (O'Reilly) and Python Distilled
|
[Python Cookbook, 3rd Edition](https://www.dabeaz.com/cookbook.html) (O'Reilly) and
|
||||||
|
[Python Distilled](https://www.dabeaz.com/python-distilled/index.html)
|
||||||
(Addison-Wesley). Released under a Creative Commons license. Free of
|
(Addison-Wesley). Released under a Creative Commons license. Free of
|
||||||
ads, tracking, pop-ups, newsletters, and AI.
|
ads, tracking, pop-ups, newsletters, and AI.
|
||||||
|
|
||||||
|
Everything in this course should work with the latest version of
|
||||||
|
Python, but be aware that the course primarily targets the feature set
|
||||||
|
of Python 3.6. As such, certain modern features don't get coverage.
|
||||||
|
Honestly, this shouldn't affect you much unless you're trying to write code
|
||||||
|
that's freakishly clever.
|
||||||
|
|
||||||
## Target Audience
|
## Target Audience
|
||||||
|
|
||||||
This course is for Python programmers who want to move beyond
|
This course is for Python programmers who want to move beyond
|
||||||
short scripts to writing more sophisticated programs. Topics
|
short scripts to writing more sophisticated programs. To do that,
|
||||||
focus on programming techniques that get used in popular libraries and
|
it helps to better understand the programming techniques used
|
||||||
frameworks. The primary goal is to better understand the Python language
|
in popular libraries and frameworks. Thus, this course is mainly
|
||||||
itself so that you can understand other people's code and so that you
|
for programmers who want to build a more complete mental model of the
|
||||||
can apply your newfound knowledge to your own projects.
|
Python language itself and how it works. Ultimately, the goal
|
||||||
|
is to be able to apply this knowledge to your own projects.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
@@ -106,9 +114,24 @@ Python language, not third party libraries or tooling.
|
|||||||
**A:** Mainly, it's an issue of calendar timing and scope. Course
|
**A:** Mainly, it's an issue of calendar timing and scope. Course
|
||||||
material was primarily developed pre-pandemic and represents Python as
|
material was primarily developed pre-pandemic and represents Python as
|
||||||
it was at that time. Some topics (e.g., typing or async) are
|
it was at that time. Some topics (e.g., typing or async) are
|
||||||
sufficiently complex that they would be bettered covered on their own
|
sufficiently complex that they would be better covered on their own
|
||||||
in a separate course.
|
in a separate course.
|
||||||
|
|
||||||
|
**Q: Do you have plans to modernize the course?**
|
||||||
|
|
||||||
|
**A:** It is my intention that everything in the course apply to the
|
||||||
|
latest version of Python. Unless Python makes backwards-incompatible
|
||||||
|
changes to the core language, that should hold. Although the course
|
||||||
|
doesn't cover every new features, I won't rule out future changes. A
|
||||||
|
lot depends on my available time and interest however. So, I make no
|
||||||
|
promises.
|
||||||
|
|
||||||
|
**Q: Why did you release the course?**
|
||||||
|
|
||||||
|
**A:** This course was extensively taught pre-pandemic. Post-pandemic,
|
||||||
|
my teaching has shifted towards projects and CS fundamentals.
|
||||||
|
However, why let a good course just languish on my computer?
|
||||||
|
|
||||||
**Q: How can I help?**
|
**Q: How can I help?**
|
||||||
|
|
||||||
**A:** If you like the course, the best way to support it is to tell
|
**A:** If you like the course, the best way to support it is to tell
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ def portfolio_cost(filename):
|
|||||||
|
|
||||||
# This catches errors in int() and float() conversions above
|
# This catches errors in int() and float() conversions above
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
print("Couldn't parse:", line)
|
print("Couldn't parse:", repr(line))
|
||||||
print("Reason:", e)
|
print("Reason:", e)
|
||||||
|
|
||||||
return total_cost
|
return total_cost
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# readrides.py
|
# readrides.py
|
||||||
|
|
||||||
import csv
|
import csv
|
||||||
|
import collections.abc
|
||||||
|
|
||||||
def read_rides_as_tuples(filename):
|
def read_rides_as_tuples(filename):
|
||||||
'''
|
'''
|
||||||
@@ -88,7 +89,7 @@ def read_rides_as_columns(filename):
|
|||||||
# The great "fake"
|
# The great "fake"
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
class RideData(collections.Sequence):
|
class RideData(collections.abc.Sequence):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# Each value is a list with all of the values (a column)
|
# Each value is a list with all of the values (a column)
|
||||||
self.routes = []
|
self.routes = []
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
# colreader.py
|
# colreader.py
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
|
import collections.abc
|
||||||
import csv
|
import csv
|
||||||
|
|
||||||
class DataCollection(collections.Sequence):
|
class DataCollection(collections.abc.Sequence):
|
||||||
def __init__(self, columns):
|
def __init__(self, columns):
|
||||||
self.column_names = list(columns)
|
self.column_names = list(columns)
|
||||||
self.column_data = list(columns.values())
|
self.column_data = list(columns.values())
|
||||||
@@ -34,4 +35,3 @@ if __name__ == '__main__':
|
|||||||
tracemalloc.start()
|
tracemalloc.start()
|
||||||
data = read_csv_as_columns('../../Data/ctabus.csv', [intern, intern, intern, int])
|
data = read_csv_as_columns('../../Data/ctabus.csv', [intern, intern, intern, int])
|
||||||
print(tracemalloc.get_traced_memory())
|
print(tracemalloc.get_traced_memory())
|
||||||
|
|
||||||
|
|||||||
@@ -9,12 +9,15 @@ def convert_csv(lines, converter, *, headers=None):
|
|||||||
return list(map(lambda row: converter(headers, row), rows))
|
return list(map(lambda row: converter(headers, row), rows))
|
||||||
|
|
||||||
def csv_as_dicts(lines, types, *, headers=None):
|
def csv_as_dicts(lines, types, *, headers=None):
|
||||||
return convert_csv(lines,
|
return convert_csv(lines,
|
||||||
lambda headers, row: { name: func(val) for name, func, val in zip(headers, types, row) })
|
lambda headers, row: {name: func(val) for name, func, val in zip(headers, types, row)},
|
||||||
|
headers=headers)
|
||||||
|
|
||||||
|
|
||||||
def csv_as_instances(lines, cls, *, headers=None):
|
def csv_as_instances(lines, cls, *, headers=None):
|
||||||
return convert_csv(lines,
|
return convert_csv(lines,
|
||||||
lambda headers, row: cls.from_row(row))
|
lambda headers, row: cls.from_row(row),
|
||||||
|
headers=headers)
|
||||||
|
|
||||||
def read_csv_as_dicts(filename, types, *, headers=None):
|
def read_csv_as_dicts(filename, types, *, headers=None):
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -8,8 +8,9 @@ class Structure:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def _init():
|
def _init():
|
||||||
locs = sys._getframe(1).f_locals
|
locs = sys._getframe(1).f_locals
|
||||||
self = locs.pop('self')
|
self = locs['self']
|
||||||
for name, val in locs.items():
|
for name, val in locs.items():
|
||||||
|
if name == 'self': continue
|
||||||
setattr(self, name, val)
|
setattr(self, name, val)
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self, name, value):
|
||||||
|
|||||||
@@ -9,8 +9,9 @@ class Structure:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def _init():
|
def _init():
|
||||||
locs = sys._getframe(1).f_locals
|
locs = sys._getframe(1).f_locals
|
||||||
self = locs.pop('self')
|
self = locs['self']
|
||||||
for name, val in locs.items():
|
for name, val in locs.items():
|
||||||
|
if name == 'self': continue
|
||||||
setattr(self, name, val)
|
setattr(self, name, val)
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self, name, value):
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# tableformat.py
|
# formatter.py
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
def print_table(records, fields, formatter):
|
def print_table(records, fields, formatter):
|
||||||
|
|||||||
Reference in New Issue
Block a user