Skip to content

Commit f817194

Browse files
committed
my notes
1 parent 3cfe6a2 commit f817194

6 files changed

Lines changed: 228 additions & 2 deletions

File tree

Notes/MyNote.md

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
2+
# 3.1 Scripting
3+
4+
> Also, a little known fact is that Python runs a bit faster if you use functions.
5+
6+
https://stackoverflow.com/questions/11241523/why-does-python-code-run-faster-in-a-function
7+
8+
The short answer is that it is faster to store local variables than globals.
9+
10+
# 3.6 Design Discussion
11+
12+
In this section we reconsider a design decision made earlier.
13+
14+
### Filenames versus Iterables
15+
16+
Compare these two programs that return the same output.
17+
18+
```python
19+
# Provide a filename
20+
def read_data(filename):
21+
records = []
22+
with open(filename) as f:
23+
for line in f:
24+
...
25+
records.append(r)
26+
return records
27+
28+
d = read_data('file.csv')
29+
```
30+
31+
```python
32+
# Provide lines
33+
def read_data(lines):
34+
records = []
35+
for line in lines:
36+
...
37+
records.append(r)
38+
return records
39+
40+
with open('file.csv') as f:
41+
d = read_data(f)
42+
```
43+
44+
* Which of these functions do you prefer? Why?
45+
* Which of these functions is more flexible?
46+
47+
### Deep Idea: "Duck Typing"
48+
49+
[Duck Typing](https://en.wikipedia.org/wiki/Duck_typing) is a computer
50+
programming concept to determine whether an object can be used for a
51+
particular purpose. It is an application of the [duck
52+
test](https://en.wikipedia.org/wiki/Duck_test).
53+
54+
> If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.
55+
56+
In the second version of `read_data()` above, the function expects any
57+
iterable object. Not just the lines of a file.
58+
59+
```python
60+
def read_data(lines):
61+
records = []
62+
for line in lines:
63+
...
64+
records.append(r)
65+
return records
66+
```
67+
68+
This means that we can use it with other *lines*.
69+
70+
```python
71+
# A CSV file
72+
lines = open('data.csv')
73+
data = read_data(lines)
74+
75+
# A zipped file
76+
lines = gzip.open('data.csv.gz','rt')
77+
data = read_data(lines)
78+
79+
# The Standard Input
80+
lines = sys.stdin
81+
data = read_data(lines)
82+
83+
# A list of strings
84+
lines = ['ACME,50,91.1','IBM,75,123.45', ... ]
85+
data = read_data(lines)
86+
```
87+
88+
There is considerable flexibility with this design.
89+
90+
*Question: Should we embrace or fight this flexibility?*
91+
92+
### Library Design Best Practices
93+
94+
Code libraries are often better served by embracing flexibility.
95+
Don't restrict your options. With great flexibility comes great power.
96+
97+
# 5.1 Dictionaries Revisited
98+
99+
### The "Mixin" Pattern
100+
101+
The *Mixin* pattern is a class with a fragment of code.
102+
103+
```python
104+
class Loud:
105+
def noise(self):
106+
return super().noise().upper()
107+
```
108+
109+
This class is not usable in isolation.
110+
It mixes with other classes via inheritance.
111+
112+
```python
113+
class LoudDog(Loud, Dog):
114+
pass
115+
116+
class LoudBike(Loud, Bike):
117+
pass
118+
```
119+
120+
Miraculously, loudness was now implemented just once and reused
121+
in two completely unrelated classes. This sort of trick is one
122+
of the primary uses of multiple inheritance in Python.
123+
124+
### Why `super()`
125+
126+
Always use `super()` when overriding methods.
127+
128+
```python
129+
class Loud:
130+
def noise(self):
131+
return super().noise().upper()
132+
```
133+
134+
`super()` delegates to the *next class* on the MRO.
135+
136+
The tricky bit is that you don't know what it is. You especially don't
137+
know what it is if multiple inheritance is being used.
138+
139+
### Some Cautions
140+
141+
Multiple inheritance is a powerful tool. Remember that with power
142+
comes responsibility. Frameworks / libraries sometimes use it for
143+
advanced features involving composition of components. Now, forget
144+
that you saw that.
145+
146+
147+
# 6.1 Interation Protocol
148+
149+
One important observation about this--generally code is considered
150+
"Pythonic" if it speaks the common vocabulary of how other parts of
151+
Python normally work. For container objects, supporting iteration,
152+
indexing, containment, and other kinds of operators is an important
153+
part of this.
154+
155+
156+
# 6.4 More Generators
157+
158+
### Why Generators
159+
160+
* Many problems are much more clearly expressed in terms of iteration.
161+
* Looping over a collection of items and performing some kind of operation (searching, replacing, modifying, etc.).
162+
* Processing pipelines can be applied to a wide range of data processing problems.
163+
* Better memory efficiency.
164+
* Only produce values when needed.
165+
* Contrast to constructing giant lists.
166+
* Can operate on streaming data
167+
* Generators encourage code reuse
168+
* Separates the *iteration* from code that uses the iteration
169+
* You can build a toolbox of interesting iteration functions and *mix-n-match*.

Solutions/3_18/report.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ def print_report(reportdata):
4040
for row in reportdata:
4141
print('%10s %10d %10.2f %10.2f' % row)
4242

43-
def portfolio_report(portfoliofile, pricefile):
43+
def portfolio_report(portfoliofile, pricefile):
4444
'''
4545
Make a stock report given portfolio and price data files.
4646
'''
47-
# Read data files
47+
# Read data files
4848
portfolio = read_portfolio(portfoliofile)
4949
prices = read_prices(pricefile)
5050

Work/bounce.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
# bounce.py
22
#
33
# Exercise 1.5
4+
5+
6+
height = 100
7+
for bounce in range(1, 11):
8+
height *= 3 / 5
9+
print(bounce, round(height, 4))

Work/mortgage.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,28 @@
11
# mortgage.py
22
#
33
# Exercise 1.7
4+
5+
principal = 500000.0
6+
rate = 0.05
7+
payment = 2684.11
8+
total_paid = 0.0
9+
10+
extra_payment_start_month = 61
11+
extra_payment_end_month = 108
12+
extra_payment = 1000
13+
14+
months = 0
15+
while principal > 0:
16+
months += 1
17+
curr_payment = (payment + extra_payment) if extra_payment_start_month <= months <= extra_payment_end_month else payment
18+
principal = principal * (1+rate/12) - curr_payment
19+
20+
if principal < 0:
21+
curr_payment += principal
22+
principal = 0.0
23+
24+
total_paid = total_paid + curr_payment
25+
print(f'{months} {total_paid:.2f} {principal:.2f}')
26+
27+
print(f'Total paid {total_paid:.2f}')
28+
print(f'Months {months}')

Work/sears.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# sears.py
2+
3+
bill_thickness = 0.11 * 0.001 # Meters (0.11 mm)
4+
sears_height = 442 # Height (meters)
5+
num_bills = 1
6+
day = 1
7+
8+
while num_bills * bill_thickness < sears_height:
9+
print(day, num_bills, num_bills * bill_thickness)
10+
day = day + 1
11+
num_bills = num_bills * 2
12+
13+
print('Number of days', day)
14+
print('Number of bills', num_bills)
15+
print('Final height', num_bills * bill_thickness)

Work/stock.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class Stock:
2+
def __init__(self, name, shares, price):
3+
self.name = name
4+
self.shares = shares
5+
self.price = price
6+
7+
def cost(self):
8+
return self.shares * self.price
9+
10+
def sell(self, shares):
11+
self.shares -= shares

0 commit comments

Comments
 (0)