forked from bslatkin/effectivepython
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathitem_17.py
executable file
·138 lines (106 loc) · 2.97 KB
/
item_17.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/env python3
# Copyright 2014 Brett Slatkin, Pearson Education Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Preamble to mimick book environment
import logging
from pprint import pprint
from sys import stdout as STDOUT
# Example 1
def normalize(numbers):
total = sum(numbers)
result = []
for value in numbers:
percent = 100 * value / total
result.append(percent)
return result
# Example 2
visits = [15, 35, 80]
percentages = normalize(visits)
print(percentages)
# Example 3
path = 'my_numbers.txt'
with open(path, 'w') as f:
for i in (15, 35, 80):
f.write('%d\n' % i)
def read_visits(data_path):
with open(data_path) as f:
for line in f:
yield int(line)
# Example 4
it = read_visits('my_numbers.txt')
percentages = normalize(it)
print(percentages)
# Example 5
it = read_visits('my_numbers.txt')
print(list(it))
print(list(it)) # Already exhausted
# Example 6
def normalize_copy(numbers):
numbers = list(numbers) # Copy the iterator
total = sum(numbers)
result = []
for value in numbers:
percent = 100 * value / total
result.append(percent)
return result
# Example 7
it = read_visits('my_numbers.txt')
percentages = normalize_copy(it)
print(percentages)
# Example 8
def normalize_func(get_iter):
total = sum(get_iter()) # New iterator
result = []
for value in get_iter(): # New iterator
percent = 100 * value / total
result.append(percent)
return result
# Example 9
percentages = normalize_func(lambda: read_visits(path))
print(percentages)
# Example 10
class ReadVisits(object):
def __init__(self, data_path):
self.data_path = data_path
def __iter__(self):
with open(self.data_path) as f:
for line in f:
yield int(line)
# Example 11
visits = ReadVisits(path)
percentages = normalize(visits)
print(percentages)
# Example 12
def normalize_defensive(numbers):
if iter(numbers) is iter(numbers): # An iterator -- bad!
raise TypeError('Must supply a container')
total = sum(numbers)
result = []
for value in numbers:
percent = 100 * value / total
result.append(percent)
return result
# Example 13
visits = [15, 35, 80]
normalize_defensive(visits) # No error
visits = ReadVisits(path)
normalize_defensive(visits) # No error
# Example 14
try:
it = iter(visits)
normalize_defensive(it)
except:
logging.exception('Expected')
else:
assert False