Skip to content

Commit 9012cbf

Browse files
PythonCHBAnastomose
authored andcommitted
updated mailroom with dicts, Exceptions and tests...
1 parent ee2240f commit 9012cbf

File tree

3 files changed

+13160
-17
lines changed

3 files changed

+13160
-17
lines changed

Solutions/Session04/mailroom.py

100644100755
Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,20 @@ def find_donor(name):
4848
return donor_db.get(key)
4949

5050

51+
def add_donor(name):
52+
"""
53+
add a new donor to the donr db
54+
55+
:param: the name of the donor
56+
57+
:returns: the new Donor data structure
58+
"""
59+
name = name.strip()
60+
donor = (name, [])
61+
donor_db[name.lower()] = donor
62+
return donor
63+
64+
5165
def main_menu_selection():
5266
"""
5367
Print out the main application menu and then read the user input.
@@ -96,56 +110,65 @@ def send_thank_you():
96110
else:
97111
break
98112

99-
# Now prompt the user for a donation amount to apply. Since this is also an exit
100-
# point to the main menu, we want to make sure this is done before mutating the db
101-
# list object.
113+
# Now prompt the user for a donation amount to apply. Since this is
114+
# also an exit point to the main menu, we want to make sure this is
115+
# done before mutating the db .
102116
while True:
103117
amount_str = raw_input("Enter a donation amount (or 'menu' to exit)> ").strip()
104118
if amount_str == "menu":
105119
return
106120
# Make sure amount is a valid amount before leaving the input loop
107-
amount = float(amount_str)
108-
# extra check here -- unliley that someone will type "NaN", but
109-
# it IS possible, and it is a valid floating point number:
110-
# http://en.wikipedia.org/wiki/NaN
111-
if math.isnan(amount) or math.isinf(amount) or round(amount, 2) == 0.00:
121+
try:
122+
amount = float(amount_str)
123+
# extra check here -- unlikely that someone will type "NaN", but
124+
# it IS possible, and it is a valid floating point number:
125+
# http://en.wikipedia.org/wiki/NaN
126+
if math.isnan(amount) or math.isinf(amount) or round(amount, 2) == 0.00:
127+
raise ValueError
128+
# in this case, the ValueError could be raised by the float() call, or by the NaN-check
129+
except ValueError:
112130
print "error: donation amount is invalid\n"
113131
else:
114132
break
115133

116-
# If this is a new user, ensure that the database has the necessary data structure.
134+
# If this is a new user, ensure that the database has the necessary
135+
# data structure.
117136
donor = find_donor(name)
118137
if donor is None:
119-
donor = (name, [])
120-
donor_db.append( donor )
138+
donor = add_donor(name)
121139

122140
# Record the donation
123141
donor[1].append(amount)
124142
print gen_letter(donor)
125143

126144

127145
def sort_key(item):
146+
## used to sort on name in donor_db
128147
return item[1]
129148

130149

131-
def print_donor_report():
150+
def generate_donor_report():
132151
"""
133152
Generate the report of the donors and amounts donated.
153+
154+
:returns: the donor report as a string.
134155
"""
135156
# First, reduce the raw data into a summary list view
136157
report_rows = []
137-
for (name, gifts) in donor_db:
158+
for (name, gifts) in donor_db.values():
138159
total_gifts = sum(gifts)
139160
num_gifts = len(gifts)
140161
avg_gift = total_gifts / num_gifts
141162
report_rows.append( (name, total_gifts, num_gifts, avg_gift) )
142163

143164
#sort the report data
144165
report_rows.sort(key=sort_key)
145-
print "%25s | %11s | %9s | %12s"%("Donor Name","Total Given","Num Gifts","Average Gift")
146-
print "-"*66
166+
report = []
167+
report.append("%25s | %11s | %9s | %12s"%("Donor Name","Total Given","Num Gifts","Average Gift") )
168+
report.append("-"*66)
147169
for row in report_rows:
148-
print "%25s %11.2f %9i %12.2f"%row
170+
report.append("%25s %11.2f %9i %12.2f"%row)
171+
return "\n".join(report)
149172

150173
if __name__ == "__main__":
151174
running = True
@@ -154,7 +177,7 @@ def print_donor_report():
154177
if selection is "1":
155178
send_thank_you()
156179
elif selection is "2":
157-
print_donor_report()
180+
print generate_donor_report()
158181
elif selection is "3":
159182
running = False
160183
else:

0 commit comments

Comments
 (0)