diff --git a/students/DanCornutt/session07/html_render.py b/students/DanCornutt/session07/html_render.py
index b55e22e8..7d662c24 100644
--- a/students/DanCornutt/session07/html_render.py
+++ b/students/DanCornutt/session07/html_render.py
@@ -8,6 +8,7 @@
# This is the framework for the base class
class Element:
tag = "html"
+ indent = 4
def __init__(self, content=None, **kwags):
if content:
diff --git a/students/DanCornutt/session07/test_html_render.py b/students/DanCornutt/session07/test_html_render.py
index 464cd161..6f0f9cd5 100644
--- a/students/DanCornutt/session07/test_html_render.py
+++ b/students/DanCornutt/session07/test_html_render.py
@@ -277,11 +277,13 @@ def test_anchor():
def test_header():
+ """a header"""
"""a horizontal rule with an attribute"""
h2 = H(2, "This is a header!")
file_contents = render_result(h2)
print(file_contents)
assert file_contents == '
This is a header!
'
+
# #####################
# # indentation testing
# # Uncomment for Step 9 -- adding indentation
diff --git a/students/DanCornutt/session09/donor_db_DAC.yaml b/students/DanCornutt/session09/donor_db_DAC.yaml
new file mode 100644
index 00000000..5449b227
--- /dev/null
+++ b/students/DanCornutt/session09/donor_db_DAC.yaml
@@ -0,0 +1,26 @@
+# !!python/object: __main__.Donor
+Fred Jones:
+ donations:
+ - 100.01
+ - 200
+ - 300
+Amy Shumer:
+ donations:
+ - 2000
+ - 4000
+ - 1000
+Billy Bills:
+ donations:
+ - 1020
+ - 20440.55
+ - 300
+Bob Sherlock:
+ donations:
+ - 10
+ - 20
+ - 30
+Tom Johnson:
+ donations:
+ - 100
+ - 200
+ - 900
diff --git a/students/DanCornutt/session09/donor_db_old_DAC.yaml b/students/DanCornutt/session09/donor_db_old_DAC.yaml
new file mode 100644
index 00000000..eb602e29
--- /dev/null
+++ b/students/DanCornutt/session09/donor_db_old_DAC.yaml
@@ -0,0 +1,30 @@
+- fred:
+ name: Fred Jones
+ donations:
+ - 100.01
+ - 200
+ - 300
+- amy:
+ name: Amy Shumer
+ donations:
+ - 2000
+ - 4000
+ - 1000
+- billy:
+ name: Billy Bills
+ donations:
+ - 1020
+ - 20440.55
+ - 300
+- bob:
+ name: Bob Sherlock
+ donations:
+ - 10
+ - 20
+ - 30
+- tom:
+ name: Tom Johnson
+ donations:
+ - 100
+ - 200
+ - 900
diff --git a/students/DanCornutt/session09/mailroom_DAC.py b/students/DanCornutt/session09/mailroom_DAC.py
new file mode 100755
index 00000000..e13ecb40
--- /dev/null
+++ b/students/DanCornutt/session09/mailroom_DAC.py
@@ -0,0 +1,210 @@
+#!/usr/bin/env python3
+
+"""
+mailroom assignment part 2 & 3
+"""
+from operator import itemgetter
+from collections import OrderedDict
+
+
+DONORS = {
+ "Fred Jones": [100.01, 200, 300], "Amy Shumer": [2000, 4000, 1000],
+ "Billy Bills": [1020, 20440.55, 300], "Bob Sherlock": [10, 20, 30],
+ "Tom Johnson": [100, 200, 900]
+ }
+
+WELCOME_PROMPT = (
+ "Welcome to the main menu, please select from the following:\n"
+ "1 - Send Thank You to a single donor.\n"
+ "2 - Create a report from Donor history.\n"
+ "3 - Send letters to all donors.\n"
+ "4 - Modify Donor Database.\n"
+ "5 - Quit\n"
+ )
+
+DATABASE_PROMPT = (
+ "Welcome to the database menu, please select from the following:\n"
+ "1 - See list of donors.\n"
+ "2 - Add new donor or edit existing.\n"
+ "3 - Quit this menu.\n"
+)
+
+
+def check_donor(name):
+ """Returns True if user is in DB. Writes user if write=True
+ :param1: name of donor
+ """
+ return name in DONORS.keys()
+
+def write_donor(name):
+ """Writes thank you email to file"""
+ text = """Dearest {donor}, \n
+ We greatly thank you for your recent contribution of ${recent:.2f}.\n
+ It will go straight to the person who needs it the most, our CEO.\n
+ Please give more next time.\n
+ \tLove,\n
+ \t\t\tThe Team""".format(donor=name, recent=DONORS[name][-1])
+ with open(name.replace(" ","") + "_thank_you.txt", 'w') as f_out:
+ f_out.write(text)
+
+
+def thank_you(donor="", all_users=False):
+ """Writes thank you letter to file, if all_users is True write letters for all users in database
+ """
+ if all_users:
+ for d in DONORS:
+ write_donor(d)
+ else:
+ donor = input("Type Donor Name =>").title()
+ if check_donor(donor):
+ write_donor(donor)
+ else:
+ print("Sorry I could not find the donor, exiting...")
+
+
+def donor_db():
+ """Editing Donor Menu"""
+ menu_selection(DATABASE_PROMPT, DATABASE_DISPATCH)
+
+
+def edit_donor():
+ answer = input("input donor name=> ").strip().title()
+ if answer:
+ add_donation(answer)
+ else:
+ print("The name must be letters only, returning...")
+ thank_you()
+
+def add_donation(donor_name):
+ """adds donation to donor records, adds donor if new donor
+
+ :param1: donar name
+ """
+ donation = add_money()
+ if donation:
+ DONORS.setdefault(donor_name, []).append(donation)
+ print(
+ "Thank you {} for your donation of ${:,.2f} dollars!".format(
+ donor_name, donation)
+ )
+
+
+def add_money():
+ """Takes input from user, validates donation
+
+ :returns: donation amount or None if donation is invalid.
+ """
+ donation = input("Please enter the donor amount larger than 0.01 => $")
+ try:
+ if float(donation) < 0.01:
+ raise ValueError
+ except ValueError:
+ print("Donation Error, numbers only. Value must be number greater than 0.01")
+ return None
+ else:
+ return float(donation)
+
+
+def thank_you_all():
+ """Writes thank you email to all users"""
+ thank_you(all_users=True)
+
+
+def report():
+ """Finds column widths, sorts donors based on amount donated.
+ :returns: report string
+ """
+ rpt_sheet = []
+ len_col = OrderedDict({
+ "n_size": len("Donor Name"),
+ "t_size" : len("Total Given"),
+ "ng_size": len("Num Gifts"),
+ "ag_size": len("Average Gift")
+ })
+
+ for d in DONORS.items():
+ if len(d[0]) > len_col["n_size"]:
+ len_col["n_size"] = len(d[0])
+ if len(str(sum(d[1]))) > len_col["t_size"]:
+ len_col["Tt_size"] = len(str(sum(d[1])))
+ if len((d[1])) > len_col["ng_size"]:
+ len_col["ng_size"] = len((d[1]))
+ if len(str(sum(d[1])/len(d[1]))) > len_col["ag_size"]:
+ len_col["ag_size"] = len(str(sum(d[1])/len(d[1])))
+ rpt_sheet.append((d[0], sum(d[1]), len(d[1]), sum(d[1])/len(d[1])))
+ rpt_sheet.sort(key=return_total, reverse=True)
+
+ sheet = (
+ "{nm:{mnm}} | {tot:<{mtot}} | {ng:<{mng}} | {ag:<{mag}}\n{header}".format(
+ nm="Donor Name", mnm=len_col["n_size"],
+ tot="Total Given", mtot=len_col["t_size"],
+ ng="Num Gifts", mng=len_col['ng_size'],
+ ag="Average Gift", mag=len_col["ag_size"],
+ header=("-" * sum(len_col.values()))
+ )
+ )
+ for d in rpt_sheet:
+ sheet = sheet + (
+ "\n{n:{n_size}} |${t:>{t_size},.2f} | {ng:>{ng_size}} |$ {avg_g:<{ag_size},.2f}"
+ .format(
+ n=d[0], n_size=len_col['n_size'],
+ t=d[1], t_size=len_col['t_size'],
+ ng=d[2], ng_size=len_col['ng_size'],
+ avg_g=d[3], ag_size=len_col['ag_size']
+ )
+ )
+ return sheet
+
+
+def make_report():
+ """Prints report"""
+ info = report()
+ print(info)
+ print(sheet)
+
+def return_total(elem):
+ """sorting function for list"""
+ return elem[1]
+
+
+def donor_list():
+ """prints donor in dict"""
+ for k in DONORS:
+ print(k)
+
+
+def unknown():
+ """Handles unknown user input"""
+ print("That is not a valid response!")
+
+
+def quit_menu():
+ """Quits menu, returns 'exit menu'. """
+ print("Quitting this menu now.")
+ return "exit menu"
+
+
+def menu_selection(prompt, dispatch_dict):
+ """dispatch function for mailroom"""
+ while True: #this loops forever, until quit is selected
+ response = input(prompt).strip()
+ response = response[:1].lower()
+ if dispatch_dict.get(response, unknown)() == "exit menu":
+ break
+
+MAIN_DISPATCH = {
+ "1": thank_you,
+ "2": make_report,
+ "3": thank_you_all,
+ "4": donor_db,
+ "5": quit_menu,
+ }
+
+DATABASE_DISPATCH = {
+ "1": donor_list,
+ "2": edit_donor,
+ "3": quit_menu
+}
+
+if __name__ == "__main__":
+ menu_selection(WELCOME_PROMPT, MAIN_DISPATCH)
diff --git a/students/DanCornutt/session09/mailroom_oo.py b/students/DanCornutt/session09/mailroom_oo.py
new file mode 100644
index 00000000..ef6dbfa9
--- /dev/null
+++ b/students/DanCornutt/session09/mailroom_oo.py
@@ -0,0 +1,100 @@
+#!usr/bin/#!/usr/bin/env python
+"""mailroom_oo module contains data objects donor and donor_collection to handle
+all required operations for the mailroom script. User inputs are handled
+elsewhere."""
+
+# └── mailroom_oo
+# ├── __init__.py - empty for init
+# ├── cli_main.py - user interface file
+# ├── donor_models.py - data file
+# └── test_mailroom_oo.py - test file
+
+import os
+import yaml
+
+
+class Donor:
+ """Donor class handles all data, opperations, and attributes needed for
+ donors."""
+ def __init__(self, name, donations=None):
+ self.name = name
+ if donations:
+ self.donations = donations
+ else:
+ self.donations = []
+
+ def add_donation(self, donation):
+ """Adds donation from donor to donor DB
+ parma1: donation (number)"""
+ self.donations.append(donation)
+
+ @property
+ def num_donations(self):
+ """Returns number of donations."""
+ return len(self.donations)
+
+ @property
+ def donor_name(self):
+ """Returns name of donor."""
+ return self.name
+
+ @property
+ def last_donation(self):
+ """Returns last donation or None if no donations."""
+ if self.num_donations:
+ return self.donations[-1]
+ else: return None
+
+ @property
+ def avg_donation(self):
+ """Returns average donor donation or None if no donations."""
+ if self.num_donations:
+ return self.sum_donations/self.num_donations
+ else: return None
+
+ @property
+ def sum_donations(self):
+ """Returns total amount donated."""
+ return sum(self.donations)
+
+ def write_letter(self):
+ """Writes thank you letter for donor's last donation. Returns string."""
+ text = """Dearest {donor},
+ We greatly thank you for your recent contribution of ${recent:.2f}.
+ It will go straight to the person who needs it the most, our CEO.
+ Please give more next time.
+ Love,
+ The Team""".format(donor=self.name, recent=self.last_donation)
+ return text
+
+
+#report - sort key needed
+#thank you letters - return list of strings
+#check donor if needed elsewhere
+
+#user interface code for input and prints
+
+class Donor_Collection:
+ def __init__(self):
+ self.name = "donor_db_object"
+ self.db = {}
+ data = yaml.load(open("donor_db.yaml"))
+
+ for k,v in data.items():
+ self.add_donor(k,v)
+
+
+ def add_donor(self, name, donations=None):
+ """Adds donor to database."""
+ print(name, donations)
+ self.db[name] = Donor(name, donations['donations'])
+
+
+ def list_donors(self):
+ """Returns list of all donors in database."""
+ donors_str = ""
+ for person in self.db.keys():
+ print(person)
+ donors_str.join(person + "\n")
+
+donors = Donor_Collection()
diff --git a/students/DanCornutt/session09/mailroom_oo/__init__.py b/students/DanCornutt/session09/mailroom_oo/__init__.py
new file mode 100644
index 00000000..5becc17c
--- /dev/null
+++ b/students/DanCornutt/session09/mailroom_oo/__init__.py
@@ -0,0 +1 @@
+__version__ = "1.0.0"
diff --git a/students/DanCornutt/session09/mailroom_oo/cli_main.py b/students/DanCornutt/session09/mailroom_oo/cli_main.py
new file mode 100644
index 00000000..e9a2f5ec
--- /dev/null
+++ b/students/DanCornutt/session09/mailroom_oo/cli_main.py
@@ -0,0 +1,205 @@
+#!/usr/bin/env python3
+
+"""
+mailroom assignment [-1]
+"""
+from operator import itemgetter
+from collections import OrderedDict
+from mailroom_oo.donor_models import Donor_Collection
+from mailroom_oo.donor_models import Donor
+
+WELCOME_PROMPT = (
+ "\nWelcome to the main menu, please select from the following:\n"
+ "1 - Send Thank You to a single donor.\n"
+ "2 - Create a report from Donor history.\n"
+ "3 - Send letters to all donors.\n"
+ "4 - Modify Donor Database.\n"
+ "5 - Quit\n"
+ )
+
+DATABASE_PROMPT = (
+ "\nWelcome to the database menu, please select from the following:\n"
+ "1 - See list of donors.\n"
+ "2 - Add new donor or edit existing.\n"
+ "3 - Quit this menu.\n"
+)
+
+## TODO: Return donor with dict.get -- returns donor or none if not found
+def check_donor(name):
+ """Returns True if user is in DB.
+ :param1: name of donor
+ """
+ return name in DONORS.db.keys()
+
+
+def gen_letter(name):
+ return DONORS.db[name].write_letter()
+
+def write_donor(name):
+ """Writes thank you letter to file"""
+ with open(name.replace(" ", "") + "_thank_you.txt", 'w') as f_out:
+ f_out.write(gen_letter(name))
+
+
+def thank_you(donor="", all_users=False):
+ """Writes thank you letter to file, if all_users is True write letters for all users in database
+ """
+ if all_users:
+ for d in DONORS.db.keys():
+ write_donor(d)
+ else:
+ donor = input("Type Donor Name =>").title()
+ if check_donor(donor):
+ write_donor(donor)
+ else:
+ print("Sorry I could not find the donor, exiting...\n")
+
+def donor_db():
+ """Editing Donor Menu"""
+ menu_selection(DATABASE_PROMPT, DATABASE_DISPATCH)
+
+
+def edit_donor():
+ answer = input("input donor name=> ").strip().title()
+ if answer:
+ add_donation(answer)
+ else:
+ print("The name must be letters only, returning...")
+
+def add_donation(donor_name):
+ """adds donation to donor records, adds donor if new donor
+
+ :param1: donar name
+ """
+ donation = add_money()
+ if donation:
+ #TODO might break at setdefault, also make alter to check it you want to add donor
+ if not donor_name in DONORS.db.keys():
+ DONORS.db[donor_name] = Donor(donor_name, donation)
+ else:
+ DONORS.db[donor_name].add_donation(donation)
+ print(
+ "Thank you {} for your donation of ${:,.2f} dollars!".format(
+ donor_name, donation)
+ )
+
+
+def add_money():
+ """Takes input from user, validates donation
+
+ :returns: donation amount or None if donation is invalid.
+ """
+ donation = input("Please enter the donor amount larger than 0.01 => $")
+ try:
+ if float(donation) < 0.01:
+ raise ValueError
+ except ValueError:
+ print("Donation Error, numbers only. Value must be number greater than 0.01")
+ return None
+ else:
+ return float(donation)
+
+
+def thank_you_all():
+ """Writes thank you email to all users"""
+ thank_you(all_users=True)
+
+
+def report():
+ """Finds column widths, sorts donors based on amount donated.
+ :returns: report string
+ """
+ rpt_sheet = []
+ len_col = OrderedDict({
+ "n_size": len("Donor Name"),
+ "t_size" : len("Total Given"),
+ "ng_size": len("Num Gifts"),
+ "ag_size": len("Average Gift"),
+ "nm": "Donor Name",
+ "tot": "Total Given",
+ "ng": "Num Gifts",
+ "ag": "Average Gift"
+ })
+
+ for name, d in DONORS.db.items():
+ #finds max column sizes
+ if len(d.donor_name) > len_col["n_size"]:
+ len_col["n_size"] = len(d.donor_name)
+ if len(str(d.sum_donations)) > len_col["t_size"]:
+ len_col["t_size"] = len(str(d.sum_donations))
+ if len(str(d.num_donations)) > len_col["ng_size"]:
+ len_col["ng_size"] = len(str(d.num_donations))
+ if len(str(d.avg_donation)) > len_col["ag_size"]:
+ len_col["ag_size"] = len(str(d.avg_donation))
+ #creates report data
+ rpt_sheet.append((
+ d.donor_name, d.sum_donations, d.num_donations, d.avg_donation
+ ))
+ rpt_sheet.sort(key=return_total, reverse=True)
+
+ #compiles data into wanted format
+ #header
+ sheet = (
+ "{nm:{n_size}} | {tot:{t_size}} | {ng:{ng_size}} |{ag:<{ag_size}}\n".format(
+ **len_col) + ("-" * sum(list(len_col.values())[:4]))
+ )
+ #data
+ for d in rpt_sheet:
+ sheet = sheet + (
+ "\n{:{n_size}} |${:>{t_size},.2f} | {:>{ng_size}} |$ {:<{ag_size},.2f}"
+ .format(*d, **len_col)
+ )
+ return sheet
+
+
+def make_report():
+ """Prints report"""
+ info = report()
+ print(info)
+
+def return_total(elem):
+ """sorting function for list"""
+ return elem[1]
+
+
+def donor_list():
+ """prints donor in dict"""
+ DONORS.list_donors()
+
+
+def unknown():
+ """Handles unknown user input"""
+ print("That is not a valid response!")
+
+
+def quit_menu():
+ """Quits menu, returns 'exit menu'. """
+ print("Quitting this menu now.")
+ return "exit menu"
+
+
+def menu_selection(prompt, dispatch_dict):
+ """dispatch function for mailroom"""
+ while True: #this loops forever, until quit is selected
+ response = input(prompt).strip()
+ response = response[:1].lower()
+ if dispatch_dict.get(response, unknown)() == "exit menu":
+ break
+
+MAIN_DISPATCH = {
+ "1": thank_you,
+ "2": make_report,
+ "3": thank_you_all,
+ "4": donor_db,
+ "5": quit_menu,
+ }
+
+DATABASE_DISPATCH = {
+ "1": donor_list,
+ "2": edit_donor,
+ "3": quit_menu
+}
+
+if __name__ == "__main__":
+ DONORS = Donor_Collection()
+ menu_selection(WELCOME_PROMPT, MAIN_DISPATCH)
diff --git a/students/DanCornutt/session09/mailroom_oo/donor_db.yaml b/students/DanCornutt/session09/mailroom_oo/donor_db.yaml
new file mode 100644
index 00000000..5449b227
--- /dev/null
+++ b/students/DanCornutt/session09/mailroom_oo/donor_db.yaml
@@ -0,0 +1,26 @@
+# !!python/object: __main__.Donor
+Fred Jones:
+ donations:
+ - 100.01
+ - 200
+ - 300
+Amy Shumer:
+ donations:
+ - 2000
+ - 4000
+ - 1000
+Billy Bills:
+ donations:
+ - 1020
+ - 20440.55
+ - 300
+Bob Sherlock:
+ donations:
+ - 10
+ - 20
+ - 30
+Tom Johnson:
+ donations:
+ - 100
+ - 200
+ - 900
diff --git a/students/DanCornutt/session09/mailroom_oo/donor_models.py b/students/DanCornutt/session09/mailroom_oo/donor_models.py
new file mode 100644
index 00000000..3ea567b6
--- /dev/null
+++ b/students/DanCornutt/session09/mailroom_oo/donor_models.py
@@ -0,0 +1,95 @@
+#!usr/bin/#!/usr/bin/env python
+"""mailroom_oo module contains data objects donor and donor_collection to handle
+all required operations for the mailroom script. User inputs are handled
+elsewhere."""
+
+# └── mailroom_oo
+# ├── __init__.py - empty for init
+# ├── cli_main.py - user interface file
+# ├── donor_models.py - data file
+# └── test_mailroom_oo.py - test file
+
+import yaml
+
+
+class Donor:
+ """Donor class handles all data, opperations, and attributes needed for
+ donors."""
+ def __init__(self, name, donation=None):
+ self.name = name
+ if not donation:
+ self.donoations = []
+ elif isinstance(donation, list):
+ self.donations = donation
+ else:
+ self.donations = [donation,]
+
+
+
+ def add_donation(self, donation):
+ """Adds donation from donor to donor DB
+ parma1: donation (number)"""
+ self.donations.append(donation)
+
+ @property
+ def num_donations(self):
+ """Returns number of donations."""
+ return len(self.donations)
+
+ @property
+ def donor_name(self):
+ """Returns name of donor."""
+ return self.name
+
+ @property
+ def last_donation(self):
+ """Returns last donation or None if no donations."""
+ if self.num_donations:
+ return self.donations[-1]
+ else: return None
+
+ @property
+ def avg_donation(self):
+ """Returns average donor donation or None if no donations."""
+ if self.num_donations:
+ return self.sum_donations/self.num_donations
+ else: return None
+
+ @property
+ def sum_donations(self):
+ """Returns total amount donated."""
+ print(type(self.donations), self.donations)
+ return sum(self.donations)
+
+ def write_letter(self):
+ """Writes thank you letter for donor's last donation. Returns string."""
+ text = """Dearest {donor},
+ We greatly thank you for your recent contribution of ${recent:.2f}.
+ It will go straight to the person who needs it the most, our CEO.
+ Please give more next time.
+ Love,
+ The Team""".format(donor=self.name, recent=self.last_donation)
+ return text
+
+
+class Donor_Collection:
+ def __init__(self):
+ self.name = "donor_db_object"
+ self.db = {}
+ data = yaml.load(open("donor_db.yaml"))
+
+ for k, v in data.items():
+ self.add_donor(k, v)
+
+
+ def add_donor(self, name, donations=None):
+ """Adds donor to database."""
+ self.db[name] = Donor(name, donations['donations'])
+
+
+ def list_donors(self):
+ """Returns string of all donors in database."""
+ donors_str = ""
+ for person in sorted(self.db.keys()):
+ print(person)
+ donors_str.join(person + "\n")
diff --git a/students/DanCornutt/session09/mailroom_oo/mailroom.py b/students/DanCornutt/session09/mailroom_oo/mailroom.py
new file mode 100644
index 00000000..4717facf
--- /dev/null
+++ b/students/DanCornutt/session09/mailroom_oo/mailroom.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+
+
+import cli_main
+
+if __name__ == "__main__":
+ cli_main.main()
diff --git a/students/DanCornutt/session09/mailroom_oo/mailroom_oo.py b/students/DanCornutt/session09/mailroom_oo/mailroom_oo.py
new file mode 100644
index 00000000..c10da2f2
--- /dev/null
+++ b/students/DanCornutt/session09/mailroom_oo/mailroom_oo.py
@@ -0,0 +1,101 @@
+#!usr/bin/#!/usr/bin/env python
+"""mailroom_oo module contains data objects donor and donor_collection to handle
+all required operations for the mailroom script. User inputs are handled
+elsewhere."""
+
+# └── mailroom_oo
+# ├── __init__.py - empty for init
+# ├── cli_main.py - user interface file
+# ├── donor_models.py - data file
+# └── test_mailroom_oo.py - test file
+
+import os
+import yaml
+
+
+class Donor:
+ """Donor class handles all data, opperations, and attributes needed for
+ donors."""
+ def __init__(self, name, donations=None):
+ self.name = name
+ if donations:
+ self.donations = donations
+ else:
+ self.donations = []
+
+ def add_donation(self, donation):
+ """Adds donation from donor to donor DB
+ parma1: donation (number)"""
+ self.donations.append(donation)
+
+ @property
+ def num_donations(self):
+ """Returns number of donations."""
+ return len(self.donations)
+
+ @property
+ def donor_name(self):
+ """Returns name of donor."""
+ return self.name
+
+ @property
+ def last_donation(self):
+ """Returns last donation or None if no donations."""
+ if self.num_donations:
+ return self.donations[-1]
+ else: return None
+
+ @property
+ def avg_donation(self):
+ """Returns average donor donation or None if no donations."""
+ if self.num_donations:
+ return self.sum_donations/self.num_donations
+ else: return None
+
+ @property
+ def sum_donations(self):
+ """Returns total amount donated."""
+ return sum(self.donations)
+
+ def write_letter(self):
+ """Writes thank you letter for donor's last donation. Returns string."""
+ text = """Dearest {donor},
+ We greatly thank you for your recent contribution of ${recent:.2f}.
+ It will go straight to the person who needs it the most, our CEO.
+ Please give more next time.
+ Love,
+ The Team""".format(donor=self.name, recent=self.last_donation)
+ return text
+
+
+#report - sort key needed
+#thank you letters - return list of strings
+#check donor if needed elsewhere
+
+
+#user interface code for input and prints
+
+class Donor_Collection:
+ def __init__(self):
+ self.name = "donor_db_object"
+ self.db = {}
+ data = yaml.load(open("donor_db.yaml"))
+
+ for k,v in data.items():
+ self.add_donor(k,v)
+
+
+ def add_donor(self, name, donations=None):
+ """Adds donor to database."""
+ print(name, donations)
+ self.db[name] = Donor(name, donations['donations'])
+
+
+ def list_donors(self):
+ """Returns list of all donors in database."""
+ donors_str = ""
+ for person in self.db.keys():
+ print(person)
+ donors_str.join(person + "\n")
+
+donors = Donor_Collection()
diff --git a/students/DanCornutt/session09/mailroom_oo/test_donor_models.py b/students/DanCornutt/session09/mailroom_oo/test_donor_models.py
new file mode 100644
index 00000000..16ddef42
--- /dev/null
+++ b/students/DanCornutt/session09/mailroom_oo/test_donor_models.py
@@ -0,0 +1,10 @@
+from .donor_models import
+
+
+
+def test_find_or_create_donor():
+ """test one that's not there"""
+ donor = sample_db.test_find_or_create_donor("Bob Jones")
+
+ assert donor.name == "Bob Jones"
+ assert donor.last_donation is None
diff --git a/students/DanCornutt/session09/mailroom_oo/test_mailroom_oo.py b/students/DanCornutt/session09/mailroom_oo/test_mailroom_oo.py
new file mode 100644
index 00000000..bcc08a97
--- /dev/null
+++ b/students/DanCornutt/session09/mailroom_oo/test_mailroom_oo.py
@@ -0,0 +1,47 @@
+import os
+from mailroom_oo import Donor
+
+def test_create_donor():
+ donor = Donor("Fred Flintstone")
+ assert donor.name == "Fred Flintstone"
+
+def test_add_donation():
+ donor = Donor("Fred Flintstone")
+ donor.add_donation(500)
+ assert donor.num_donations == 1
+
+def test_last_donation():
+ donor = Donor("Fred Flintstone")
+ donor.add_donation(500)
+ assert donor.last_donation == 500
+
+def test_num_donations():
+ donor = Donor("Fred Flintstone")
+ donor.add_donation(500)
+ donor.add_donation(10)
+ assert donor.num_donations == 2
+
+def test_donor_thank_you_letter():
+ Fred = Donor("Fred Flintstone")
+ Fred.add_donation(500)
+ Fred.add_donation(10)
+
+ assert Fred.write_letter == """Dearest Fred Flintstone,
+ We greatly thank you for your recent contribution of $10.00.
+ It will go straight to the person who needs it the most, our CEO.
+ Please give more next time.
+ Love,
+ The Team"""
+
+def test_donor_collection():
+ dc = Donor_Collection()
+ assert len(dc.db) == 6
+
+
+
+
+ # dc.add_donor(Donor("Bob"))
+ # dc.find_donor()
+ # dc.list_donors()
+ # dc.thank_donors()
+ # dc.create_report()
diff --git a/students/DanCornutt/session09/mailroom_oo_DAC.py b/students/DanCornutt/session09/mailroom_oo_DAC.py
new file mode 100644
index 00000000..ef6dbfa9
--- /dev/null
+++ b/students/DanCornutt/session09/mailroom_oo_DAC.py
@@ -0,0 +1,100 @@
+#!usr/bin/#!/usr/bin/env python
+"""mailroom_oo module contains data objects donor and donor_collection to handle
+all required operations for the mailroom script. User inputs are handled
+elsewhere."""
+
+# └── mailroom_oo
+# ├── __init__.py - empty for init
+# ├── cli_main.py - user interface file
+# ├── donor_models.py - data file
+# └── test_mailroom_oo.py - test file
+
+import os
+import yaml
+
+
+class Donor:
+ """Donor class handles all data, opperations, and attributes needed for
+ donors."""
+ def __init__(self, name, donations=None):
+ self.name = name
+ if donations:
+ self.donations = donations
+ else:
+ self.donations = []
+
+ def add_donation(self, donation):
+ """Adds donation from donor to donor DB
+ parma1: donation (number)"""
+ self.donations.append(donation)
+
+ @property
+ def num_donations(self):
+ """Returns number of donations."""
+ return len(self.donations)
+
+ @property
+ def donor_name(self):
+ """Returns name of donor."""
+ return self.name
+
+ @property
+ def last_donation(self):
+ """Returns last donation or None if no donations."""
+ if self.num_donations:
+ return self.donations[-1]
+ else: return None
+
+ @property
+ def avg_donation(self):
+ """Returns average donor donation or None if no donations."""
+ if self.num_donations:
+ return self.sum_donations/self.num_donations
+ else: return None
+
+ @property
+ def sum_donations(self):
+ """Returns total amount donated."""
+ return sum(self.donations)
+
+ def write_letter(self):
+ """Writes thank you letter for donor's last donation. Returns string."""
+ text = """Dearest {donor},
+ We greatly thank you for your recent contribution of ${recent:.2f}.
+ It will go straight to the person who needs it the most, our CEO.
+ Please give more next time.
+ Love,
+ The Team""".format(donor=self.name, recent=self.last_donation)
+ return text
+
+
+#report - sort key needed
+#thank you letters - return list of strings
+#check donor if needed elsewhere
+
+#user interface code for input and prints
+
+class Donor_Collection:
+ def __init__(self):
+ self.name = "donor_db_object"
+ self.db = {}
+ data = yaml.load(open("donor_db.yaml"))
+
+ for k,v in data.items():
+ self.add_donor(k,v)
+
+
+ def add_donor(self, name, donations=None):
+ """Adds donor to database."""
+ print(name, donations)
+ self.db[name] = Donor(name, donations['donations'])
+
+
+ def list_donors(self):
+ """Returns list of all donors in database."""
+ donors_str = ""
+ for person in self.db.keys():
+ print(person)
+ donors_str.join(person + "\n")
+
+donors = Donor_Collection()
diff --git a/students/DanCornutt/session09/test_mailroom_oo_DAC.py b/students/DanCornutt/session09/test_mailroom_oo_DAC.py
new file mode 100644
index 00000000..a27216bc
--- /dev/null
+++ b/students/DanCornutt/session09/test_mailroom_oo_DAC.py
@@ -0,0 +1,47 @@
+import os
+from mailroom_oo import Donor
+
+def test_create_donor():
+ donor = Donor("Fred Flintstone")
+ assert donor.name == "Fred Flintstone"
+
+def test_add_donation():
+ donor = Donor("Fred Flintstone")
+ donor.add_donation(500)
+ assert donor.num_donations == 1
+
+def test_last_donation():
+ donor = Donor("Fred Flintstone")
+ donor.add_donation(500)
+ assert donor.last_donation == 500
+
+def test_num_donations():
+ donor = Donor("Fred Flintstone")
+ donor.add_donation(500)
+ donor.add_donation(10)
+ assert donor.num_donations == 2
+
+def test_donor_thank_you_letter():
+ Fred = Donor("Fred Flintstone")
+ Fred.add_donation(500)
+ Fred.add_donation(10)
+
+ assert Fred.write_letter == """Dearest Fred Flintstone,
+ We greatly thank you for your recent contribution of $10.00.
+ It will go straight to the person who needs it the most, our CEO.
+ Please give more next time.
+ Love,
+ The Team"""
+
+def test_donor_collection():
+ dc = Donor_Collection()
+ assert len(dc.db) == 0
+
+
+
+
+ # dc.add_donor(Donor("Bob"))
+ # dc.find_donor()
+ # dc.list_donors()
+ # dc.thank_donors()
+ # dc.create_report()