From 935a141d9c94e71999df6bee38c52ae358c61905 Mon Sep 17 00:00:00 2001
From: woosukjeung <47073569+woosukjeung@users.noreply.github.com>
Date: Mon, 11 Feb 2019 00:01:18 -0800
Subject: [PATCH 001/367] Create Lesson4
---
students/WooseokJ/Lesson4 | 1 +
1 file changed, 1 insertion(+)
create mode 100644 students/WooseokJ/Lesson4
diff --git a/students/WooseokJ/Lesson4 b/students/WooseokJ/Lesson4
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/students/WooseokJ/Lesson4
@@ -0,0 +1 @@
+
From c08c36ccb32dd54f9fccadae00e3a21339d2b844 Mon Sep 17 00:00:00 2001
From: woosukjeung <47073569+woosukjeung@users.noreply.github.com>
Date: Mon, 11 Feb 2019 00:02:03 -0800
Subject: [PATCH 002/367] Lesson 4 submission
---
students/WooseokJ/MailP2fixedWJ.py | 111 +++++++++++++++++++++++++++++
students/WooseokJ/TrigramWJ.py | 50 +++++++++++++
2 files changed, 161 insertions(+)
create mode 100644 students/WooseokJ/MailP2fixedWJ.py
create mode 100644 students/WooseokJ/TrigramWJ.py
diff --git a/students/WooseokJ/MailP2fixedWJ.py b/students/WooseokJ/MailP2fixedWJ.py
new file mode 100644
index 00000000..ebd196af
--- /dev/null
+++ b/students/WooseokJ/MailP2fixedWJ.py
@@ -0,0 +1,111 @@
+
+# coding: utf-8
+
+# In[3]:
+
+
+# print of the main menu
+import sys
+import datetime
+import operator
+
+def menu():
+ print(''''Menu
+ Please choose from below options:
+ 1 - Send a Thank You
+ 2 - Create a Report
+ 3 - Exit the program
+ 4 - Print thank you letter to all current doners''')
+#first it will ask to choose a name whoom you would want to send the mail
+#along side that when typing list it will give you all the names on the current list
+#second if the name is not in the list then it will prompt to add the name into the data base
+#lastly it will print the message of the email
+# have a problem here where when asked for the amount of donation if the value type is not a number we get a error how to loop around this?
+def send_a_thankyou():
+ donor_list = []
+ for donor in donor_db:
+ donor_list.append(donor.lower())
+ while True:
+ fullname = input("Enter the full name of the donor typing list will give the names of current doners ")
+ if fullname.lower() == 'list':
+ for donor in donor_db:
+ print(donor)
+ elif fullname.lower() not in donor_list:
+ print(f'{fullname} does not exist in the donor data, '
+ f'we will add {fullname} to the donor data.')
+ amount = float(input("Please enter the donation amount: "))
+ donor_db.append((fullname, [amount, 1]))
+ print(f"{amount} has been added to {fullname}'s donation history.")
+ break
+ elif fullname.lower() in donor_list:
+ fullname = donor_list.index(fullname.lower())
+ amount = float(input("Please Enter the donation amount: "))
+ donor_db[fullname][1][0] = donor_db[fullname][1][0] + amount
+ donor_db[fullname][1][1] = donor_db[fullname][1][1] + 1
+ print(f"{amount} has been added to {fullname}'s donation history.")
+ break
+ print("Creating a Thank You email:")
+ print(f'Thank you {fullname} for your donation of {amount:^10.2f}!')
+ print()
+ menu()
+#this prints out the database of the donors with their total amaounts and average amount donated
+def create_a_report():
+ sorted_donor_db = sorted(donor_db.items(), key=operator.itemgetter(1), reverse=True)
+ print("Printing report:")
+ title = ('Donor Name', 'Total Given', "Num Gifts", 'Average Gift')
+ print("{:<19} | {:^13} | {:^13} | {:^11}".format(*title))
+ print("-"*70)
+ for i, row in enumerate(donor_db):
+ print("{:<21} ${:>13.2f} {:>13} ${:>12.2f}"
+ .format(donor_db[i][0], donor_db[i][1][0], donor_db[i][1][1],
+ donor_db[i][1][0]/donor_db[i][1][1]))
+ print()
+ menu()
+
+def sort_total_donation(number):
+ return number[1][0]
+#this makes a text that has the thankyou message to all the current doners on the list
+#the title of the file has the date and the name of the person on the list
+def send_letters_to_all_donors():
+ '''generate thankyou letter to all donors'''
+ for key in donor_db:
+ with open(key+"_"+str(datetime.date.today())+".txt", 'w') as f:
+ f.write("Dear {name},\n"
+ "\n"
+ " Thank you for your very kind donation of ${amount:10.2f}.\n"
+ "\n"
+ " It will be put to very good use.\n"
+ "\n"
+ " Sincerely\n"
+ " -The Team".format(name=key, amount=donor_db[key][0]))
+ print("Thank you letters to all donors have been generated in the local disk.\n")
+
+def exit_program():
+ print("Exiting the program")
+ sys.exit()
+
+def main():
+ choice = ''
+ while True:
+ choice = int(input(menu()))
+ if choice in main_menu:
+ main_menu[choice]()
+ else:
+ print("Not a valid option, try again.")
+#the main frame of the console
+main_menu = {1: send_a_thankyou,
+ 2: create_a_report,
+ 3: exit_program,
+ 4: send_letters_to_all_donors
+ }
+
+if __name__ == "__main__":
+
+ donor_db = {"William Gates, III": [ 653784.49, 2],
+ "Mark Zuckerberg": [16396.10, 3],
+ "Jeff Bezos": [877.33, 1],
+ "Paul Allen": [708.42, 3],
+ }
+
+ main()
+
diff --git a/students/WooseokJ/TrigramWJ.py b/students/WooseokJ/TrigramWJ.py
new file mode 100644
index 00000000..c6f762a7
--- /dev/null
+++ b/students/WooseokJ/TrigramWJ.py
@@ -0,0 +1,50 @@
+
+# coding: utf-8
+
+# In[3]:
+
+
+import sys
+import random
+
+#takes the words from the given file and returns it in a list
+def words_from_file(filename):
+ with open(filename, 'r') as textfile:
+ return [word.strip('\n') for l in textfile.readlines()
+ for word in l.split(' ')]
+#from the list makes a dictiondary to mix it in the next process
+def build_trigrams_dict(words):
+ trigrams = {}
+ for i, w in enumerate(words):
+ if i + 2 < len(words):
+ first = w.strip()
+ second = words[i + 1].strip()
+ third = words[i + 2].strip()
+ mix = '{} {}'.format(first, second)
+ if mix not in trigrams.keys():
+ trigrams[mix] = []
+ trigrams[mix].append(third)
+ return trigrams
+#this mixes the words to create the trigram
+def build_text(trigrams, num, new_words=[]):
+ if len(new_words) >= int(num) or int(num) < 3:
+ return ' '.join(new_words)
+ if not new_words:
+ second_start = random.choice(list(trigrams.keys()))
+ new_words.extend(second_start.split(' '))
+ if len(new_words) > 1:
+ mix = '{} {}'.format(new_words[-2], new_words[-1])
+ if mix not in trigrams.keys():
+ mix = random.choice(list(trigrams.keys()))
+ third = random.choice(trigrams[mix])
+ new_words.append(third)
+#this is a promot that asks for the file that we want to scramble make sure to add .txt at the end of the file
+ return build_text(trigrams, num, new_words)
+if __name__ == '__main__':
+ filename = input('Please enter a filename:\n--->')
+ length = 178
+ words = words_from_file(filename)
+ trigrams = build_trigrams_dict(words)
+ new_text = build_text(trigrams,length)
+ print (new_text)
+
From 548651e9a0779e3a9808c87fd0d6d813c60c1b8b Mon Sep 17 00:00:00 2001
From: woosukjeung <47073569+woosukjeung@users.noreply.github.com>
Date: Mon, 11 Feb 2019 19:19:52 -0800
Subject: [PATCH 003/367] Update TrigramWJ.py
i tried something else to make the code more compact and tried to stick more to the example given on the site but can't seem to fix the problem where the output is super short
---
students/WooseokJ/TrigramWJ.py | 55 +++++++++++++---------------------
1 file changed, 21 insertions(+), 34 deletions(-)
diff --git a/students/WooseokJ/TrigramWJ.py b/students/WooseokJ/TrigramWJ.py
index c6f762a7..17996cbe 100644
--- a/students/WooseokJ/TrigramWJ.py
+++ b/students/WooseokJ/TrigramWJ.py
@@ -1,9 +1,3 @@
-
-# coding: utf-8
-
-# In[3]:
-
-
import sys
import random
@@ -15,36 +9,29 @@ def words_from_file(filename):
#from the list makes a dictiondary to mix it in the next process
def build_trigrams_dict(words):
trigrams = {}
- for i, w in enumerate(words):
- if i + 2 < len(words):
- first = w.strip()
- second = words[i + 1].strip()
- third = words[i + 2].strip()
- mix = '{} {}'.format(first, second)
- if mix not in trigrams.keys():
- trigrams[mix] = []
- trigrams[mix].append(third)
- return trigrams
-#this mixes the words to create the trigram
-def build_text(trigrams, num, new_words=[]):
- if len(new_words) >= int(num) or int(num) < 3:
- return ' '.join(new_words)
- if not new_words:
- second_start = random.choice(list(trigrams.keys()))
- new_words.extend(second_start.split(' '))
- if len(new_words) > 1:
- mix = '{} {}'.format(new_words[-2], new_words[-1])
- if mix not in trigrams.keys():
- mix = random.choice(list(trigrams.keys()))
- third = random.choice(trigrams[mix])
- new_words.append(third)
+ for i in range(len(words)-2):
+ pair = tuple(words[i:i + 2])
+ follower = words[i + 2]
+ if pair not in trigrams:
+ trigrams[pair] = [follower]
+ else:
+ trigrams[pair] += [follower]
+ return trigrams
+#this mixes the words to create the new text
+def build_text(pairs):
+ random_text = []
+ while len(random_text) < len(pairs):
+ random_key = random.choice(list(pairs.keys()))
+ value = pairs.get(random_key)
+ random_text.append(list(random_key))
+ random_text.append(value)
+ new_list = [item for fixedlist in random_text for item in fixedlist]
+ clean_text = " ".join(new_list)
#this is a promot that asks for the file that we want to scramble make sure to add .txt at the end of the file
- return build_text(trigrams, num, new_words)
+ return clean_text
if __name__ == '__main__':
- filename = input('Please enter a filename:\n--->')
- length = 178
+ filename = input('Please enter a filename:')
words = words_from_file(filename)
trigrams = build_trigrams_dict(words)
- new_text = build_text(trigrams,length)
+ new_text = build_text(trigrams)
print (new_text)
-
From ca82472f08b43934691b2ceb269a841395f57a35 Mon Sep 17 00:00:00 2001
From: woosukjeung <47073569+woosukjeung@users.noreply.github.com>
Date: Sun, 17 Feb 2019 16:43:40 -0800
Subject: [PATCH 004/367] code review for fixed mail_p2 before adding in p3
every error should have been fixed before adding in codes for p3
---
students/WooseokJ/MailP2fixedWJFixed.py | 121 ++++++++++++++++++++++++
1 file changed, 121 insertions(+)
create mode 100644 students/WooseokJ/MailP2fixedWJFixed.py
diff --git a/students/WooseokJ/MailP2fixedWJFixed.py b/students/WooseokJ/MailP2fixedWJFixed.py
new file mode 100644
index 00000000..d23086f9
--- /dev/null
+++ b/students/WooseokJ/MailP2fixedWJFixed.py
@@ -0,0 +1,121 @@
+
+# coding: utf-8
+
+# In[ ]:
+
+
+import sys
+import datetime
+import operator
+
+
+def menu():
+ print(''''Menu
+ Please choose from below options:
+ 1 - Send a Thank You
+ 2 - Create a Report
+ 3 - Exit the program
+ 4 - Print thank you letter to all current donors''')
+
+
+# first it will ask to choose a name whoom you would want to send the mail
+# along side that when typing list it will give you all the names on the current list
+# second if the name is not in the list then it will prompt to add the name into the data base
+# lastly it will print the message of the email
+def send_a_thankyou():
+ donor_list = []
+ for donor in donor_db:
+ donor_list.append(donor.lower())
+ while True:
+ fullname = input("Enter the full name of the donor typing list will give the names of current doners ")
+ if fullname.lower() == 'list':
+ for donor in donor_db:
+ print(donor)
+ elif fullname.lower() not in donor_list:
+ print(f'{fullname} does not exist in the donor data, '
+ f'we will add {fullname} to the donor data.')
+ amount = float(input("Please enter the donation amount: "))
+ donor_db[fullname] = [amount, 1]
+ print(f"{amount} has been added to {fullname}'s donation history.")
+ break
+ elif fullname.lower() in donor_list:
+ amount = float(input("Please Enter the donation amount: "))
+ donor_db[fullname][0] = donor_db[fullname][0] + amount
+ donor_db[fullname][1] = donor_db[fullname][1] + 1
+ print(f"{amount} has been added to {fullname}'s donation history.")
+ break
+ print("Creating a Thank You email:")
+ print(f'Thank you {fullname} for your donation of {amount:^10.2f}!')
+ print()
+ menu()
+
+
+# this prints out the database of the donors with their total amaounts and average amount donated
+def create_a_report():
+ print("Printing report:")
+ title = ("Donor Name", "| Total Given", "| Num Gifts", "| Average Gift")
+ row = " ".join(["{:<19} | {:^13} | {:^13} | {:^11}"]).format(*title)
+ length = len(row)
+ print("\n" + row)
+ print("=" * length)
+ for key, value in sorted(donor_db.items()):
+ given = str(sum(value))
+ gift = str(len(value))
+ average = str(sum(value) / (len(value)))
+ row_format = (key, "$" + given, gift, "$" + average)
+ donor_row = " ".join(["{:<19} | {:^13} | {:^13} | {:^11}"]).format(*row_format)
+ print(donor_row)
+ print("\n")
+
+def sort_total_donation(number):
+ return number[1][0]
+
+
+# this makes a text that has the thankyou message to all the current doners on the list
+# the title of the file has the date and the name of the person on the list
+def send_letters_to_all_donors():
+ '''generate thank you letter to all donors'''
+ for key in donor_db:
+ with open(key + "_" + str(datetime.date.today()) + ".txt", 'w') as f:
+ f.write("Dear {name},\n"
+ "\n"
+ " Thank you for your very kind donation of ${amount:10.2f}.\n"
+ "\n"
+ " It will be put to very good use.\n"
+ "\n"
+ " Sincerely\n"
+ " -The Team".format(name=key, amount=donor_db[key][0]))
+ print("Thank you letters to all donors have been generated in the local disk.\n")
+
+
+def exit_program():
+ print("Exiting the program")
+ sys.exit()
+
+
+def main():
+ choice = ''
+ while True:
+ choice = int(input(menu()))
+ if choice in main_menu:
+ main_menu[choice]()
+ else:
+ print("Not a valid option, try again.")
+
+
+# the main frame of the console
+main_menu = {1: send_a_thankyou,
+ 2: create_a_report,
+ 3: exit_program,
+ 4: send_letters_to_all_donors
+ }
+
+if __name__ == "__main__":
+ donor_db = {"William Gates, III": [653784.49, 2],
+ "Mark Zuckerberg": [16396.10, 3],
+ "Jeff Bezos": [877.33, 1],
+ "Paul Allen": [708.42, 3],
+ }
+
+ main()
+
From 2614cac60f91757365f5a2c420af11e55b2aa48b Mon Sep 17 00:00:00 2001
From: woosukjeung <47073569+woosukjeung@users.noreply.github.com>
Date: Sun, 17 Feb 2019 21:35:00 -0800
Subject: [PATCH 005/367] Lesson 5 submission
---
students/WooseokJ/MailP3exceptWJ.py | 134 ++++++++++++++++++++++++++++
students/WooseokJ/exceptWJ.py | 59 ++++++++++++
students/WooseokJ/except_test.py | 41 +++++++++
3 files changed, 234 insertions(+)
create mode 100644 students/WooseokJ/MailP3exceptWJ.py
create mode 100644 students/WooseokJ/exceptWJ.py
create mode 100644 students/WooseokJ/except_test.py
diff --git a/students/WooseokJ/MailP3exceptWJ.py b/students/WooseokJ/MailP3exceptWJ.py
new file mode 100644
index 00000000..ca1b6bfe
--- /dev/null
+++ b/students/WooseokJ/MailP3exceptWJ.py
@@ -0,0 +1,134 @@
+
+# coding: utf-8
+
+# In[12]:
+
+
+import sys
+import datetime
+import operator
+
+
+def menu():
+ print(''''Menu
+ Please choose from below options:
+ 1 - Send a Thank You
+ 2 - Create a Report
+ 3 - Exit the program
+ 4 - Print thank you letter to all current donors''')
+
+
+# first it will ask to choose a name whoom you would want to send the mail
+# along side that when typing list it will give you all the names on the current list
+# second if the name is not in the list then it will prompt to add the name into the data base
+# lastly it will print the message of the email
+#added excepts to close off any errors that has to do with input errors
+def send_a_thankyou():
+ donor_list = []
+ for donor in donor_db:
+ donor_list.append(donor.lower())
+ while True:
+ fullname = input("Enter the full name of the donor typing list will give the names of current doners ")
+ if fullname.lower() == 'list':
+ for donor in donor_db:
+ print(donor)
+ elif fullname.lower() not in donor_list:
+ print(f'{fullname} does not exist in the donor data, '
+ f'we will add {fullname} to the donor data.')
+ while True:
+ try:
+ amount = float(input("Please enter the donation amount: "))
+ break
+ except ValueError:
+ print("Invalid input please try again")
+ donor_db[fullname] = [amount, 1]
+ print(f"{amount} has been added to {fullname}'s donation history.")
+ break
+ elif fullname.lower() in donor_list:
+ while True:
+ try:
+ amount = float(input("Please Enter the donation amount: "))
+ break
+ except ValueError:
+ print("Invalid input please try again")
+ donor_db[fullname][0] = donor_db[fullname][0] + amount
+ donor_db[fullname][1] = donor_db[fullname][1] + 1
+ print(f"{amount} has been added to {fullname}'s donation history.")
+ break
+ print("Creating a Thank You email:")
+ print(f'Thank you {fullname} for your donation of {amount:^10.2f}!')
+ print()
+ menu()
+
+
+# this prints out the database of the donors with their total amaounts and average amount donated
+def create_a_report():
+ print("Printing report:")
+ title = ("Donor Name", "| Total Given", "| Num Gifts", "| Average Gift")
+ row = " ".join(["{:<19} | {:^13} | {:^13} | {:^11}"]).format(*title)
+ length = len(row)
+ print("\n" + row)
+ print("=" * length)
+ for key, value in sorted(donor_db.items()):
+ given = str(sum(value))
+ gift = str(len(value))
+ average = str(sum(value) / (len(value)))
+ row_format = (key, "$" + given, gift, "$" + average)
+ donor_row = " ".join(["{:<19} | {:^13} | {:^13} | {:^11}"]).format(*row_format)
+ print(donor_row)
+ print("\n")
+
+def sort_total_donation(number):
+ return number[1][0]
+
+
+# this makes a text that has the thankyou message to all the current doners on the list
+# the title of the file has the date and the name of the person on the list
+def send_letters_to_all_donors():
+ '''generate thank you letter to all donors'''
+ for key in donor_db:
+ with open(key + "_" + str(datetime.date.today()) + ".txt", 'w') as f:
+ f.write("Dear {name},\n"
+ "\n"
+ " Thank you for your very kind donation of ${amount:10.2f}.\n"
+ "\n"
+ " It will be put to very good use.\n"
+ "\n"
+ " Sincerely\n"
+ " -The Team".format(name=key, amount=donor_db[key][0]))
+ print("Thank you letters to all donors have been generated in the local disk.\n")
+
+
+def exit_program():
+ print("Exiting the program")
+ sys.exit()
+
+
+def main():
+ while True:
+ try:
+ choice = ''
+ choice = int(input(menu()))
+ if choice in main_menu:
+ main_menu[choice]()
+ else:
+ print("Not a valid option, try again.")
+ except ValueError:
+ print("Selection has to be a number, try again.\n")
+
+# the main frame of the console
+main_menu = {1: send_a_thankyou,
+ 2: create_a_report,
+ 3: exit_program,
+ 4: send_letters_to_all_donors
+ }
+
+if __name__ == "__main__":
+ donor_db = {"William Gates, III": [653784.49, 2],
+ "Mark Zuckerberg": [16396.10, 3],
+ "Jeff Bezos": [877.33, 1],
+ "Paul Allen": [708.42, 3],
+ }
+
+ main()
+
diff --git a/students/WooseokJ/exceptWJ.py b/students/WooseokJ/exceptWJ.py
new file mode 100644
index 00000000..b23b6d28
--- /dev/null
+++ b/students/WooseokJ/exceptWJ.py
@@ -0,0 +1,59 @@
+
+# coding: utf-8
+
+# In[ ]:
+
+
+#!/usr/bin/python
+
+"""
+An exercise in playing with Exceptions.
+Make lots of try/except blocks for fun and profit.
+
+Make sure to catch specifically the error you find, rather than all errors.
+"""
+
+from except_test import fun, more_fun, last_fun
+
+
+# Figure out what the exception is, catch it and while still
+# in that catch block, try again with the second item in the list
+first_try = ['spam', 'cheese', 'mr death']
+try:
+ joke = fun(first_try[0])
+except NameError:
+ joke = fun(first_try[1])
+
+# Here is a try/except block. Add an else that prints not_joke
+try:
+ not_joke = fun(first_try[2])
+except SyntaxError:
+ print('Run Away!')
+else:
+ print(not_joke)
+# What did that do? You can think of else in this context, as well as in
+# loops as meaning: "else if nothing went wrong"
+# (no breaks in loops, no exceptions in try blocks)
+
+# Figure out what the exception is, catch it and in that same block
+#
+# try calling the more_fun function with the 2nd language in the list,
+# again assigning it to more_joke.
+#
+# If there are no exceptions, call the more_fun function with the last
+# language in the list
+
+# Finally, while still in the try/except block and regardless of whether
+# there were any exceptions, call the function last_fun with no
+# parameters. (pun intended)
+
+langs = ['java', 'c', 'python']
+try:
+ more_joke= more_fun(langs[0])
+except IndexError:
+ more_joke = more_fun(langs[1])
+else:
+ more_joke = more_fun(langs[2])
+finally:
+ last_fun()
+
diff --git a/students/WooseokJ/except_test.py b/students/WooseokJ/except_test.py
new file mode 100644
index 00000000..905dd675
--- /dev/null
+++ b/students/WooseokJ/except_test.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python3
+
+"""
+silly little test module that is designed to trigger Exceptions when
+run from the except_exercise.py file
+"""
+
+import time
+
+conclude = "And what leads you to that conclusion?"
+district = "Finest in the district, sir."
+cheese = "It's certainly uncontaminated by cheese."
+clean = "Well, it's so clean."
+shop = "Not much of a cheese shop really, is it?"
+cust = "Customer: "
+clerk = "Shopkeeper: "
+
+
+def fun(reaper):
+ if reaper == 'spam':
+ print(s)
+ elif reaper == 'cheese':
+ print()
+ print('Spam, Spam, Spam, Spam, Beautiful Spam')
+ elif reaper == 'mr death':
+ print()
+ return('{}{}\n{}{}'.format(cust, shop, clerk, district))
+
+
+def more_fun(language):
+ if language == 'java':
+ test = [1, 2, 3]
+ test[5] = language
+ elif language == 'c':
+ print('{}{}\n{}{}'.format(cust, conclude, clerk, clean))
+
+
+def last_fun():
+ print(cust, cheese)
+ time.sleep(1)
+ import antigravity
From 34a4ee6ed68b763126f46b64838ed301f9c3ae12 Mon Sep 17 00:00:00 2001
From: mjchang14
Date: Sat, 23 Feb 2019 19:29:57 -0800
Subject: [PATCH 006/367] adding mailroom4 and test_mailroom4
---
students/mjchang/session06/mailroom4.py | 122 +++++++++++++++++++
students/mjchang/session06/test_mailroom4.py | 65 ++++++++++
2 files changed, 187 insertions(+)
create mode 100644 students/mjchang/session06/mailroom4.py
create mode 100644 students/mjchang/session06/test_mailroom4.py
diff --git a/students/mjchang/session06/mailroom4.py b/students/mjchang/session06/mailroom4.py
new file mode 100644
index 00000000..23feff98
--- /dev/null
+++ b/students/mjchang/session06/mailroom4.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env python3
+
+import os
+import datetime
+import sys
+import unittest
+
+donor_db = {"Eliza Sommers": [4000, 250, 70],
+ "Tao Chien": [350, 1000, 225],
+ "Joaquin Andieta": [100, 25],
+ "Paulina Rodriguez": [50000],
+ "Jacob Todd": [75, 80]}
+
+def thank_you_one(): # adding a new vendor
+ while True:
+ name = input("Please enter a full name (or 'list' for a list of current donors): ")
+ name = name.title() #keeps capitalization format the same
+ if name.lower() == "list":
+ print('\n'.join(donor_db.keys())) #displays list of donors
+
+ elif name not in donor_db.keys(): #adding new donor
+ print("Adding {} to the donor list".format(name))
+ #adding exception for donation input that isn't a number
+ try:
+ donation = input("Enter the donation amount from {}: ".format(name)) #adding donation from new donor
+ donation = float(donation) #converting to a float
+ except (ValueError, EOFError):
+ print("Donation amount must be a number")
+ continue
+ donor_db.setdefault(name, []).append(donation)
+ break
+
+ elif name in donor_db.keys(): #adding donation for existing donor
+ name = name.title() #keep capitalization same as keys
+ #adding exception for scenario where input isn't a number
+ try:
+ donation = input("Enter the new donation amount: ")
+ donation = float(donation)
+ except (ValueError, EOFError):
+ print("Donation amount must be a number")
+ continue
+ donor_db[name].append(donation)
+ print("\n \n The ${:.2f} donation from {} was added".format(donation, name))
+ break
+
+
+# send the thank you letter to one donor
+ print("\n \n Generating the letter for {}\n \n".format(name))
+ print("Dear {}, \n\n On behalf of all of us, we thank your for your generous donation of ${:10.2f}. \n You have helped make a big impact on the community!".format(name, donation))
+
+
+# send the thank you letter to all donors
+def thank_you_all():
+ path = os.getcwd()
+ folder = path + '/donor_letters/'
+ os.mkdir(folder)
+ os.chdir(folder)
+ for key in donor_db:
+ timestamp = str(datetime.date.today())
+ with open(key + '_' + timestamp + ".txt", "w+") as f:
+ f.write("Dear {}, \n\n On behalf of all of us, we thank your for your generous donation. \n You have helped make a big impact on the community!".format(key))
+ f.close()
+
+ print("Letters to all donors were generated.")
+
+
+# set up for donor report
+def sort_key(data):
+ return data[1]
+
+# create a report of donors and amounts
+def donor_report():
+ #using a list comprehension to simplify building the donor report
+ spreadsheet = [(name, sum(gifts), len(gifts), sum(gifts)/len(gifts))
+ for name, gifts in donor_db.items()]
+
+ #sort the report by total donation
+ spreadsheet.sort(key = sort_key)
+
+ print("{:<30} | {:<12} | {:>15} | {:12}".format("Donor Name", "Total Given", "Number of Gifts", "Average Gift")) #print the header
+ print("-"*79) #print the dashed line
+ for data in spreadsheet:
+ print("{:<30} ${:12.2f} {:>15} ${:12.2f}".format(data[0], data[1], data[2], data[3]))
+
+
+
+def quit_program():
+ sys.exit()
+
+
+
+def main():
+ while True:
+ response = ''
+ response = int(input("""
+ Please enter a number from the following options:
+ 1 - Send a Thank You to One Donor
+ 2 - Send a Thank You to All Donors
+ 3 - Create a Report
+ 4 - Quit
+ """))
+ selection = {1: thank_you_one,
+ 2: thank_you_all,
+ 3: donor_report,
+ 4: quit_program
+ }
+ #adding exception to handle responses other than 1-4
+ try:
+ if response in selection.keys():
+ selection.get(response)()
+ else:
+ print("Please make a valid selection")
+ except (ValueError, EOFError):
+ print("Please select from the available options")
+ continue
+
+
+if __name__ == "__main__":
+
+ donor_db = donor_db()
+
+ main()
\ No newline at end of file
diff --git a/students/mjchang/session06/test_mailroom4.py b/students/mjchang/session06/test_mailroom4.py
new file mode 100644
index 00000000..b70ed622
--- /dev/null
+++ b/students/mjchang/session06/test_mailroom4.py
@@ -0,0 +1,65 @@
+#!/usr/bon/env python3
+
+
+import os
+import sys
+import unittest
+
+import mailroom4
+
+mr4.donor_db = mailroom4.donor_db()
+
+def test_donor_list():
+ """ test to see if donors are showing up in list"""
+ donors = mr4.donor_db.keys()
+ assert len(donors.split('\n')) == 5
+ assert "Tao Chien" in donors
+ assert "Eliza Sommers" in donors
+
+
+def test_no_donor_search():
+ """ test that a new donor doesn't show up"""
+ donor = mr4.donor_db.keys()
+ assert donor is None
+
+
+
+def test_donor_search():
+ """ test that an existing donor is there
+also test if existing donor can be found using different capitalization inputs"""
+ donor = mr4.donor_db.keys()
+ assert donor[2] == "Joaquin Andieta"
+ assert donor[4] == "Jacob Todd"
+
+
+
+def test_gen_single_letter():
+ """test that the donor letter/message is generated"""
+ pass
+
+
+def test_donor_addition():
+ """ test that new donor is added"""
+ pass
+
+
+def test_create_report():
+ """ test that the donor report is created and displayed correctly"""
+ pass
+
+
+def test_gen_letters():
+ """ test that letters were generated and saved to the specified folder"""
+ pass
+
+
+if __name__ == "__main__":
+ test_donor_list()
+ test_no_donor_search()
+ test_donor_search()
+ test_gen_single_letter()
+ test_donor_addition()
+ test_create_report()
+ test_gen_letters()
+ print("All the tests passed!")
+
From 0b56d035aa03b04daaa5b400de9a5a75d3ecfdc3 Mon Sep 17 00:00:00 2001
From: mjchang14
Date: Sun, 24 Feb 2019 17:50:05 -0800
Subject: [PATCH 007/367] split thank_you_one function into 4 parts
---
students/mjchang/session06/mailroom4.py | 103 +++++++++++++++++-------
1 file changed, 72 insertions(+), 31 deletions(-)
diff --git a/students/mjchang/session06/mailroom4.py b/students/mjchang/session06/mailroom4.py
index 23feff98..7f10c8f8 100644
--- a/students/mjchang/session06/mailroom4.py
+++ b/students/mjchang/session06/mailroom4.py
@@ -5,48 +5,89 @@
import sys
import unittest
-donor_db = {"Eliza Sommers": [4000, 250, 70],
+
+def donor_db(): #defining donor database to make it easier to test
+ return {"Eliza Sommers": [4000, 250, 70],
"Tao Chien": [350, 1000, 225],
"Joaquin Andieta": [100, 25],
"Paulina Rodriguez": [50000],
"Jacob Todd": [75, 80]}
+def donor_list():
+ print('\n'.join(donor_db.keys())) #displays list of donors
+
+
+def add_new_donor(name):
+ print("Adding {} to the donor list".format(name))
+ #adding exception for donation input that isn't a number
+ try:
+ donation = input("Enter the donation amount from {}: ".format(name)) #adding donation from new donor
+ donation = float(donation) #converting to a float
+ except (ValueError, EOFError):
+ print("Donation amount must be a number")
+ continue
+ donor_db.setdefault(name, []).append(donation)
+ break
+
+
+def add_new_donation():
+ try:
+ donation = input("Enter the new donation amount: ")
+ donation = float(donation)
+ except (ValueError, EOFError):
+ print("Donation amount must be a number")
+ continue
+ donor_db[name].append(donation)
+ print("\n \n The ${:.2f} donation from {} was added".format(donation, name))
+ break
+
+
+def ty_message_one(name, donation):
+
+ print("\n \n Generating the letter for {}\n \n".format(name))
+ print("Dear {}, \n\n On behalf of all of us, we thank your for your generous donation of ${:10.2f}. \n You have helped make a big impact on the community!".format(name, donation))
+
+
+
def thank_you_one(): # adding a new vendor
while True:
name = input("Please enter a full name (or 'list' for a list of current donors): ")
name = name.title() #keeps capitalization format the same
if name.lower() == "list":
- print('\n'.join(donor_db.keys())) #displays list of donors
+ donor_list()
- elif name not in donor_db.keys(): #adding new donor
- print("Adding {} to the donor list".format(name))
- #adding exception for donation input that isn't a number
- try:
- donation = input("Enter the donation amount from {}: ".format(name)) #adding donation from new donor
- donation = float(donation) #converting to a float
- except (ValueError, EOFError):
- print("Donation amount must be a number")
- continue
- donor_db.setdefault(name, []).append(donation)
- break
+ elif name not in donor_db.keys():
+ add_new_donor(name)
+ #adding new donor
+ # print("Adding {} to the donor list".format(name))
+ # #adding exception for donation input that isn't a number
+ # try:
+ # donation = input("Enter the donation amount from {}: ".format(name)) #adding donation from new donor
+ # donation = float(donation) #converting to a float
+ # except (ValueError, EOFError):
+ # print("Donation amount must be a number")
+ # continue
+ # donor_db.setdefault(name, []).append(donation)
+ # break
elif name in donor_db.keys(): #adding donation for existing donor
- name = name.title() #keep capitalization same as keys
+ # name = name.title() #keep capitalization same as keys
#adding exception for scenario where input isn't a number
- try:
- donation = input("Enter the new donation amount: ")
- donation = float(donation)
- except (ValueError, EOFError):
- print("Donation amount must be a number")
- continue
- donor_db[name].append(donation)
- print("\n \n The ${:.2f} donation from {} was added".format(donation, name))
- break
-
-
-# send the thank you letter to one donor
- print("\n \n Generating the letter for {}\n \n".format(name))
- print("Dear {}, \n\n On behalf of all of us, we thank your for your generous donation of ${:10.2f}. \n You have helped make a big impact on the community!".format(name, donation))
+ add_new_donation()
+ # try:
+ # donation = input("Enter the new donation amount: ")
+ # donation = float(donation)
+ # except (ValueError, EOFError):
+ # print("Donation amount must be a number")
+ # continue
+ # donor_db[name].append(donation)
+ # print("\n \n The ${:.2f} donation from {} was added".format(donation, name))
+ # break
+ # send the thank you letter to one donor
+ ty_message_one()
+ # print("\n \n Generating the letter for {}\n \n".format(name))
+ # print("Dear {}, \n\n On behalf of all of us, we thank your for your generous donation of ${:10.2f}. \n You have helped make a big impact on the community!".format(name, donation))
+
# send the thank you letter to all donors
@@ -83,12 +124,11 @@ def donor_report():
print("{:<30} ${:12.2f} {:>15} ${:12.2f}".format(data[0], data[1], data[2], data[3]))
-
def quit_program():
+ print("Goodbye!\n")
sys.exit()
-
def main():
while True:
response = ''
@@ -117,6 +157,7 @@ def main():
if __name__ == "__main__":
- donor_db = donor_db()
+
+ donor_db = donor_db()
main()
\ No newline at end of file
From d126293d9bc2af18ca565fb6832ca30b845af08a Mon Sep 17 00:00:00 2001
From: mjchang14
Date: Sun, 24 Feb 2019 20:53:00 -0800
Subject: [PATCH 008/367] adding mailroom4.1 - cleaned up thank_you_one
function
---
students/mjchang/session06/mailroom4.1.py | 124 ++++++++++++++++++++++
1 file changed, 124 insertions(+)
create mode 100644 students/mjchang/session06/mailroom4.1.py
diff --git a/students/mjchang/session06/mailroom4.1.py b/students/mjchang/session06/mailroom4.1.py
new file mode 100644
index 00000000..45eaf7d3
--- /dev/null
+++ b/students/mjchang/session06/mailroom4.1.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python3
+
+import os
+import datetime
+import sys
+import unittest
+
+
+def donor_db(): #defining donor database to make it easier to test
+ return {"Eliza Sommers": [4000, 250, 70],
+ "Tao Chien": [350, 1000, 225],
+ "Joaquin Andieta": [100, 25],
+ "Paulina Rodriguez": [50000],
+ "Jacob Todd": [75, 80]}
+
+def donor_list(): #splitting thank_you_one function into multiple parts in mailroom4
+ print('\n'.join(donor_db.keys())) #displays list of donors
+
+
+
+def thank_you_one(): # adding a new vendor
+ while True:
+ name = input("Please enter a full name (or 'list' for a list of current donors): ")
+ name = name.title() #keeps capitalization format the same
+ if name.lower() == "list":
+ donor_list()
+ else:
+ break
+
+ if name not in donor_db.keys(): #adding new donor
+ print("Adding {} to the donor list".format(name))
+ donor_db.setdefault(name, [])
+ break
+
+
+ while True:
+ name = name.title() #keep capitalization same as keys
+ #adding exception for scenario where input isn't a number
+ try:
+ donation = input("Enter the new donation amount: ")
+ donation = float(donation)
+ except (ValueError, EOFError):
+ print("Donation amount must be a number")
+ continue
+ donor_db[name].append(donation)
+ break
+ print("\n \n The ${:.2f} donation from {} was added".format(donation, name))
+
+# send the thank you letter to one donor
+ print("\n \n Generating the letter for {}\n \n".format(name))
+ print("Dear {}, \n\n On behalf of all of us, we thank your for your generous donation of ${:10.2f}. \n You have helped make a big impact on the community!".format(name, donation))
+
+
+# send the thank you letter to all donors
+def thank_you_all():
+ path = os.getcwd()
+ folder = path + '/donor_letters/'
+ os.mkdir(folder)
+ os.chdir(folder)
+ for key in donor_db:
+ timestamp = str(datetime.date.today())
+ with open(key + '_' + timestamp + ".txt", "w+") as f:
+ f.write("Dear {}, \n\n On behalf of all of us, we thank your for your generous donation. \n You have helped make a big impact on the community!".format(key))
+ f.close()
+
+ print("Letters to all donors were generated.")
+
+
+# set up for donor report
+def sort_key(data):
+ return data[1]
+
+# create a report of donors and amounts
+def donor_report():
+ #using a list comprehension to simplify building the donor report
+ spreadsheet = [(name, sum(gifts), len(gifts), sum(gifts)/len(gifts))
+ for name, gifts in donor_db.items()]
+
+ #sort the report by total donation
+ spreadsheet.sort(key = sort_key)
+
+ print("{:<30} | {:<12} | {:>15} | {:12}".format("Donor Name", "Total Given", "Number of Gifts", "Average Gift")) #print the header
+ print("-"*79) #print the dashed line
+ for data in spreadsheet:
+ print("{:<30} ${:12.2f} {:>15} ${:12.2f}".format(data[0], data[1], data[2], data[3]))
+
+
+def quit_program():
+ print("Goodbye!\n")
+ sys.exit()
+
+
+def main():
+ while True:
+ response = ''
+ response = int(input("""
+ Please enter a number from the following options:
+ 1 - Send a Thank You to One Donor
+ 2 - Send a Thank You to All Donors
+ 3 - Create a Report
+ 4 - Quit
+ """))
+ selection = {1: thank_you_one,
+ 2: thank_you_all,
+ 3: donor_report,
+ 4: quit_program
+ }
+ #adding exception to handle responses other than 1-4
+ try:
+ if response in selection.keys():
+ selection.get(response)()
+ else:
+ print("Please make a valid selection")
+ except (ValueError, EOFError):
+ print("Please select from the available options")
+ continue
+
+
+if __name__ == "__main__":
+
+
+ donor_db = donor_db()
+
+ main()
\ No newline at end of file
From 45ddd7b9910d3245d684a56e4fadb4906f1b0d00 Mon Sep 17 00:00:00 2001
From: woosukjeung <47073569+woosukjeung@users.noreply.github.com>
Date: Sun, 24 Feb 2019 22:24:10 -0800
Subject: [PATCH 009/367] lessons 6 submission
added fixes commented on lessons 5 as well
---
students/WooseokJ/MailP4WJ.py | 149 ++++++++++++++++++++++++++++++
students/WooseokJ/MailP4testWJ.py | 29 ++++++
2 files changed, 178 insertions(+)
create mode 100644 students/WooseokJ/MailP4WJ.py
create mode 100644 students/WooseokJ/MailP4testWJ.py
diff --git a/students/WooseokJ/MailP4WJ.py b/students/WooseokJ/MailP4WJ.py
new file mode 100644
index 00000000..ccbc7652
--- /dev/null
+++ b/students/WooseokJ/MailP4WJ.py
@@ -0,0 +1,149 @@
+
+# coding: utf-8
+
+# In[12]:
+
+
+import sys
+import datetime
+import operator
+
+
+def menu():
+ return(''''Menu
+ Please choose from below options:
+ 1 - Send a Thank You
+ 2 - Create a Report
+ 3 - Exit the program
+ 4 - Print thank you letter to all current donors''')
+
+
+# first it will ask to choose a name whoom you would want to send the mail
+# along side that when typing list it will give you all the names on the current list
+# second if the name is not in the list then it will prompt to add the name into the data base
+# lastly it will print the message of the email
+#added excepts to close off any errors that has to do with input errors
+def send_a_thankyou():
+ while True:
+ fullname = input("Enter the full name of the donor typing list will give the names of current doners ")
+ if fullname.lower() == 'list':
+ for donor in donor_db:
+ print(donor)
+ else:
+ while True:
+ try:
+ amount = float(input("Please enter the donation amount: "))
+ break
+ except ValueError:
+ print("Invalid input please try again")
+ send_a_thankyou(fullname, amount, donor_db)
+ print(f"${amount} has been updated to {fullname}'s donation history.")
+ break
+ print(f'Thank you {fullname} for your donation of ${amount:^10.2f}!')
+ print()
+ menu()
+
+
+def send_thankyou_test(fullname, amount, donor_list):
+ donor_list = [donor.lower() for donor in donor_list]
+ if fullname.lower() not in donor_list:
+ print(f'{fullname} does not exist in the donor data, '
+ f'we will add {fullname} to the donor data.')
+ donor_list[fullname] = [amount,1]
+ elif fullname.lower() in donor_list:
+ donor_list[fullname][0] = donor_list[fullname][0] + amount
+ donor_list[fullname][1] = donor_list[fullname][1] + 1
+ return fullname, donor_list[fullname]
+
+
+# this prints out the database of the donors with their total amaounts and average amount donated
+def create_a_report():
+ print("Printing report:")
+ title = ("Donor Name", "| Total Given", "| Num Gifts", "| Average Gift")
+ row = " ".join(["{:<19} | {:^13} | {:^13} | {:^11}"]).format(*title)
+ length = len(row)
+ print("\n" + row)
+ print("=" * length)
+ for key, value in sorted(donor_db.items()):
+ given = str(sum(value))
+ gift = str(len(value))
+ average = str(sum(value) / (len(value)))
+ row_format = (key, "$" + given, gift, "$" + average)
+ donor_row = " ".join(["{:<19} | {:^13} | {:^13} | {:^11}"]).format(*row_format)
+ print(donor_row)
+ print("\n")
+
+
+def create_a_report_test():
+ print("Printing report:")
+ title = ("Donor Name", "| Total Given", "| Num Gifts", "| Average Gift")
+ row = " ".join(["{:<19} | {:^13} | {:^13} | {:^11}"]).format(*title)
+ length = len(row)
+ print("\n" + row)
+ print("=" * length)
+ for key, value in sorted(donor_db.items()):
+ given = sum(value[1])
+ gift = len(value[1])
+ average = sum(value[1]) / (len(value[1]))
+ row_format = (key, "$" + given, gift, "$" + average)
+ donor_row = " ".join(["{:<19} | {:^13} | {:^13} | {:^11}"]).format(*row_format)
+ print(donor_row)
+ print("\n")
+
+
+def sort_total_donation(number):
+ return number[1][0]
+
+
+# this makes a text that has the thankyou message to all the current doners on the list
+# the title of the file has the date and the name of the person on the list
+def send_letters_to_all_donors():
+ '''generate thank you letter to all donors'''
+ for key in donor_db:
+ with open(key + "_" + str(datetime.date.today()) + ".txt", 'w') as f:
+ f.write(send_letter_to_all_donors_test(key,donor_db))
+ print("Thank you letters to all donors have been generated in the local disk.\n")
+
+
+def send_letter_to_all_donors_test(key, donor_list):
+ return ("Dear {name},\n"
+ "\n"
+ " Thank you for your very kind donation of ${amount:10.2f}.\n"
+ "\n"
+ " It will be put to very good use.\n"
+ "\n"
+ " Sincerely\n"
+ " -The Team".format(name=key, amount=donor_list[key][0]))
+
+def exit_program():
+ print("Exiting the program")
+ sys.exit()
+
+
+def main():
+ while True:
+ try:
+ choice = ''
+ choice = int(input(menu()))
+ if choice in main_menu:
+ main_menu[choice]()
+ else:
+ print("Not a valid option, try again.")
+ except ValueError:
+ print("Selection has to be a number, try again.\n")
+
+# the main frame of the console
+main_menu = {1: send_a_thankyou,
+ 2: create_a_report,
+ 3: exit_program,
+ 4: send_letters_to_all_donors
+ }
+
+if __name__ == "__main__":
+ donor_db = {"William Gates, III": [653784.49, 2],
+ "Mark Zuckerberg": [16396.10, 3],
+ "Jeff Bezos": [877.33, 1],
+ "Paul Allen": [708.42, 3],
+ }
+
+ main()
\ No newline at end of file
diff --git a/students/WooseokJ/MailP4testWJ.py b/students/WooseokJ/MailP4testWJ.py
new file mode 100644
index 00000000..c643184e
--- /dev/null
+++ b/students/WooseokJ/MailP4testWJ.py
@@ -0,0 +1,29 @@
+# import from the MailP4WJ file to test
+from MailP4WJ import send_thankyou_test
+from MailP4WJ import create_a_report_test
+from MailP4WJ import send_letter_to_all_donors_test
+
+donor_db = {"William Gates, III": [653784.49, 2],
+ "Mark Zuckerberg": [16396.10, 3],
+ "Jeff Bezos": [877.33, 1],
+ "Paul Allen": [708.42, 3],
+ }
+
+# tests the sending the thank you test
+def test_thankyou():
+ expected = ('Paul Allen', [708.42, 3])
+ assert send_thankyou_test('Paul Allen' , 100, donor_db) == expected
+
+# tests the making the report function
+def test_report():
+ expected = "Paul Allen | $711.42 | 2 | $355.71 "
+ assert create_a_report_test('Paul Allen', [711.42, 2]) == expected
+
+# tests the contents of the letter created
+def test_letter():
+ expected = "Dear Paul Allen ,\n\n" \
+ " Thank you for your very kind donation of $ 711.42.\n" \
+ "\n" \
+ " Sincerely\n" \
+ " -The Team"
+ assert send_letter_to_all_donors_test() == expected
From bdd42d0f69b2fe69813bfa820946a06cc0e386a4 Mon Sep 17 00:00:00 2001
From: mjchang14
Date: Sun, 24 Feb 2019 22:41:05 -0800
Subject: [PATCH 010/367] updated mailroom4 to match naming used in
test_mailroom4
---
students/mjchang/session06/mailroom4.1.py | 3 +-
students/mjchang/session06/mailroom4.py | 63 ++++++-----------------
2 files changed, 18 insertions(+), 48 deletions(-)
diff --git a/students/mjchang/session06/mailroom4.1.py b/students/mjchang/session06/mailroom4.1.py
index 45eaf7d3..2c683c20 100644
--- a/students/mjchang/session06/mailroom4.1.py
+++ b/students/mjchang/session06/mailroom4.1.py
@@ -30,7 +30,8 @@ def thank_you_one(): # adding a new vendor
if name not in donor_db.keys(): #adding new donor
print("Adding {} to the donor list".format(name))
donor_db.setdefault(name, [])
- break
+ else:
+ pass
while True:
diff --git a/students/mjchang/session06/mailroom4.py b/students/mjchang/session06/mailroom4.py
index 7f10c8f8..fc932d45 100644
--- a/students/mjchang/session06/mailroom4.py
+++ b/students/mjchang/session06/mailroom4.py
@@ -13,40 +13,35 @@ def donor_db(): #defining donor database to make it easier to test
"Paulina Rodriguez": [50000],
"Jacob Todd": [75, 80]}
-def donor_list():
+def donor_list(): #splitting thank_you_one function into multiple parts in mailroom4
print('\n'.join(donor_db.keys())) #displays list of donors
+def gen_letter(name, donation):
+ print("\n \n The ${:.2f} donation from {} was added".format(donation, name))
+ print("\n \n Generating the letter for {}\n \n".format(name))
+ print("Dear {}, \n\n On behalf of all of us, we thank you for your generous donation of ${:10.2f}. \n You have helped make a big impact on the community!".format(name, donation))
+
+
def add_new_donor(name):
print("Adding {} to the donor list".format(name))
- #adding exception for donation input that isn't a number
+ #adding exception for donation input that isn't a number
try:
donation = input("Enter the donation amount from {}: ".format(name)) #adding donation from new donor
donation = float(donation) #converting to a float
except (ValueError, EOFError):
- print("Donation amount must be a number")
- continue
+ print("Donation amount must be a number")
donor_db.setdefault(name, []).append(donation)
- break
-
+ gen_letter(name, donation)
-def add_new_donation():
+def add_new_donation(name):
try:
donation = input("Enter the new donation amount: ")
donation = float(donation)
except (ValueError, EOFError):
print("Donation amount must be a number")
- continue
donor_db[name].append(donation)
- print("\n \n The ${:.2f} donation from {} was added".format(donation, name))
- break
-
-
-def ty_message_one(name, donation):
-
- print("\n \n Generating the letter for {}\n \n".format(name))
- print("Dear {}, \n\n On behalf of all of us, we thank your for your generous donation of ${:10.2f}. \n You have helped make a big impact on the community!".format(name, donation))
-
+ gen_letter(name, donation)
def thank_you_one(): # adding a new vendor
@@ -56,39 +51,13 @@ def thank_you_one(): # adding a new vendor
if name.lower() == "list":
donor_list()
- elif name not in donor_db.keys():
+ elif name not in donor_db.keys(): #adding new donor
add_new_donor(name)
- #adding new donor
- # print("Adding {} to the donor list".format(name))
- # #adding exception for donation input that isn't a number
- # try:
- # donation = input("Enter the donation amount from {}: ".format(name)) #adding donation from new donor
- # donation = float(donation) #converting to a float
- # except (ValueError, EOFError):
- # print("Donation amount must be a number")
- # continue
- # donor_db.setdefault(name, []).append(donation)
- # break
+ break
elif name in donor_db.keys(): #adding donation for existing donor
- # name = name.title() #keep capitalization same as keys
- #adding exception for scenario where input isn't a number
- add_new_donation()
- # try:
- # donation = input("Enter the new donation amount: ")
- # donation = float(donation)
- # except (ValueError, EOFError):
- # print("Donation amount must be a number")
- # continue
- # donor_db[name].append(donation)
- # print("\n \n The ${:.2f} donation from {} was added".format(donation, name))
- # break
- # send the thank you letter to one donor
- ty_message_one()
- # print("\n \n Generating the letter for {}\n \n".format(name))
- # print("Dear {}, \n\n On behalf of all of us, we thank your for your generous donation of ${:10.2f}. \n You have helped make a big impact on the community!".format(name, donation))
-
-
+ add_new_donation(name)
+ break
# send the thank you letter to all donors
def thank_you_all():
From b7cf1c8abbdadc103159b34281a72d8242f6ceb3 Mon Sep 17 00:00:00 2001
From: mjchang14
Date: Mon, 25 Feb 2019 22:02:05 -0800
Subject: [PATCH 011/367] got test_create_report to work
---
students/mjchang/session06/test_mailroom4.py | 53 ++++++++++++--------
1 file changed, 33 insertions(+), 20 deletions(-)
diff --git a/students/mjchang/session06/test_mailroom4.py b/students/mjchang/session06/test_mailroom4.py
index b70ed622..9f401d39 100644
--- a/students/mjchang/session06/test_mailroom4.py
+++ b/students/mjchang/session06/test_mailroom4.py
@@ -1,56 +1,69 @@
#!/usr/bon/env python3
-
import os
import sys
+import datetime
import unittest
-import mailroom4
+import mailroom4 as mr4
-mr4.donor_db = mailroom4.donor_db()
+mr4.donor_db = mr4.donor_db()
def test_donor_list():
""" test to see if donors are showing up in list"""
donors = mr4.donor_db.keys()
- assert len(donors.split('\n')) == 5
+ assert len(donors) == 5
assert "Tao Chien" in donors
assert "Eliza Sommers" in donors
def test_no_donor_search():
""" test that a new donor doesn't show up"""
- donor = mr4.donor_db.keys()
+ donor = mr4.donor_db.get("Mama Fresia")
assert donor is None
-
def test_donor_search():
- """ test that an existing donor is there
-also test if existing donor can be found using different capitalization inputs"""
- donor = mr4.donor_db.keys()
- assert donor[2] == "Joaquin Andieta"
- assert donor[4] == "Jacob Todd"
-
+ """ test that an existing donor is there"""
+ donors = mr4.donor_db.keys()
+ assert "Joaquin Andieta" in donors
def test_gen_single_letter():
- """test that the donor letter/message is generated"""
- pass
+ """test that the donor letter/message is generated
+ bring in a test donor, then check the letter"""
+ expected = "Dear Jacob Todd, \n\n Thank you for your generous donation of $ 100.00. \n You have helped make a big impact on the community!"
+ assert mr4.generate_letter("Jacob Todd", 100.00) == expected
+
def test_donor_addition():
- """ test that new donor is added"""
- pass
+ """ test that new donor is added
+ created a test new donor and donation, then check that new donor is in the donor_db"""
+ name = "Isabel Allende"
+ donation = 2500
+ mr4.donor_db.setdefault(name, []).append(donation)
+ donors = mr4.donor_db.keys()
+ don_amt = mr4.donor_db.values()
+ assert "Isabel Allende" in donors
+ assert mr4.donor_db.get("Isabel Allende") == [2500]
def test_create_report():
- """ test that the donor report is created and displayed correctly"""
- pass
+ """ test that the donor report is created
+ using a random line from the report to test that it displays correctly"""
+ expected = "Paulina Rodriguez $ 50000.00 1 $ 50000.00"
+ assert mr4.report_line(["Paulina Rodriguez", 50000, 1, 50000]) == expected
def test_gen_letters():
- """ test that letters were generated and saved to the specified folder"""
- pass
+ """ test that letters were generated to separate files"""
+ timestamp = str(datetime.date.today())
+ assert os.path.isfile('Tao Chien_'+timestamp+'.txt')
+ assert os.path.isfile('Joaquin Andieta_'+timestamp+'.txt')
+
+def test_get_letter_text():
+ expected = ""
if __name__ == "__main__":
From f00c90ecbdab10ee21a909be76dd30539d16852c Mon Sep 17 00:00:00 2001
From: mjchang14
Date: Mon, 25 Feb 2019 22:33:05 -0800
Subject: [PATCH 012/367] adding mailroom4 and test_mailroom4 for submission
---
students/mjchang/session06/mailroom4.py | 22 ++++++++++++--------
students/mjchang/session06/test_mailroom4.py | 10 ++++++---
2 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/students/mjchang/session06/mailroom4.py b/students/mjchang/session06/mailroom4.py
index fc932d45..fc2c73bb 100644
--- a/students/mjchang/session06/mailroom4.py
+++ b/students/mjchang/session06/mailroom4.py
@@ -17,11 +17,9 @@ def donor_list(): #splitting thank_you_one function into multiple parts in mailr
print('\n'.join(donor_db.keys())) #displays list of donors
-def gen_letter(name, donation):
- print("\n \n The ${:.2f} donation from {} was added".format(donation, name))
- print("\n \n Generating the letter for {}\n \n".format(name))
- print("Dear {}, \n\n On behalf of all of us, we thank you for your generous donation of ${:10.2f}. \n You have helped make a big impact on the community!".format(name, donation))
-
+def generate_letter(name, donation):
+ message = "Dear {}, \n\n Thank you for your generous donation of ${:10.2f}. \n You have helped make a big impact on the community!".format(name, donation)
+ return message
def add_new_donor(name):
print("Adding {} to the donor list".format(name))
@@ -32,7 +30,7 @@ def add_new_donor(name):
except (ValueError, EOFError):
print("Donation amount must be a number")
donor_db.setdefault(name, []).append(donation)
- gen_letter(name, donation)
+ print(generate_letter(name, donation))
def add_new_donation(name):
try:
@@ -41,7 +39,7 @@ def add_new_donation(name):
except (ValueError, EOFError):
print("Donation amount must be a number")
donor_db[name].append(donation)
- gen_letter(name, donation)
+ print(generate_letter(name, donation))
def thank_you_one(): # adding a new vendor
@@ -59,6 +57,9 @@ def thank_you_one(): # adding a new vendor
add_new_donation(name)
break
+def thank_you_all_text(key):
+ return "Dear {}, \n\n On behalf of all of us, we thank your for your generous donation. \n You have helped make a big impact on the community!".format(key)
+
# send the thank you letter to all donors
def thank_you_all():
path = os.getcwd()
@@ -68,7 +69,7 @@ def thank_you_all():
for key in donor_db:
timestamp = str(datetime.date.today())
with open(key + '_' + timestamp + ".txt", "w+") as f:
- f.write("Dear {}, \n\n On behalf of all of us, we thank your for your generous donation. \n You have helped make a big impact on the community!".format(key))
+ f.write(thank_you_all_text(key))
f.close()
print("Letters to all donors were generated.")
@@ -78,6 +79,9 @@ def thank_you_all():
def sort_key(data):
return data[1]
+def report_line(data):
+ return "{:<30} ${:12.2f} {:>15} ${:12.2f}".format(data[0], data[1], data[2], data[3])
+
# create a report of donors and amounts
def donor_report():
#using a list comprehension to simplify building the donor report
@@ -90,7 +94,7 @@ def donor_report():
print("{:<30} | {:<12} | {:>15} | {:12}".format("Donor Name", "Total Given", "Number of Gifts", "Average Gift")) #print the header
print("-"*79) #print the dashed line
for data in spreadsheet:
- print("{:<30} ${:12.2f} {:>15} ${:12.2f}".format(data[0], data[1], data[2], data[3]))
+ print(report_line(data))
def quit_program():
diff --git a/students/mjchang/session06/test_mailroom4.py b/students/mjchang/session06/test_mailroom4.py
index 9f401d39..c0ef5957 100644
--- a/students/mjchang/session06/test_mailroom4.py
+++ b/students/mjchang/session06/test_mailroom4.py
@@ -34,7 +34,6 @@ def test_gen_single_letter():
bring in a test donor, then check the letter"""
expected = "Dear Jacob Todd, \n\n Thank you for your generous donation of $ 100.00. \n You have helped make a big impact on the community!"
assert mr4.generate_letter("Jacob Todd", 100.00) == expected
-
def test_donor_addition():
@@ -58,13 +57,18 @@ def test_create_report():
def test_gen_letters():
""" test that letters were generated to separate files"""
+ path = os.getcwd()
+ folder = path + '/donor_letters/'
+ os.chdir(folder)
timestamp = str(datetime.date.today())
assert os.path.isfile('Tao Chien_'+timestamp+'.txt')
assert os.path.isfile('Joaquin Andieta_'+timestamp+'.txt')
def test_get_letter_text():
- expected = ""
-
+ """ test that content of generated letters is pulling in the name correctly
+ we don't want the letter to be addressed to the wrong person"""
+ expected = "Dear Eliza Sommers, \n\n On behalf of all of us, we thank your for your generous donation. \n You have helped make a big impact on the community!"
+ assert mr4.thank_you_all_text('Eliza Sommers') == expected
if __name__ == "__main__":
test_donor_list()
From 0d96c0b40562325ff4184723312a115394f5378d Mon Sep 17 00:00:00 2001
From: mjchang14
Date: Mon, 25 Feb 2019 22:35:25 -0800
Subject: [PATCH 013/367] submitting an updated version of test_mailroom4
---
students/mjchang/session06/test_mailroom4.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/students/mjchang/session06/test_mailroom4.py b/students/mjchang/session06/test_mailroom4.py
index c0ef5957..4ee12240 100644
--- a/students/mjchang/session06/test_mailroom4.py
+++ b/students/mjchang/session06/test_mailroom4.py
@@ -56,7 +56,8 @@ def test_create_report():
def test_gen_letters():
- """ test that letters were generated to separate files"""
+ """ test that letters were generated to separate files
+ mailroom4.py, option 2 has to be run first otherwise there's nothing to test against"""
path = os.getcwd()
folder = path + '/donor_letters/'
os.chdir(folder)
From 3501da99b3b03d2b41864e7fcb5d4aea8d144431 Mon Sep 17 00:00:00 2001
From: mjchang14
Date: Mon, 25 Feb 2019 22:39:24 -0800
Subject: [PATCH 014/367] Removing mailroom4.1.py
I overthought a few things and tried to make them work, but ended up reverting back to my previous file and used mailroom4 for the exercise.
---
students/mjchang/session06/mailroom4.1.py | 125 ----------------------
1 file changed, 125 deletions(-)
delete mode 100644 students/mjchang/session06/mailroom4.1.py
diff --git a/students/mjchang/session06/mailroom4.1.py b/students/mjchang/session06/mailroom4.1.py
deleted file mode 100644
index 2c683c20..00000000
--- a/students/mjchang/session06/mailroom4.1.py
+++ /dev/null
@@ -1,125 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-import datetime
-import sys
-import unittest
-
-
-def donor_db(): #defining donor database to make it easier to test
- return {"Eliza Sommers": [4000, 250, 70],
- "Tao Chien": [350, 1000, 225],
- "Joaquin Andieta": [100, 25],
- "Paulina Rodriguez": [50000],
- "Jacob Todd": [75, 80]}
-
-def donor_list(): #splitting thank_you_one function into multiple parts in mailroom4
- print('\n'.join(donor_db.keys())) #displays list of donors
-
-
-
-def thank_you_one(): # adding a new vendor
- while True:
- name = input("Please enter a full name (or 'list' for a list of current donors): ")
- name = name.title() #keeps capitalization format the same
- if name.lower() == "list":
- donor_list()
- else:
- break
-
- if name not in donor_db.keys(): #adding new donor
- print("Adding {} to the donor list".format(name))
- donor_db.setdefault(name, [])
- else:
- pass
-
-
- while True:
- name = name.title() #keep capitalization same as keys
- #adding exception for scenario where input isn't a number
- try:
- donation = input("Enter the new donation amount: ")
- donation = float(donation)
- except (ValueError, EOFError):
- print("Donation amount must be a number")
- continue
- donor_db[name].append(donation)
- break
- print("\n \n The ${:.2f} donation from {} was added".format(donation, name))
-
-# send the thank you letter to one donor
- print("\n \n Generating the letter for {}\n \n".format(name))
- print("Dear {}, \n\n On behalf of all of us, we thank your for your generous donation of ${:10.2f}. \n You have helped make a big impact on the community!".format(name, donation))
-
-
-# send the thank you letter to all donors
-def thank_you_all():
- path = os.getcwd()
- folder = path + '/donor_letters/'
- os.mkdir(folder)
- os.chdir(folder)
- for key in donor_db:
- timestamp = str(datetime.date.today())
- with open(key + '_' + timestamp + ".txt", "w+") as f:
- f.write("Dear {}, \n\n On behalf of all of us, we thank your for your generous donation. \n You have helped make a big impact on the community!".format(key))
- f.close()
-
- print("Letters to all donors were generated.")
-
-
-# set up for donor report
-def sort_key(data):
- return data[1]
-
-# create a report of donors and amounts
-def donor_report():
- #using a list comprehension to simplify building the donor report
- spreadsheet = [(name, sum(gifts), len(gifts), sum(gifts)/len(gifts))
- for name, gifts in donor_db.items()]
-
- #sort the report by total donation
- spreadsheet.sort(key = sort_key)
-
- print("{:<30} | {:<12} | {:>15} | {:12}".format("Donor Name", "Total Given", "Number of Gifts", "Average Gift")) #print the header
- print("-"*79) #print the dashed line
- for data in spreadsheet:
- print("{:<30} ${:12.2f} {:>15} ${:12.2f}".format(data[0], data[1], data[2], data[3]))
-
-
-def quit_program():
- print("Goodbye!\n")
- sys.exit()
-
-
-def main():
- while True:
- response = ''
- response = int(input("""
- Please enter a number from the following options:
- 1 - Send a Thank You to One Donor
- 2 - Send a Thank You to All Donors
- 3 - Create a Report
- 4 - Quit
- """))
- selection = {1: thank_you_one,
- 2: thank_you_all,
- 3: donor_report,
- 4: quit_program
- }
- #adding exception to handle responses other than 1-4
- try:
- if response in selection.keys():
- selection.get(response)()
- else:
- print("Please make a valid selection")
- except (ValueError, EOFError):
- print("Please select from the available options")
- continue
-
-
-if __name__ == "__main__":
-
-
- donor_db = donor_db()
-
- main()
\ No newline at end of file
From 41797f47496d0a27fbb13c11c9e3ad47fd5d276a Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Thu, 28 Feb 2019 10:50:01 -0800
Subject: [PATCH 015/367] Update get value function
---
students/jeff_shabani/session06/mailroom_4.py | 16 ----------------
1 file changed, 16 deletions(-)
diff --git a/students/jeff_shabani/session06/mailroom_4.py b/students/jeff_shabani/session06/mailroom_4.py
index b4feaf40..64cdcd25 100644
--- a/students/jeff_shabani/session06/mailroom_4.py
+++ b/students/jeff_shabani/session06/mailroom_4.py
@@ -34,22 +34,6 @@ def get_value(text, check_type):
print("Invalid value. Please try again")
continue
-def get_input(text):
- return input(text)
-
-def get_value_test(text, check_type):
- def get_value_test(text, check_type):
- """
- Catch non-numeric entries for donation amount.
- """
- text = get_input('Please enter a value')
- try:
- value = check_type(text)
- return True
- except ValueError:
- return False
-
-
def view_donor_names():
[print(name) for name in donors]
From 2af98192c3377116ffb2a28c131c260cc4d70311 Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Thu, 28 Feb 2019 11:06:19 -0800
Subject: [PATCH 016/367] Update testing to accept mock input.
---
students/jeff_shabani/session06/test_mailroom_4.py | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/students/jeff_shabani/session06/test_mailroom_4.py b/students/jeff_shabani/session06/test_mailroom_4.py
index 96ee7008..affe2db7 100644
--- a/students/jeff_shabani/session06/test_mailroom_4.py
+++ b/students/jeff_shabani/session06/test_mailroom_4.py
@@ -1,9 +1,8 @@
#!/usr/bin/env python3
+import mock
import unittest
from pathlib import Path
-from unittest.mock import patch
-
from students.jeff_shabani.session06 import mailroom_4
ANSWER = 'New_Donor'
@@ -59,13 +58,9 @@ def test_membership_in_dictionary(self):
self.assertIn('Bobby', mailroom_4.create_new_donors_dict())
- @patch('students.jeff_shabani.session06.mailroom_4.get_value_test')
- def test_correct_input(self, mock_input):
- """
- test for correct input. Not currently working.
- """
- mock_input.return_value = 6
- self.assertEqual(mailroom_4.get_value_test('Enter', int), 6)
+ @mock.patch('mailroom_4.get_value.input', mock.Mock(return_value='54'))
+ def test_correct_input(self):
+ self.assertEqual(mailroom_4.get_value('Enter a value:', int), 'Invalid')
if __name__ == '__main__':
From c1f768fe1de96d3263f50c1bab364013100fc5cf Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Thu, 28 Feb 2019 11:08:05 -0800
Subject: [PATCH 017/367] Update to html_render assignment
---
students/jeff_shabani/session07/html_render.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 0739e75e..1f3e2b80 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -9,7 +9,10 @@
class Element(object):
def __init__(self, content=None):
- self.content = str(content)
+ if content:
+ self.content = content
+ else:
+ self.content = ''
def append(self, new_content):
result = list()
From f420277b8d1356d27e3c5ba95efbca7306370777 Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Thu, 28 Feb 2019 15:28:48 -0800
Subject: [PATCH 018/367] Session07 files
---
students/jeff_shabani/session07/html_render.py | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 1f3e2b80..8944947d 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -23,9 +23,12 @@ def append(self, new_content):
def render(self, out_file):
- out_file.write("just something as a place holder...")
+ outtext = f'\n{self.content}\n'
+ out_file.write(outtext)
-e=Element()
-e.append('Wulliam\nB')
+e=Element('Erst Line')
+e.append('\nWulliam\nB')
+with open('test.html', 'w') as outf:
+ e.render(outf)
print(e.content)
From 56c13bca742592ae4a29a03e876d3c72d66a139b Mon Sep 17 00:00:00 2001
From: JRockwell70
Date: Thu, 28 Feb 2019 16:43:36 -0800
Subject: [PATCH 019/367] Update to html_render
---
students/jeff_shabani/session07/html_render.py | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 8944947d..c8bdbf54 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -18,17 +18,19 @@ def append(self, new_content):
result = list()
result.append(new_content)
for i in result:
- self.content +=i
+ self.content += i
return self.content
+ def tag(self, tag):
+ self.tag = ''
def render(self, out_file):
outtext = f'\n{self.content}\n'
out_file.write(outtext)
-e=Element('Erst Line')
+
+e = Element('Erst Line')
e.append('\nWulliam\nB')
with open('test.html', 'w') as outf:
e.render(outf)
print(e.content)
-
From 266c629cbcd1e91b14c66e6d480008dd2f08d17c Mon Sep 17 00:00:00 2001
From: admin <23247076+Rockwell70@users.noreply.github.com>
Date: Thu, 28 Feb 2019 19:07:23 -0800
Subject: [PATCH 020/367] First attempt at html_render.
---
students/jeff_shabani/session07/html_render.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 69734249..94301f76 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -24,5 +24,5 @@ def render(self, out_file):
e=Element()
e.append('Line1\nLine2')
-print(e.content)
+#print(e.content)
From d51976dbedbd0545dd31d8af2ace861d164efa53 Mon Sep 17 00:00:00 2001
From: admin <23247076+Rockwell70@users.noreply.github.com>
Date: Thu, 28 Feb 2019 19:07:50 -0800
Subject: [PATCH 021/367] First attempt at html_render.
---
students/jeff_shabani/session06/test_mailroom_4.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/students/jeff_shabani/session06/test_mailroom_4.py b/students/jeff_shabani/session06/test_mailroom_4.py
index 96ee7008..42832d99 100644
--- a/students/jeff_shabani/session06/test_mailroom_4.py
+++ b/students/jeff_shabani/session06/test_mailroom_4.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
+import mock
import unittest
from pathlib import Path
From 8777b94b61c8ee987a116043cde411cb17b5d082 Mon Sep 17 00:00:00 2001
From: admin <23247076+Rockwell70@users.noreply.github.com>
Date: Thu, 28 Feb 2019 20:12:23 -0800
Subject: [PATCH 022/367] Merge branch 'master' of
https://github.com/Rockwell70/GP_Python210B_Winter_2019
# Conflicts:
# students/jeff_shabani/session07/html_render.py
---
students/jeff_shabani/session07/html_render.py | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index c8bdbf54..098164f8 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -21,11 +21,15 @@ def append(self, new_content):
self.content += i
return self.content
- def tag(self, tag):
- self.tag = ''
+ def tag(self):
+ tag = ''
+ return tag
+
+
+
def render(self, out_file):
- outtext = f'\n{self.content}\n'
+ outtext = f'{self.tag()}\n{self.content}\n'
out_file.write(outtext)
From 3072e526a822c07b241b67f0ba22cedc91dd167b Mon Sep 17 00:00:00 2001
From: admin <23247076+Rockwell70@users.noreply.github.com>
Date: Thu, 28 Feb 2019 20:12:43 -0800
Subject: [PATCH 023/367] Merge branch 'master' of
https://github.com/Rockwell70/GP_Python210B_Winter_2019
# Conflicts:
# students/jeff_shabani/session07/html_render.py
---
students/jeff_shabani/session06/mailroom_4.py | 16 ----------------
1 file changed, 16 deletions(-)
diff --git a/students/jeff_shabani/session06/mailroom_4.py b/students/jeff_shabani/session06/mailroom_4.py
index b4feaf40..64cdcd25 100644
--- a/students/jeff_shabani/session06/mailroom_4.py
+++ b/students/jeff_shabani/session06/mailroom_4.py
@@ -34,22 +34,6 @@ def get_value(text, check_type):
print("Invalid value. Please try again")
continue
-def get_input(text):
- return input(text)
-
-def get_value_test(text, check_type):
- def get_value_test(text, check_type):
- """
- Catch non-numeric entries for donation amount.
- """
- text = get_input('Please enter a value')
- try:
- value = check_type(text)
- return True
- except ValueError:
- return False
-
-
def view_donor_names():
[print(name) for name in donors]
From 7beba59331145b8625a489d2795880032b3215a5 Mon Sep 17 00:00:00 2001
From: admin <23247076+Rockwell70@users.noreply.github.com>
Date: Thu, 28 Feb 2019 20:12:57 -0800
Subject: [PATCH 024/367] Merge branch 'master' of
https://github.com/Rockwell70/GP_Python210B_Winter_2019
# Conflicts:
# students/jeff_shabani/session07/html_render.py
---
students/jeff_shabani/session06/test_mailroom_4.py | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
diff --git a/students/jeff_shabani/session06/test_mailroom_4.py b/students/jeff_shabani/session06/test_mailroom_4.py
index 42832d99..affe2db7 100644
--- a/students/jeff_shabani/session06/test_mailroom_4.py
+++ b/students/jeff_shabani/session06/test_mailroom_4.py
@@ -3,8 +3,6 @@
import unittest
from pathlib import Path
-from unittest.mock import patch
-
from students.jeff_shabani.session06 import mailroom_4
ANSWER = 'New_Donor'
@@ -60,13 +58,9 @@ def test_membership_in_dictionary(self):
self.assertIn('Bobby', mailroom_4.create_new_donors_dict())
- @patch('students.jeff_shabani.session06.mailroom_4.get_value_test')
- def test_correct_input(self, mock_input):
- """
- test for correct input. Not currently working.
- """
- mock_input.return_value = 6
- self.assertEqual(mailroom_4.get_value_test('Enter', int), 6)
+ @mock.patch('mailroom_4.get_value.input', mock.Mock(return_value='54'))
+ def test_correct_input(self):
+ self.assertEqual(mailroom_4.get_value('Enter a value:', int), 'Invalid')
if __name__ == '__main__':
From 094d698e5d0412b7844f1a7b78ba3b8c4b79cfbe Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Fri, 1 Mar 2019 07:42:46 -0800
Subject: [PATCH 025/367] html_render update
---
students/jeff_shabani/session07/html_render.py | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 098164f8..b87fdcf1 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -22,14 +22,11 @@ def append(self, new_content):
return self.content
def tag(self):
- tag = ''
+ tag = 'body'
return tag
-
-
-
def render(self, out_file):
- outtext = f'{self.tag()}\n{self.content}\n'
+ outtext = f'<{self.tag()}>\n{self.content}\n{self.tag()}>'
out_file.write(outtext)
From adcd448ab91eef2b2df0772341c43625cf9b55b1 Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Fri, 1 Mar 2019 09:42:51 -0800
Subject: [PATCH 026/367] Session07 files
---
.../jeff_shabani/session07/html_render.py | 27 ++++++++++++-------
1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index b87fdcf1..58907e15 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -8,30 +8,39 @@
# This is the framework for the base class
class Element(object):
- def __init__(self, content=None):
+ def __init__(self, content=None, tag=None):
+ if tag:
+ self.tag = tag
+ else:
+ self.tag = ''
if content:
self.content = content
else:
self.content = ''
+
def append(self, new_content):
result = list()
result.append(new_content)
for i in result:
- self.content += i
+ self.content += f'\n{i}\n'
return self.content
- def tag(self):
- tag = 'body'
- return tag
def render(self, out_file):
- outtext = f'<{self.tag()}>\n{self.content}\n{self.tag()}>'
+ outtext = f'<{self.tag}>\n{self.content}\n{self.tag}>'
out_file.write(outtext)
-e = Element('Erst Line')
-e.append('\nWulliam\nB')
+e = Element('First Line', 'body')
+e.append('Second Line\nThird line')
+
with open('test.html', 'w') as outf:
e.render(outf)
-print(e.content)
+
+# """
+# Step 2 part A
+# """
+# html_sub = Element('HTML subclass 1st line', 'html')
+# html_sub.append('')
+
From 037398853ef6606eeaf1b61ec1dc45c754994997 Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Fri, 1 Mar 2019 09:51:33 -0800
Subject: [PATCH 027/367] html_render update
---
.../jeff_shabani/session07/html_render.py | 26 +++++++++++--------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 58907e15..b9969bf9 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -23,24 +23,28 @@ def append(self, new_content):
result = list()
result.append(new_content)
for i in result:
- self.content += f'\n{i}\n'
+ self.content += i
return self.content
- def render(self, out_file):
+ # def render(self, out_file):
+ # outtext = f'<{self.tag}>\n{self.content}\n{self.tag}>'
+ # out_file.write(outtext)
+
+ def render2(self, file_name, open_method):
outtext = f'<{self.tag}>\n{self.content}\n{self.tag}>'
- out_file.write(outtext)
+ with open(f'{file_name}.html', open_method) as file:
+ file.write(outtext)
e = Element('First Line', 'body')
e.append('Second Line\nThird line')
+e.render2('test', 'w')
-with open('test.html', 'w') as outf:
- e.render(outf)
-
-# """
-# Step 2 part A
-# """
-# html_sub = Element('HTML subclass 1st line', 'html')
-# html_sub.append('')
+"""
+Step 2 part A
+"""
+html_sub = Element('HTML subclass 1st line', 'html')
+html_sub.append('\nHTML subclass 2nd line')
+html_sub.render2('html_subclass', 'w')
From b3fbaad36312864d6e45a8b6813a5c8101cc599b Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Fri, 1 Mar 2019 15:37:22 -0800
Subject: [PATCH 028/367] Session07 files
---
.../jeff_shabani/session07/html_render.py | 64 ++++++++++++++-----
1 file changed, 49 insertions(+), 15 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index b9969bf9..97fdcf3b 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -8,7 +8,8 @@
# This is the framework for the base class
class Element(object):
- def __init__(self, content=None, tag=None):
+ def __init__(self, content=None, tag=None, **attrs):
+ self.attrs = attrs
if tag:
self.tag = tag
else:
@@ -23,28 +24,61 @@ def append(self, new_content):
result = list()
result.append(new_content)
for i in result:
- self.content += i
+ self.content += f'\n{i}\n'
return self.content
- # def render(self, out_file):
- # outtext = f'<{self.tag}>\n{self.content}\n{self.tag}>'
- # out_file.write(outtext)
-
- def render2(self, file_name, open_method):
- outtext = f'<{self.tag}>\n{self.content}\n{self.tag}>'
+ def render(self, file_name, open_method='w'):
+ head = f'{self.tag} '
+ for k,v in self.attrs.items():
+ head += f'{k}={v}'
+ #outtext = f'<{self.tag}>\n{self.content}\n{self.tag}>'
+ outtext = f'<{head}>\n{self.content}\n{self.tag}>'
with open(f'{file_name}.html', open_method) as file:
file.write(outtext)
-e = Element('First Line', 'body')
-e.append('Second Line\nThird line')
-e.render2('test', 'w')
+"""
+Step 2 part B
+"""
+class HTML(Element):
+ tag = 'html'
+
+
+class PTag(Element):
+ tag = 'p'
+
"""
-Step 2 part A
+Step 3
"""
-html_sub = Element('HTML subclass 1st line', 'html')
-html_sub.append('\nHTML subclass 2nd line')
-html_sub.render2('html_subclass', 'w')
+class OneLineTag(Element):
+ def render(self, file_name, open_method='w'):
+ outtext = f'<{self.tag}> {self.content} {self.tag}>'
+ with open(f'{file_name}.html', open_method) as file:
+ file.write(outtext)
+
+
+if __name__ == '__main__':
+ # e = Element("this is some text", 'body')
+ # e.append("and this is some more text")
+ # e.render('test')
+
+ #html sub-class
+ # html_sub = HTML('HTML subclass 1st line', 'html')
+ # print(html_sub.tag)
+ # html_sub.append('HTML subclass 2nd line')
+ # html_sub.render('html_subclass')
+ #
+ # #p subclass
+ # p_sub = PTag('p subclass 1st line', 'p')
+ # p_sub.append('p subclass 2nd line')
+ # p_sub.render('p_subclass')
+ #
+ # olt = OneLineTag('PythonClass - oneliner', 'title')
+ # olt.render('OneLingTagTest')
+
+ attrs_test = Element('kwargs test', 'html',style='text-align', id='intro')
+ attrs_test.append('kwargstest line 2')
+ attrs_test.render('kwargs_test')
From ea0bd7cb8b7fe39a7c766bf49a15e89b4778eca9 Mon Sep 17 00:00:00 2001
From: admin <23247076+Rockwell70@users.noreply.github.com>
Date: Fri, 1 Mar 2019 17:54:14 -0800
Subject: [PATCH 029/367] html_render update
---
students/jeff_shabani/session07/html_render.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 97fdcf3b..91733a7a 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -29,9 +29,9 @@ def append(self, new_content):
def render(self, file_name, open_method='w'):
- head = f'{self.tag} '
+ head = f'{self.tag.ljust(len(self.tag)+1)}'
for k,v in self.attrs.items():
- head += f'{k}={v}'
+ head += f'{k.rjust(len(k)+1)}="{v}"'
#outtext = f'<{self.tag}>\n{self.content}\n{self.tag}>'
outtext = f'<{head}>\n{self.content}\n{self.tag}>'
with open(f'{file_name}.html', open_method) as file:
From b75d11e4ac5c913ec823cdc4021fb7c462918ef8 Mon Sep 17 00:00:00 2001
From: admin <23247076+Rockwell70@users.noreply.github.com>
Date: Fri, 1 Mar 2019 18:00:28 -0800
Subject: [PATCH 030/367] html_render update
---
students/jeff_shabani/session07/html_render.py | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 91733a7a..cbf8a618 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -54,7 +54,10 @@ class PTag(Element):
"""
class OneLineTag(Element):
def render(self, file_name, open_method='w'):
- outtext = f'<{self.tag}> {self.content} {self.tag}>'
+ head = f'{self.tag.ljust(len(self.tag)+1)}'
+ for k,v in self.attrs.items():
+ head += f'{k.rjust(len(k)+1)}="{v}"'
+ outtext = f'<{head}>\n{self.content}\n{self.tag}>'
with open(f'{file_name}.html', open_method) as file:
file.write(outtext)
@@ -78,6 +81,10 @@ def render(self, file_name, open_method='w'):
# olt = OneLineTag('PythonClass - oneliner', 'title')
# olt.render('OneLingTagTest')
+ """
+ step 4
+ """
+
attrs_test = Element('kwargs test', 'html',style='text-align', id='intro')
attrs_test.append('kwargstest line 2')
attrs_test.render('kwargs_test')
From aa5d94350a721a992c5d27b89cc7034a88336297 Mon Sep 17 00:00:00 2001
From: admin <23247076+Rockwell70@users.noreply.github.com>
Date: Fri, 1 Mar 2019 19:40:30 -0800
Subject: [PATCH 031/367] html_render update
---
.../jeff_shabani/session07/html_render.py | 43 ++++++++++++++++---
1 file changed, 37 insertions(+), 6 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index cbf8a618..10457699 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -53,6 +53,7 @@ class PTag(Element):
Step 3
"""
class OneLineTag(Element):
+
def render(self, file_name, open_method='w'):
head = f'{self.tag.ljust(len(self.tag)+1)}'
for k,v in self.attrs.items():
@@ -61,6 +62,27 @@ def render(self, file_name, open_method='w'):
with open(f'{file_name}.html', open_method) as file:
file.write(outtext)
+"""
+Step 5
+"""
+class SelfClosingTag(Element):
+
+
+ def render(self, file_name, open_method='w'):
+ if self.content:
+ return TypeError
+ else:
+ self.content =''
+ return self.content
+
+ head = f'{self.tag.ljust(len(self.tag)+1)}'
+ for k,v in self.attrs.items():
+ head += f'{k.rjust(len(k)+1)}="{v}"'
+ outtext = f'<{head}/>'
+ with open(f'{file_name}.html', open_method) as file:
+ file.write(outtext)
+
+
if __name__ == '__main__':
# e = Element("this is some text", 'body')
@@ -78,14 +100,23 @@ def render(self, file_name, open_method='w'):
# p_sub.append('p subclass 2nd line')
# p_sub.render('p_subclass')
#
- # olt = OneLineTag('PythonClass - oneliner', 'title')
+ """
+ Step 3
+ """
+ # olt = OneLineTag('PythonClass - oneliner', 'title', style='text-align')
# olt.render('OneLingTagTest')
+ #
+ # """
+ # step 4
+ # """
+ # attrs_test = Element('kwargs test', 'html',style='text-align', id='intro')
+ # attrs_test.append('kwargstest line 2')
+ # attrs_test.render('kwargs_test')
"""
- step 4
+ step 5
"""
-
- attrs_test = Element('kwargs test', 'html',style='text-align', id='intro')
- attrs_test.append('kwargstest line 2')
- attrs_test.render('kwargs_test')
+ #sct_test = SelfClosingTag('html',style='text-align', id='intro')
+ sct_test = SelfClosingTag('html')
+ sct_test.render('sct_test')
From c13f342319ca9b14a7745d76e90ca1cb71a94765 Mon Sep 17 00:00:00 2001
From: mjchang14
Date: Sat, 2 Mar 2019 00:19:57 -0800
Subject: [PATCH 032/367] adding html_render through step 3
---
students/mjchang/session07/html_render.py | 58 ++++
.../mjchang/session07/test_html_render.py | 290 ++++++++++++++++++
2 files changed, 348 insertions(+)
create mode 100644 students/mjchang/session07/html_render.py
create mode 100644 students/mjchang/session07/test_html_render.py
diff --git a/students/mjchang/session07/html_render.py b/students/mjchang/session07/html_render.py
new file mode 100644
index 00000000..291351f3
--- /dev/null
+++ b/students/mjchang/session07/html_render.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python3
+
+"""
+A class-based system for rendering html.
+"""
+
+
+# This is the framework for the base class
+class Element(object):
+
+ tag = "html"
+
+ def __init__(self, content=None):
+ self.contents = []
+ if content:
+ self.contents.append(content)
+
+ def append(self, new_content):
+ self.contents.append(new_content)
+
+ def render(self, out_file):
+ for content in self.contents: #adding contents to file
+ out_file.write("<{}>\n".format(self.tag))
+ try:
+ content.render(out_file)
+ except AttributeError:
+ out_file.write(content)
+ out_file.write("\n") #newline to keep it readable
+ out_file.write("{}>\n".format(self.tag))
+
+class OneLineTag(Element):
+ def render(self, out_file,):
+ for content in self.contents:
+ out_file.write("<{}>".format(self.tag)) #removed newline
+ try:
+ content.render(out_file)
+ except AttributeError:
+ out_file.write(content) #removed newline from Element
+ out_file.write("{}>\n".format(self.tag))
+
+ def append(self, content):
+ raise NotImplementedError
+
+
+class Html(Element):
+ tag = "html"
+
+class Body(Element):
+ tag = "body"
+
+class P(Element):
+ tag = "p"
+
+class Head(Element):
+ tag = "head"
+
+class Title(OneLineTag):
+ tag = "title"
diff --git a/students/mjchang/session07/test_html_render.py b/students/mjchang/session07/test_html_render.py
new file mode 100644
index 00000000..f1228939
--- /dev/null
+++ b/students/mjchang/session07/test_html_render.py
@@ -0,0 +1,290 @@
+"""
+test code for html_render.py
+
+This is just a start -- you will need more tests!
+"""
+
+import io
+import pytest
+
+# import * is often bad form, but makes it easier to test everything in a module.
+from html_render import *
+
+
+# utility function for testing render methods
+# needs to be used in multiple tests, so we write it once here.
+def render_result(element, ind=""):
+ """
+ calls the element's render method, and returns what got rendered as a
+ string
+ """
+ # the StringIO object is a "file-like" object -- something that
+ # provides the methods of a file, but keeps everything in memory
+ # so it can be used to test code that writes to a file, without
+ # having to actually write to disk.
+ outfile = io.StringIO()
+ # this so the tests will work before we tackle indentation
+ if ind:
+ element.render(outfile, ind)
+ else:
+ element.render(outfile)
+ return outfile.getvalue()
+
+########
+# Step 1
+########
+
+def test_init():
+ """
+ This only tests that it can be initialized with and without
+ some content -- but it's a start
+ """
+ e = Element()
+
+ e = Element("this is some text")
+
+
+def test_append():
+ """
+ This tests that you can append text
+
+ It doesn't test if it works --
+ that will be covered by the render test later
+ """
+ e = Element("this is some text")
+ e.append("some more text")
+
+
+def test_render_element():
+ """
+ Tests whether the Element can render two pieces of text
+ So it is also testing that the append method works correctly.
+
+ It is not testing whether indentation or line feeds are correct.
+ """
+ e = Element("this is some text")
+ e.append("and this is some more text")
+
+ # This uses the render_results utility above
+ file_contents = render_result(e).strip()
+
+ # making sure the content got in there.
+ assert("this is some text") in file_contents
+ assert("and this is some more text") in file_contents
+
+ # make sure it's in the right order
+ assert file_contents.index("this is") < file_contents.index("and this")
+
+ # making sure the opening and closing tags are right.
+ assert file_contents.startswith("")
+ assert file_contents.endswith("")
+
+# Uncomment this one after you get the one above to pass
+# Does it pass right away?
+def test_render_element2():
+ """
+ Tests whether the Element can render two pieces of text
+ So it is also testing that the append method works correctly.
+
+ It is not testing whether indentation or line feeds are correct.
+ """
+ e = Element()
+ e.append("this is some text")
+ e.append("and this is some more text")
+
+ # This uses the render_results utility above
+ file_contents = render_result(e).strip()
+
+ # making sure the content got in there.
+ assert("this is some text") in file_contents
+ assert("and this is some more text") in file_contents
+
+ # make sure it's in the right order
+ assert file_contents.index("this is") < file_contents.index("and this")
+
+ # making sure the opening and closing tags are right.
+ assert file_contents.startswith("")
+ assert file_contents.endswith("")
+
+
+
+# ########
+# # Step 2
+# ########
+
+# tests for the new tags
+def test_html():
+ e = Html("this is some text")
+ e.append("and this is some more text")
+
+ file_contents = render_result(e).strip()
+
+ assert("this is some text") in file_contents
+ assert("and this is some more text") in file_contents
+ print(file_contents)
+ assert file_contents.endswith("")
+
+
+def test_body():
+ e = Body("this is some text")
+ e.append("and this is some more text")
+
+ file_contents = render_result(e).strip()
+
+ assert("this is some text") in file_contents
+ assert("and this is some more text") in file_contents
+
+ assert file_contents.startswith("")
+ assert file_contents.endswith("")
+
+
+def test_p():
+ e = P("this is some text")
+ e.append("and this is some more text")
+
+ file_contents = render_result(e).strip()
+
+ assert("this is some text") in file_contents
+ assert("and this is some more text") in file_contents
+
+ assert file_contents.startswith("")
+ assert file_contents.endswith("
")
+
+
+def test_sub_element():
+ """
+ tests that you can add another element and still render properly
+ """
+ page = Html()
+ page.append("some plain text.")
+ page.append(P("A simple paragraph of text"))
+ page.append("Some more plain text.")
+
+ file_contents = render_result(page)
+ print(file_contents) # so we can see it if the test fails
+
+ # note: The previous tests should make sure that the tags are getting
+ # properly rendered, so we don't need to test that here.
+ assert "some plain text" in file_contents
+ assert "A simple paragraph of text" in file_contents
+ assert "Some more plain text." in file_contents
+ assert "some plain text" in file_contents
+ # but make sure the embedded element's tags get rendered!
+ assert "" in file_contents
+ assert "" in file_contents
+
+
+
+
+#######
+# Step 3
+#######
+
+def test_head():
+ e = Head("this is a text header")
+
+ file_contents = render_result(e).strip()
+
+ assert("this is a text header") in file_contents
+ assert file_contents.startswith("")
+ assert file_contents.endswith("")
+
+def test_title():
+ e = Title("This is a Title")
+ # print(file_contents)
+ file_contents = render_result(e).strip()
+
+ assert("This is a Title") in file_contents
+ assert file_contents.startswith("")
+ assert file_contents.endswith("")
+ assert "\n" not in file_contents
+
+
+def test_one_line_tag_append():
+ e = OneLineTag("initial content")
+ with pytest.raises(NotImplementedError): #disallow appending text
+ e.append("more content")
+
+ file_contents = render_result(e).strip()
+
+
+#####################
+# indentation testing
+# Uncomment for Step 9 -- adding indentation
+#####################
+
+
+# def test_indent():
+# """
+# Tests that the indentation gets passed through to the renderer
+# """
+# html = Html("some content")
+# file_contents = render_result(html, ind=" ").rstrip() #remove the end newline
+
+# print(file_contents)
+# lines = file_contents.split("\n")
+# assert lines[0].startswith(" <")
+# print(repr(lines[-1]))
+# assert lines[-1].startswith(" <")
+
+
+# def test_indent_contents():
+# """
+# The contents in a element should be indented more than the tag
+# by the amount in the indent class attribute
+# """
+# html = Element("some content")
+# file_contents = render_result(html, ind="")
+
+# print(file_contents)
+# lines = file_contents.split("\n")
+# assert lines[1].startswith(Element.indent)
+
+
+# def test_multiple_indent():
+# """
+# make sure multiple levels get indented fully
+# """
+# body = Body()
+# body.append(P("some text"))
+# html = Html(body)
+
+# file_contents = render_result(html)
+
+# print(file_contents)
+# lines = file_contents.split("\n")
+# for i in range(3): # this needed to be adapted to the tag
+# assert lines[i + 1].startswith(i * Element.indent + "<")
+
+# assert lines[4].startswith(3 * Element.indent + "some")
+
+
+# def test_element_indent1():
+# """
+# Tests whether the Element indents at least simple content
+
+# we are expecting to to look like this:
+
+#
+# this is some text
+# <\html>
+
+# More complex indentation should be tested later.
+# """
+# e = Element("this is some text")
+
+# # This uses the render_results utility above
+# file_contents = render_result(e).strip()
+
+# # making sure the content got in there.
+# assert("this is some text") in file_contents
+
+# # break into lines to check indentation
+# lines = file_contents.split('\n')
+# # making sure the opening and closing tags are right.
+# assert lines[0] == ""
+# # this line should be indented by the amount specified
+# # by the class attribute: "indent"
+# assert lines[1].startswith(Element.indent + "thi")
+# assert lines[2] == ""
+# assert file_contents.endswith("")
From 575826301b424f63310f512ff5c92210fe5350ec Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Sat, 2 Mar 2019 09:44:34 -0800
Subject: [PATCH 033/367] html_render update
---
.../jeff_shabani/session07/html_render.py | 49 ++++++++++---------
1 file changed, 25 insertions(+), 24 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 10457699..66d942c8 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -19,7 +19,6 @@ def __init__(self, content=None, tag=None, **attrs):
else:
self.content = ''
-
def append(self, new_content):
result = list()
result.append(new_content)
@@ -27,12 +26,10 @@ def append(self, new_content):
self.content += f'\n{i}\n'
return self.content
-
def render(self, file_name, open_method='w'):
- head = f'{self.tag.ljust(len(self.tag)+1)}'
- for k,v in self.attrs.items():
- head += f'{k.rjust(len(k)+1)}="{v}"'
- #outtext = f'<{self.tag}>\n{self.content}\n{self.tag}>'
+ head = f'{self.tag.ljust(len(self.tag) + 1)}'
+ for k, v in self.attrs.items():
+ head += f'{k.rjust(len(k) + 1)}="{v}"'
outtext = f'<{head}>\n{self.content}\n{self.tag}>'
with open(f'{file_name}.html', open_method) as file:
file.write(outtext)
@@ -41,6 +38,8 @@ def render(self, file_name, open_method='w'):
"""
Step 2 part B
"""
+
+
class HTML(Element):
tag = 'html'
@@ -50,46 +49,48 @@ class PTag(Element):
"""
-Step 3
+Step 3: print on one line
"""
+
+
class OneLineTag(Element):
def render(self, file_name, open_method='w'):
- head = f'{self.tag.ljust(len(self.tag)+1)}'
- for k,v in self.attrs.items():
- head += f'{k.rjust(len(k)+1)}="{v}"'
+ head = f'{self.tag.ljust(len(self.tag) + 1)}'
+ for k, v in self.attrs.items():
+ head += f'{k.rjust(len(k) + 1)}="{v}"'
outtext = f'<{head}>\n{self.content}\n{self.tag}>'
with open(f'{file_name}.html', open_method) as file:
file.write(outtext)
+
"""
-Step 5
+Step 5: Self closing tag
"""
-class SelfClosingTag(Element):
+class SelfClosingTag(Element):
+
def render(self, file_name, open_method='w'):
if self.content:
- return TypeError
+ print('Self closing tags do not have content')
else:
- self.content =''
- return self.content
+ self.content = ''
- head = f'{self.tag.ljust(len(self.tag)+1)}'
- for k,v in self.attrs.items():
- head += f'{k.rjust(len(k)+1)}="{v}"'
+ head = f'{self.tag.ljust(len(self.tag) + 1)}'
+ for k, v in self.attrs.items():
+ head += f'{k.rjust(len(k) + 1)}="{v}"'
outtext = f'<{head}/>'
with open(f'{file_name}.html', open_method) as file:
file.write(outtext)
-
if __name__ == '__main__':
# e = Element("this is some text", 'body')
# e.append("and this is some more text")
# e.render('test')
- #html sub-class
+ # html sub-class
# html_sub = HTML('HTML subclass 1st line', 'html')
# print(html_sub.tag)
# html_sub.append('HTML subclass 2nd line')
@@ -114,9 +115,9 @@ def render(self, file_name, open_method='w'):
# attrs_test.render('kwargs_test')
"""
- step 5
+ step 5 test for self closing tag
"""
- #sct_test = SelfClosingTag('html',style='text-align', id='intro')
- sct_test = SelfClosingTag('html')
+ # sct_test = SelfClosingTag('html',style='text-align', id='intro')
+ sct_test = SelfClosingTag('_', 'html')
sct_test.render('sct_test')
-
+ # print(dir(sct_test))
From b91b6ada9a21697f9084807a0bf2ef1eafd6570f Mon Sep 17 00:00:00 2001
From: Rockwell70
Date: Sat, 2 Mar 2019 09:52:05 -0800
Subject: [PATCH 034/367] html_render update
---
students/jeff_shabani/session07/html_render.py | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 66d942c8..f76644e4 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -72,8 +72,13 @@ def render(self, file_name, open_method='w'):
class SelfClosingTag(Element):
def render(self, file_name, open_method='w'):
+ """
+ if conent is entered this tells user that self closing tags
+ can't have conent and resets the conent to an empty string.
+ """
+
if self.content:
- print('Self closing tags do not have content')
+ print('Self closing tags cannot have content')
else:
self.content = ''
From fbe4eab95883ff36c2b4b71c646a21f3dde20b74 Mon Sep 17 00:00:00 2001
From: Rockwell70
Date: Sat, 2 Mar 2019 18:18:01 -0800
Subject: [PATCH 035/367] html_render update
---
students/jeff_shabani/session07/html_render.py | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index f76644e4..26a511ee 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -56,10 +56,11 @@ class PTag(Element):
class OneLineTag(Element):
def render(self, file_name, open_method='w'):
+ self.tag = f'{self.tag}>'
head = f'{self.tag.ljust(len(self.tag) + 1)}'
for k, v in self.attrs.items():
head += f'{k.rjust(len(k) + 1)}="{v}"'
- outtext = f'<{head}>\n{self.content}\n{self.tag}>'
+ outtext = f'<{head}{self.content}{self.tag}>'
with open(f'{file_name}.html', open_method) as file:
file.write(outtext)
@@ -109,8 +110,8 @@ def render(self, file_name, open_method='w'):
"""
Step 3
"""
- # olt = OneLineTag('PythonClass - oneliner', 'title', style='text-align')
- # olt.render('OneLingTagTest')
+ olt = OneLineTag('PythonClass - oneliner', 'title', style='text-align')
+ olt.render('OneLingTagTest')
#
# """
# step 4
@@ -123,6 +124,6 @@ def render(self, file_name, open_method='w'):
step 5 test for self closing tag
"""
# sct_test = SelfClosingTag('html',style='text-align', id='intro')
- sct_test = SelfClosingTag('_', 'html')
- sct_test.render('sct_test')
+ # sct_test = SelfClosingTag('_', 'html')
+ # sct_test.render('sct_test')
# print(dir(sct_test))
From 8c059b266d68e6c2169561a31b4e0af3783ee90f Mon Sep 17 00:00:00 2001
From: mjchang14
Date: Sun, 3 Mar 2019 01:12:38 -0800
Subject: [PATCH 036/367] adding html_render through step 5
---
students/mjchang/session07/html_render.py | 58 ++++-
students/mjchang/session07/run_html_render.py | 231 ++++++++++++++++++
.../mjchang/session07/test_html_render.py | 54 ++++
3 files changed, 337 insertions(+), 6 deletions(-)
create mode 100644 students/mjchang/session07/run_html_render.py
diff --git a/students/mjchang/session07/html_render.py b/students/mjchang/session07/html_render.py
index 291351f3..7c27a67f 100644
--- a/students/mjchang/session07/html_render.py
+++ b/students/mjchang/session07/html_render.py
@@ -10,7 +10,8 @@ class Element(object):
tag = "html"
- def __init__(self, content=None):
+ def __init__(self, content=None, **kwargs):
+ self.attributes = kwargs
self.contents = []
if content:
self.contents.append(content)
@@ -18,18 +19,33 @@ def __init__(self, content=None):
def append(self, new_content):
self.contents.append(new_content)
+
def render(self, out_file):
- for content in self.contents: #adding contents to file
- out_file.write("<{}>\n".format(self.tag))
+ out_file.write(self._open_tag())
+ out_file.write("\n")
+ for content in self.contents:
try:
content.render(out_file)
except AttributeError:
out_file.write(content)
- out_file.write("\n") #newline to keep it readable
- out_file.write("{}>\n".format(self.tag))
+ out_file.write("\n")
+ out_file.write(self._close_tag())
+ out_file.write("\n")
+
+ def _open_tag(self):
+ open_tag = ["<{}".format(self.tag)]
+ for key, value in self.attributes.items():
+ open_tag.append(' {}="{}"'.format(key, value))
+ open_tag.append(">")
+ return "".join(open_tag)
+
+ def _close_tag(self):
+ return "{}>\n".format(self.tag)
+
+
class OneLineTag(Element):
- def render(self, out_file,):
+ def render(self, out_file):
for content in self.contents:
out_file.write("<{}>".format(self.tag)) #removed newline
try:
@@ -42,6 +58,26 @@ def append(self, content):
raise NotImplementedError
+class SelfClosingTag(Element):
+ def __init__(self, content=None, **kwargs):
+ if content is not None:
+ raise TypeError("SelfClosingTag cannot contain any content")
+ super().__init__(content=content, **kwargs)
+
+ def render(self, out_file):
+ tag = self._open_tag()[:-1] + " />\n"
+ out_file.write(tag)
+
+ def append(self, *args):
+ raise TypeError("You cannot add content to SelfClosingTag")
+
+
+class Hr(SelfClosingTag):
+ tag = "hr"
+
+class Br(SelfClosingTag):
+ tag = "br"
+
class Html(Element):
tag = "html"
@@ -56,3 +92,13 @@ class Head(Element):
class Title(OneLineTag):
tag = "title"
+
+class Ul(Element):
+ tag = "ul"
+
+class List(Element):
+ tag = "li"
+
+class Anchor(Element):
+ tag = "a"
+
diff --git a/students/mjchang/session07/run_html_render.py b/students/mjchang/session07/run_html_render.py
new file mode 100644
index 00000000..05e5453b
--- /dev/null
+++ b/students/mjchang/session07/run_html_render.py
@@ -0,0 +1,231 @@
+#!/usr/bin/env python3
+
+"""
+a simple script can run and test your html rendering classes.
+
+Uncomment the steps as you add to your rendering.
+
+"""
+
+from io import StringIO
+
+# importing the html_rendering code with a short name for easy typing.
+import html_render as hr
+
+
+# writing the file out:
+def render_page(page, filename, indent=None):
+ """
+ render the tree of elements
+
+ This uses StringIO to render to memory, then dump to console and
+ write to file -- very handy!
+ """
+
+ f = StringIO()
+ if indent is None:
+ page.render(f)
+ else:
+ page.render(f, indent)
+
+ print(f.getvalue())
+ with open(filename, 'w') as outfile:
+ outfile.write(f.getvalue())
+
+
+# # Step 1
+# #########
+
+# page = hr.Element()
+
+# page.append("Here is a paragraph of text -- there could be more of them, "
+# "but this is enough to show that we can do some text")
+
+# page.append("And here is another piece of text -- you should be able to add any number")
+
+# render_page(page, "test_html_output1.html")
+
+# # The rest of the steps have been commented out.
+# # Uncomment them as you move along with the assignment.
+
+## Step 2
+##########
+
+page = hr.Html()
+
+body = hr.Body()
+
+body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+ "but this is enough to show that we can do some text"))
+
+body.append(hr.P("And here is another piece of text -- you should be able to add any number"))
+
+page.append(body)
+
+render_page(page, "test_html_output2.html")
+
+# Step 3
+##########
+
+page = hr.Html()
+
+head = hr.Head()
+head.append(hr.Title("PythonClass = Revision 1087:"))
+
+page.append(head)
+
+body = hr.Body()
+
+body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+ "but this is enough to show that we can do some text"))
+body.append(hr.P("And here is another piece of text -- you should be able to add any number"))
+
+page.append(body)
+
+render_page(page, "test_html_output3.html")
+
+# Step 4
+##########
+
+page = hr.Html()
+
+head = hr.Head()
+head.append(hr.Title("PythonClass = Revision 1087:"))
+
+page.append(head)
+
+body = hr.Body()
+
+body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+ "but this is enough to show that we can do some text",
+ style="text-align: center; font-style: oblique;"))
+
+page.append(body)
+
+render_page(page, "test_html_output4.html")
+
+# Step 5
+#########
+
+page = hr.Html()
+
+head = hr.Head()
+head.append(hr.Title("PythonClass = Revision 1087:"))
+
+page.append(head)
+
+body = hr.Body()
+
+body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+ "but this is enough to show that we can do some text",
+ style="text-align: center; font-style: oblique;"))
+
+body.append(hr.Hr())
+
+page.append(body)
+
+render_page(page, "test_html_output5.html")
+
+# # Step 6
+# #########
+
+# page = hr.Html()
+
+# head = hr.Head()
+# head.append(hr.Title("PythonClass = Revision 1087:"))
+
+# page.append(head)
+
+# body = hr.Body()
+
+# body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+# "but this is enough to show that we can do some text",
+# style="text-align: center; font-style: oblique;"))
+
+# body.append(hr.Hr())
+
+# body.append("And this is a ")
+# body.append( hr.A("http://google.com/", "link") )
+# body.append("to google")
+
+# page.append(body)
+
+# render_page(page, "test_html_output6.html")
+
+# # Step 7
+# #########
+
+# page = hr.Html()
+
+# head = hr.Head()
+# head.append(hr.Title("PythonClass = Revision 1087:"))
+
+# page.append(head)
+
+# body = hr.Body()
+
+# body.append( hr.H(2, "PythonClass - Class 6 example") )
+
+# body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+# "but this is enough to show that we can do some text",
+# style="text-align: center; font-style: oblique;"))
+
+# body.append(hr.Hr())
+
+# list = hr.Ul(id="TheList", style="line-height:200%")
+
+# list.append( hr.Li("The first item in a list") )
+# list.append( hr.Li("This is the second item", style="color: red") )
+
+# item = hr.Li()
+# item.append("And this is a ")
+# item.append( hr.A("http://google.com/", "link") )
+# item.append("to google")
+
+# list.append(item)
+
+# body.append(list)
+
+# page.append(body)
+
+# render_page(page, "test_html_output7.html")
+
+# # Step 8 and 9
+# ##############
+
+# page = hr.Html()
+
+
+# head = hr.Head()
+# head.append( hr.Meta(charset="UTF-8") )
+# head.append(hr.Title("PythonClass = Revision 1087:"))
+
+# page.append(head)
+
+# body = hr.Body()
+
+# body.append( hr.H(2, "PythonClass - Example") )
+
+# body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+# "but this is enough to show that we can do some text",
+# style="text-align: center; font-style: oblique;"))
+
+# body.append(hr.Hr())
+
+# list = hr.Ul(id="TheList", style="line-height:200%")
+
+# list.append( hr.Li("The first item in a list") )
+# list.append( hr.Li("This is the second item", style="color: red") )
+
+# item = hr.Li()
+# item.append("And this is a ")
+# item.append( hr.A("http://google.com/", "link") )
+# item.append("to google")
+
+# list.append(item)
+
+# body.append(list)
+
+# page.append(body)
+
+# render_page(page, "test_html_output8.html")
diff --git a/students/mjchang/session07/test_html_render.py b/students/mjchang/session07/test_html_render.py
index f1228939..ac8dc97d 100644
--- a/students/mjchang/session07/test_html_render.py
+++ b/students/mjchang/session07/test_html_render.py
@@ -208,6 +208,60 @@ def test_one_line_tag_append():
file_contents = render_result(e).strip()
+#######
+# Step 4
+#######
+
+
+def test_attributes():
+ e = P("A paragraph of text", style="text-align: center", id="intro")
+ file_contents = render_result(e).strip()
+ print(file_contents)
+ assert "A paragraph of text" in file_contents
+ assert file_contents.endswith("
")
+ assert file_contents.startswith(" because open tag more complex
+ # assert False
+ assert 'style="text-align: center"' in file_contents
+ assert 'id="intro"' in file_contents
+ assert file_contents[:-1].index(">") > file_contents.index('id="intro"')
+ assert file_contents[:file_contents.index(">")].count(" ") == 3
+
+
+#######
+# Step 5
+#######
+
+def test_hr():
+ hr = Hr()
+ file_contents = render_result(hr)
+ print(file_contents)
+ assert file_contents == '
\n'
+
+
+def test_hr_attr():
+ hr = Hr(width=400)
+ file_contents = render_result(hr)
+ print(file_contents)
+ assert file_contents == '
\n'
+
+
+def test_br():
+ br = Br()
+ file_contents = render_result(br)
+ print(file_contents)
+ assert file_contents == "
\n"
+
+def test_content_in_br():
+ with pytest.raises(TypeError):
+ br = Br("some content")
+
+def test_append_content_in_br():
+ with pytest.raises(TypeError):
+ br = Br()
+ br.append("some content")
+
+
+
#####################
# indentation testing
# Uncomment for Step 9 -- adding indentation
From 068cb80d75b2766a403b30e1d68069d62bf3d710 Mon Sep 17 00:00:00 2001
From: Douglas Klos
Date: Sun, 3 Mar 2019 10:16:46 -0800
Subject: [PATCH 037/367] added session8 files
---
students/douglas_klos/.gitignore | 13 +++++
.../session8/examples/index_slicing.py | 50 +++++++++++++++++
.../session8/examples/properties_example.py | 30 ++++++++++
.../session8/examples/quadratic.py | 36 ++++++++++++
.../session8/examples/sort_key.py | 56 +++++++++++++++++++
.../douglas_klos/session8/examples/vector.py | 51 +++++++++++++++++
students/douglas_klos/session8/lab/circle.py | 23 ++++++++
7 files changed, 259 insertions(+)
create mode 100755 students/douglas_klos/session8/examples/index_slicing.py
create mode 100755 students/douglas_klos/session8/examples/properties_example.py
create mode 100755 students/douglas_klos/session8/examples/quadratic.py
create mode 100755 students/douglas_klos/session8/examples/sort_key.py
create mode 100755 students/douglas_klos/session8/examples/vector.py
create mode 100755 students/douglas_klos/session8/lab/circle.py
diff --git a/students/douglas_klos/.gitignore b/students/douglas_klos/.gitignore
index 595c358f..62537ae9 100644
--- a/students/douglas_klos/.gitignore
+++ b/students/douglas_klos/.gitignore
@@ -1,3 +1,16 @@
*.swp
*.back
.vscode
+../.vscode/
+session7/execution_times.txt
+session7/html_render.zip
+session7/test_html_output1.html
+session7/test_html_output2.html
+session7/test_html_output3.html
+session7/test_html_output4.html
+session7/test_html_output5.html
+session7/test_html_output6.html
+session7/test_html_output7.html
+session7/test_html_output8.html
+session7/test_html_output9.html
+
diff --git a/students/douglas_klos/session8/examples/index_slicing.py b/students/douglas_klos/session8/examples/index_slicing.py
new file mode 100755
index 00000000..dedd464c
--- /dev/null
+++ b/students/douglas_klos/session8/examples/index_slicing.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+
+"""
+examples / test code for __getindex__
+
+Doesn't really do anything, but you can see what happens with different indexing.
+"""
+
+import operator
+
+
+class IndexTest:
+
+ def __getitem__(self, index):
+ # print("In getindex, indexes is:", index)
+ if isinstance(index, slice):
+ print("it's a single slice:", index)
+ elif isinstance(index, tuple):
+ print("it's a multi-dimensional slice:", index)
+ else:
+ try:
+ ind = operator.index(index) # this converts arbitrary objects to an int.
+ print("it's an index: ", ind)
+ except TypeError: # not a simple index
+ raise
+ print("It's a simple index")
+
+
+if __name__ == "__main__":
+
+ it = IndexTest()
+
+ print("calling with simple index")
+ it[4]
+
+ print("calling with single slice")
+ it[3:4]
+
+ print("calling with two slices")
+ it[3:4, 7:8]
+
+ print("calling with an invalid index")
+ it["this"]
+
+
+
+
+
+
+
diff --git a/students/douglas_klos/session8/examples/properties_example.py b/students/douglas_klos/session8/examples/properties_example.py
new file mode 100755
index 00000000..f70760e9
--- /dev/null
+++ b/students/douglas_klos/session8/examples/properties_example.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+
+"""
+Example code for properties
+
+NOTE: if your getters and setters are this simple: don't do this!
+
+"""
+
+
+class C:
+ def __init__(self):
+ self._x = None
+ @property
+ def x(self):
+ print("in getter")
+ return self._x
+ @x.setter
+ def x(self, value):
+ print("in setter", value)
+ self._x = value
+ @x.deleter
+ def x(self):
+ del self._x
+
+if __name__ == "__main__":
+ c = C()
+ c.x = 5
+ print(c.x)
+
diff --git a/students/douglas_klos/session8/examples/quadratic.py b/students/douglas_klos/session8/examples/quadratic.py
new file mode 100755
index 00000000..96dc1569
--- /dev/null
+++ b/students/douglas_klos/session8/examples/quadratic.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python3
+
+"""
+A quaratic function evaluator
+
+used to demonstrate callable classes
+"""
+
+class Quadratic:
+ """
+ Class to evaluate quadratic equations
+
+ Each instance wil have a certain set of coefficients
+ """
+
+ def __init__(self, A, B, C):
+ self.A = A
+ self.B = B
+ self.C = C
+
+ def __call__(self, x):
+ return self.A * x**2 + self.B * x + self.C
+
+
+
+def main():
+ q1 = Quadratic(3,4,5)
+ print(q1(1))
+ print(q1(5))
+
+
+
+
+
+if __name__ == '__main__':
+ main()
diff --git a/students/douglas_klos/session8/examples/sort_key.py b/students/douglas_klos/session8/examples/sort_key.py
new file mode 100755
index 00000000..0fe61c89
--- /dev/null
+++ b/students/douglas_klos/session8/examples/sort_key.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python3
+"""
+demonstration of defining a sort_key method for sorting
+"""
+
+import random
+import time
+
+
+class Simple:
+ """
+ simple class to demonstrate a simple sorting key method
+ """
+
+ def __init__(self, val):
+ self.val = val
+
+ def sort_key(self):
+ """
+ sorting key function --used to pass in to sort functions
+ to get faster sorting
+
+ Example::
+
+ sorted(list_of_simple_objects, key=Simple.sort_key)
+
+ """
+ return self.val
+
+ def __lt__(self, other):
+ """
+ less than --required for regular sorting
+ """
+ return self.val < other.val
+
+ def __repr__(self):
+ return "Simple({})".format(self.val)
+
+
+if __name__ == "__main__":
+ N = 10000
+ a_list = [Simple(random.randint(0, 10000)) for i in range(N)]
+ # print("Before sorting:", a_list)
+
+ print("Timing for {} items".format(N))
+ start = time.clock()
+ sorted(a_list)
+ reg_time = time.clock() - start
+ print("regular sort took: {:.4g}s".format(reg_time))
+
+ start = time.clock()
+ sorted(a_list, key=Simple.sort_key)
+ key_time = time.clock() - start
+ print("key sort took: {:.4g}s".format(key_time))
+
+ print("performance improvement factor: {:.4f}".format((reg_time / key_time)))
diff --git a/students/douglas_klos/session8/examples/vector.py b/students/douglas_klos/session8/examples/vector.py
new file mode 100755
index 00000000..adf0061d
--- /dev/null
+++ b/students/douglas_klos/session8/examples/vector.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+"""
+Vector type with +, * redefined as Vector addition and dot product
+"""
+
+
+class Vector(list):
+ def __repr__(self):
+ """
+ String representation, uses list (superclass) representation
+ """
+ return 'Vector({})'.format(super().__repr__())
+
+ def __add__(self, v):
+ """
+ redefine + as element-wise Vector sum
+ """
+ if len(self) != len(v):
+ raise TypeError("Vector can only be added to a sequence of the same length")
+ else:
+ return Vector([x1 + x2 for x1, x2 in zip(self, v)])
+
+ def __mul__(self, v):
+ """
+ redefine * as Vector dot product
+ """
+ if len(self) != len(v):
+ raise TypeError("Vector can only be multiplied with a sequence of the same length")
+ else:
+ return sum([x1 * x2 for x1, x2 in zip(self, v)])
+
+
+if __name__ == '__main__':
+ l1 = [1, 2, 3]
+ l2 = [4, 5, 6]
+ v1 = Vector(l1)
+ v2 = Vector(l2)
+
+ print('l1')
+ print(l1)
+ print('l1 + l2')
+ print(l1 + l2)
+ # print(l1 * l2) # TypeError
+ print('zip(l1, l2)')
+ print(zip(l1, l2))
+ print('v1')
+ print(v1)
+ print('v1 + v2')
+ print(v1 + v2)
+ print('v1 * v2')
+ print(v1 * v2)
diff --git a/students/douglas_klos/session8/lab/circle.py b/students/douglas_klos/session8/lab/circle.py
new file mode 100755
index 00000000..dbea7cb1
--- /dev/null
+++ b/students/douglas_klos/session8/lab/circle.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python3
+
+import math
+
+class Circle():
+ """ Circle class """
+
+ def __init__(self, radius):
+ self.radius = radius
+
+ def __call__(self):
+ return 2 * math.pi * self.radius ** 2
+
+
+def main():
+ c1 = Circle(5)
+ c2 = Circle(10)
+
+ print(c1())
+ print(c2())
+
+if __name__ == '__main__':
+ main()
From 6a97d999dc26fe389bdf97a3b0e962c052d6a08c Mon Sep 17 00:00:00 2001
From: JRockwell70
Date: Sun, 3 Mar 2019 10:17:32 -0800
Subject: [PATCH 038/367] html_render through step 6
---
.../jeff_shabani/session07/html_render.py | 31 +++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 26a511ee..31e50cae 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -73,6 +73,7 @@ def render(self, file_name, open_method='w'):
class SelfClosingTag(Element):
def render(self, file_name, open_method='w'):
+
"""
if conent is entered this tells user that self closing tags
can't have conent and resets the conent to an empty string.
@@ -90,6 +91,26 @@ def render(self, file_name, open_method='w'):
with open(f'{file_name}.html', open_method) as file:
file.write(outtext)
+"""
+Step 6
+"""
+
+class A(Element):
+
+ def __init__(self, link, content):
+ self.link = link
+ self.content = content
+ super(Element).__init__()
+
+ def render(self, file_name, open_method='w'):
+ head = 'a href='
+ tail = 'a'
+ outtext = f'<{head}"{self.link}">{self.content}{tail}>'
+ with open(f'{file_name}.html', open_method) as file:
+ file.write(outtext)
+
+
+
if __name__ == '__main__':
# e = Element("this is some text", 'body')
@@ -110,8 +131,8 @@ def render(self, file_name, open_method='w'):
"""
Step 3
"""
- olt = OneLineTag('PythonClass - oneliner', 'title', style='text-align')
- olt.render('OneLingTagTest')
+ # olt = OneLineTag('PythonClass - oneliner', 'title', style='text-align')
+ # olt.render('OneLingTagTest')
#
# """
# step 4
@@ -127,3 +148,9 @@ def render(self, file_name, open_method='w'):
# sct_test = SelfClosingTag('_', 'html')
# sct_test.render('sct_test')
# print(dir(sct_test))
+
+ """
+ step 6 test for A class
+ """
+ A = A("http://google.com/", "link to google")
+ A.render('google_test')
From 6765ef7f21e1080f3757f4dd02b784a6d860f6e4 Mon Sep 17 00:00:00 2001
From: JRockwell70
Date: Sun, 3 Mar 2019 11:35:15 -0800
Subject: [PATCH 039/367] html_render through step 7
---
.../jeff_shabani/session07/html_render.py | 37 ++++++++++++++++++-
1 file changed, 35 insertions(+), 2 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 31e50cae..d225896b 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -41,10 +41,16 @@ def render(self, file_name, open_method='w'):
class HTML(Element):
+ """
+ html sublcass
+ """
tag = 'html'
class PTag(Element):
+ """
+ p subclass
+ """
tag = 'p'
@@ -109,6 +115,24 @@ def render(self, file_name, open_method='w'):
with open(f'{file_name}.html', open_method) as file:
file.write(outtext)
+"""
+Step 7: Ul class
+"""
+
+class Ul(Element):
+ ul = []
+
+class Li(Element):
+ list_element = ''
+
+class Header(OneLineTag):
+
+ def __init__(self, level, content, tag=None, **attrs):
+ self.level = level
+ self.content = content
+ self.tag = f'h{level}'
+ self.attrs = attrs
+ super(OneLineTag).__init__(list, tag, **attrs)
@@ -131,6 +155,9 @@ def render(self, file_name, open_method='w'):
"""
Step 3
"""
+
+ # p = PTag('p')
+ # p.render('ptag')
# olt = OneLineTag('PythonClass - oneliner', 'title', style='text-align')
# olt.render('OneLingTagTest')
#
@@ -152,5 +179,11 @@ def render(self, file_name, open_method='w'):
"""
step 6 test for A class
"""
- A = A("http://google.com/", "link to google")
- A.render('google_test')
+ # A = A("http://google.com/", "link to google")
+ # A.render('google_test')
+
+ """
+ step 7 tests
+ """
+ h=Header(3, 'Dies ist Kopfebene')
+ h.render('header_test')
From 9eab5d715bdbdb0904bbf9ba198f1b1bf6c9936c Mon Sep 17 00:00:00 2001
From: Douglas Klos
Date: Sun, 3 Mar 2019 11:49:13 -0800
Subject: [PATCH 040/367] circle.py steps 1-5 and tests
---
students/douglas_klos/session8/lab/circle.py | 60 +++++++++++++++----
.../douglas_klos/session8/lab/test_circle.py | 60 +++++++++++++++++++
2 files changed, 109 insertions(+), 11 deletions(-)
create mode 100644 students/douglas_klos/session8/lab/test_circle.py
diff --git a/students/douglas_klos/session8/lab/circle.py b/students/douglas_klos/session8/lab/circle.py
index dbea7cb1..0f6d3bb9 100755
--- a/students/douglas_klos/session8/lab/circle.py
+++ b/students/douglas_klos/session8/lab/circle.py
@@ -2,22 +2,60 @@
import math
+
class Circle():
""" Circle class """
- def __init__(self, radius):
- self.radius = radius
+ def __init__(self, radius=0):
+ self._radius = radius
- def __call__(self):
- return 2 * math.pi * self.radius ** 2
+ def __lt__(self, other):
+ return self._radius < other.radius
+
+ def __le__(self, other):
+ return self._radius <= other.radius
+
+ def __eq__(self, other):
+ return self._radius == other.radius
+
+ def __ge__(self, other):
+ return self._radius >= other.radius
+
+ def __gt__(self, other):
+ return self._radius > other.radius
+ def __ne__(self, other):
+ return self._radius != other.radius
-def main():
- c1 = Circle(5)
- c2 = Circle(10)
+ def __str__(self):
+ return f'Circle with radius: {self.radius}'
- print(c1())
- print(c2())
+ @property
+ def radius(self):
+ return self._radius
+
+ @radius.setter
+ def radius(self, value):
+ self._radius = value
+
+ @radius.deleter
+ def radius(self):
+ del self._radius
+
+ @property
+ def diameter(self):
+ return self._radius * 2
+
+ @diameter.setter
+ def diameter(self, value):
+ self._radius = .5 * value
+
+ @property
+ def area(self):
+ return 2 * math.pi * self.radius ** 2
-if __name__ == '__main__':
- main()
+ @classmethod
+ def from_diameter(cls, diameter):
+ self = cls()
+ self._radius = diameter * .5
+ return self
diff --git a/students/douglas_klos/session8/lab/test_circle.py b/students/douglas_klos/session8/lab/test_circle.py
new file mode 100644
index 00000000..edcb564f
--- /dev/null
+++ b/students/douglas_klos/session8/lab/test_circle.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python3
+
+import math
+import pytest
+from circle import *
+
+
+def test_set_radius_init():
+ """ Tests that you can set the radius of a circle during init """
+
+ circle1 = Circle()
+ assert circle1.radius == 0
+ assert circle1.diameter == 0
+
+ circle2 = Circle(5)
+ assert circle2.radius == 5
+ assert circle2.diameter == 10
+
+
+def test_set_diameter():
+ """ Tests that you can set the diameter of circle and that radius updates """
+
+ circle1 = Circle()
+ circle1.diameter = 10
+
+ assert circle1.radius == 5
+ assert circle1.diameter == 10
+
+
+def test_area():
+
+ circle1 = Circle(10)
+
+ assert circle1.radius == 10
+ assert circle1.diameter == 20
+ assert circle1.area == 2 * math.pi * circle1.radius ** 2
+
+def test_set_area():
+ """ Tests that setting the area fails and returns an AttributeError """
+
+ circle1 = Circle(10)
+
+ with pytest.raises(AttributeError):
+ circle1.area = 100
+
+def test_from_diameter():
+ """ Tests that a circle can be created from a diameter """
+
+ circle1 = Circle.from_diameter(10)
+
+ assert circle1.radius == 5
+ assert circle1.diameter == 10
+ assert circle1.area == 2 * math.pi * circle1.radius ** 2
+
+def test_str():
+ """ Tests that __str__ is working """
+
+ circle1 = Circle(10)
+
+ assert 'Circle with radius: 10' == str(circle1)
From 71f418763dd2ffb34aa4a6957de70f646206088c Mon Sep 17 00:00:00 2001
From: JRockwell70
Date: Sun, 3 Mar 2019 16:10:08 -0800
Subject: [PATCH 041/367] html_render through step 7
---
.../jeff_shabani/session07/html_render.py | 25 ++++++++++++++-----
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index d225896b..7d8fdf4a 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -46,6 +46,15 @@ class HTML(Element):
"""
tag = 'html'
+ def render(self, file_name, open_method = 'w'):
+ head = f'!DOCTYPE {self.tag.ljust(len(self.tag) + 1)}'
+ #super().render(file_name)
+ for k, v in self.attrs.items():
+ head += f'{k.rjust(len(k) + 1)}="{v}"'
+ outtext = f'<{head}>\n{self.content}\n{self.tag}>'
+ with open(f'{file_name}.html', open_method) as file:
+ file.write(outtext)
+
class PTag(Element):
"""
@@ -134,6 +143,8 @@ def __init__(self, level, content, tag=None, **attrs):
self.attrs = attrs
super(OneLineTag).__init__(list, tag, **attrs)
+class Meta(SelfClosingTag):
+ tag = 'meta'
if __name__ == '__main__':
@@ -141,7 +152,7 @@ def __init__(self, level, content, tag=None, **attrs):
# e.append("and this is some more text")
# e.render('test')
- # html sub-class
+ #html sub-class
# html_sub = HTML('HTML subclass 1st line', 'html')
# print(html_sub.tag)
# html_sub.append('HTML subclass 2nd line')
@@ -171,9 +182,8 @@ def __init__(self, level, content, tag=None, **attrs):
"""
step 5 test for self closing tag
"""
- # sct_test = SelfClosingTag('html',style='text-align', id='intro')
- # sct_test = SelfClosingTag('_', 'html')
- # sct_test.render('sct_test')
+ sct_test = SelfClosingTag('_','html')
+ sct_test.render('sct_test')
# print(dir(sct_test))
"""
@@ -185,5 +195,8 @@ def __init__(self, level, content, tag=None, **attrs):
"""
step 7 tests
"""
- h=Header(3, 'Dies ist Kopfebene')
- h.render('header_test')
+ # h=Header(3, 'Dies ist Kopfebene')
+ # h.render('header_test')
+ #
+ # meta_test = Meta('_','meta charset="UTF-8"')
+ # meta_test.render('meta_test')
From f5339987836d8057b5f92f3032be7ec3aa1e4303 Mon Sep 17 00:00:00 2001
From: JRockwell70
Date: Sun, 3 Mar 2019 16:42:41 -0800
Subject: [PATCH 042/367] html_render through step 8
---
.../jeff_shabani/session07/html_render.py | 57 +++++++++++--------
1 file changed, 34 insertions(+), 23 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 7d8fdf4a..e4ba41e4 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -8,6 +8,8 @@
# This is the framework for the base class
class Element(object):
+ indent = " "*2
+
def __init__(self, content=None, tag=None, **attrs):
self.attrs = attrs
if tag:
@@ -26,12 +28,14 @@ def append(self, new_content):
self.content += f'\n{i}\n'
return self.content
- def render(self, file_name, open_method='w'):
+ def render(self, file_name, cur_indent=''):
+ if cur_indent:
+ cur_indent = ' '*cur_indent
head = f'{self.tag.ljust(len(self.tag) + 1)}'
for k, v in self.attrs.items():
head += f'{k.rjust(len(k) + 1)}="{v}"'
- outtext = f'<{head}>\n{self.content}\n{self.tag}>'
- with open(f'{file_name}.html', open_method) as file:
+ outtext = f'<{cur_indent}{head}>\n{self.content}\n{self.tag}>'
+ with open(f'{file_name}.html', 'w') as file:
file.write(outtext)
@@ -46,19 +50,19 @@ class HTML(Element):
"""
tag = 'html'
- def render(self, file_name, open_method = 'w'):
+ def render(self, file_name):
head = f'!DOCTYPE {self.tag.ljust(len(self.tag) + 1)}'
#super().render(file_name)
for k, v in self.attrs.items():
head += f'{k.rjust(len(k) + 1)}="{v}"'
outtext = f'<{head}>\n{self.content}\n{self.tag}>'
- with open(f'{file_name}.html', open_method) as file:
+ with open(f'{file_name}.html', 'w') as file:
file.write(outtext)
class PTag(Element):
"""
- p subclass
+ class for p tag
"""
tag = 'p'
@@ -70,13 +74,13 @@ class PTag(Element):
class OneLineTag(Element):
- def render(self, file_name, open_method='w'):
+ def render(self, file_name):
self.tag = f'{self.tag}>'
head = f'{self.tag.ljust(len(self.tag) + 1)}'
for k, v in self.attrs.items():
head += f'{k.rjust(len(k) + 1)}="{v}"'
outtext = f'<{head}{self.content}{self.tag}>'
- with open(f'{file_name}.html', open_method) as file:
+ with open(f'{file_name}.html', 'w') as file:
file.write(outtext)
@@ -87,7 +91,7 @@ def render(self, file_name, open_method='w'):
class SelfClosingTag(Element):
- def render(self, file_name, open_method='w'):
+ def render(self, file_name):
"""
if conent is entered this tells user that self closing tags
@@ -103,7 +107,7 @@ def render(self, file_name, open_method='w'):
for k, v in self.attrs.items():
head += f'{k.rjust(len(k) + 1)}="{v}"'
outtext = f'<{head}/>'
- with open(f'{file_name}.html', open_method) as file:
+ with open(f'{file_name}.html', 'w') as file:
file.write(outtext)
"""
@@ -117,21 +121,23 @@ def __init__(self, link, content):
self.content = content
super(Element).__init__()
- def render(self, file_name, open_method='w'):
+ def render(self, file_name):
head = 'a href='
tail = 'a'
outtext = f'<{head}"{self.link}">{self.content}{tail}>'
- with open(f'{file_name}.html', open_method) as file:
+ with open(f'{file_name}.html', 'w') as file:
file.write(outtext)
-"""
-Step 7: Ul class
-"""
-
class Ul(Element):
+ """
+ Step 7: Ul class
+ """
ul = []
class Li(Element):
+ """
+ Step 7: Li class
+ """
list_element = ''
class Header(OneLineTag):
@@ -144,13 +150,18 @@ def __init__(self, level, content, tag=None, **attrs):
super(OneLineTag).__init__(list, tag, **attrs)
class Meta(SelfClosingTag):
- tag = 'meta'
+ """
+ add meta tag
+ """
+
+ def __init__(self, content=None, tag = 'meta charset="UTF-8"'):
+ super().__init__(content, tag)
if __name__ == '__main__':
- # e = Element("this is some text", 'body')
- # e.append("and this is some more text")
- # e.render('test')
+ e = Element("this is some text", 'body')
+ e.append("and this is some more text")
+ e.render('test')
#html sub-class
# html_sub = HTML('HTML subclass 1st line', 'html')
@@ -182,8 +193,8 @@ class Meta(SelfClosingTag):
"""
step 5 test for self closing tag
"""
- sct_test = SelfClosingTag('_','html')
- sct_test.render('sct_test')
+ # sct_test = SelfClosingTag('_','html')
+ # sct_test.render('sct_test')
# print(dir(sct_test))
"""
@@ -198,5 +209,5 @@ class Meta(SelfClosingTag):
# h=Header(3, 'Dies ist Kopfebene')
# h.render('header_test')
#
- # meta_test = Meta('_','meta charset="UTF-8"')
+ # meta_test = Meta()
# meta_test.render('meta_test')
From af7780efd482254648fe8a2939ab7f1579095f42 Mon Sep 17 00:00:00 2001
From: admin <23247076+Rockwell70@users.noreply.github.com>
Date: Sun, 3 Mar 2019 17:55:34 -0800
Subject: [PATCH 043/367] html_render update
---
students/jeff_shabani/session07/html_render.py | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index e4ba41e4..c7021b50 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -159,13 +159,12 @@ def __init__(self, content=None, tag = 'meta charset="UTF-8"'):
if __name__ == '__main__':
- e = Element("this is some text", 'body')
- e.append("and this is some more text")
- e.render('test')
+ # e = Element("this is some text", 'body')
+ # e.append("and this is some more text")
+ # e.render('test')
#html sub-class
# html_sub = HTML('HTML subclass 1st line', 'html')
- # print(html_sub.tag)
# html_sub.append('HTML subclass 2nd line')
# html_sub.render('html_subclass')
#
@@ -191,20 +190,20 @@ def __init__(self, content=None, tag = 'meta charset="UTF-8"'):
# attrs_test.render('kwargs_test')
"""
- step 5 test for self closing tag
+ step 5 self closing tag
"""
# sct_test = SelfClosingTag('_','html')
# sct_test.render('sct_test')
# print(dir(sct_test))
"""
- step 6 test for A class
+ step 6 A class
"""
# A = A("http://google.com/", "link to google")
# A.render('google_test')
"""
- step 7 tests
+ step 7
"""
# h=Header(3, 'Dies ist Kopfebene')
# h.render('header_test')
From 14f5ee708fb57567e9df3295316f4efa0813a463 Mon Sep 17 00:00:00 2001
From: woosukjeung <47073569+woosukjeung@users.noreply.github.com>
Date: Sun, 3 Mar 2019 22:48:16 -0800
Subject: [PATCH 044/367] Create Lesson 7
---
students/WooseokJ/Lesson 7 | 1 +
1 file changed, 1 insertion(+)
create mode 100644 students/WooseokJ/Lesson 7
diff --git a/students/WooseokJ/Lesson 7 b/students/WooseokJ/Lesson 7
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/students/WooseokJ/Lesson 7
@@ -0,0 +1 @@
+
From f7d9e354cddf98f615725faaa4dd28472f5888fd Mon Sep 17 00:00:00 2001
From: woosukjeung <47073569+woosukjeung@users.noreply.github.com>
Date: Sun, 3 Mar 2019 22:49:03 -0800
Subject: [PATCH 045/367] Delete Lesson 7
---
students/WooseokJ/Lesson 7 | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 students/WooseokJ/Lesson 7
diff --git a/students/WooseokJ/Lesson 7 b/students/WooseokJ/Lesson 7
deleted file mode 100644
index 8b137891..00000000
--- a/students/WooseokJ/Lesson 7
+++ /dev/null
@@ -1 +0,0 @@
-
From fed674d74563a3e9fabb7f9b77576ab839a41d9d Mon Sep 17 00:00:00 2001
From: woosukjeung <47073569+woosukjeung@users.noreply.github.com>
Date: Sun, 3 Mar 2019 22:51:08 -0800
Subject: [PATCH 046/367] Create test
---
students/WooseokJ/Lesson 7/test | 1 +
1 file changed, 1 insertion(+)
create mode 100644 students/WooseokJ/Lesson 7/test
diff --git a/students/WooseokJ/Lesson 7/test b/students/WooseokJ/Lesson 7/test
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/students/WooseokJ/Lesson 7/test
@@ -0,0 +1 @@
+
From f29713c7a3b140a92f1db0c4ee52b2de07eed15e Mon Sep 17 00:00:00 2001
From: woosukjeung <47073569+woosukjeung@users.noreply.github.com>
Date: Sun, 3 Mar 2019 22:51:50 -0800
Subject: [PATCH 047/367] Add files via upload
---
students/WooseokJ/Lesson 7/html_render.py | 144 +++++++
students/WooseokJ/Lesson 7/run_html_render.py | 226 +++++++++++
.../WooseokJ/Lesson 7/test_html_render.py | 351 ++++++++++++++++++
3 files changed, 721 insertions(+)
create mode 100644 students/WooseokJ/Lesson 7/html_render.py
create mode 100644 students/WooseokJ/Lesson 7/run_html_render.py
create mode 100644 students/WooseokJ/Lesson 7/test_html_render.py
diff --git a/students/WooseokJ/Lesson 7/html_render.py b/students/WooseokJ/Lesson 7/html_render.py
new file mode 100644
index 00000000..db438415
--- /dev/null
+++ b/students/WooseokJ/Lesson 7/html_render.py
@@ -0,0 +1,144 @@
+#!/usr/bin/env python3
+
+"""
+A class-based system for rendering html.
+"""
+
+
+# Base class
+class Element():
+ tag = 'html'
+ indent = ' '
+
+ def __init__(self, content=None, **kwargs):
+ self.attributes = kwargs
+ self.contents = []
+ if content is not None:
+ self.contents = [content]
+
+ def append(self, new_content):
+ self.contents.append(new_content)
+
+ def attrib(self):
+ attribs = "".join([' {}="{}"'.format(key, val)
+ for key, val in self.attributes.items()]
+ )
+ return attribs
+
+ def open_tag(self, cur_ind=""):
+ open_tag = "<{}{}>".format(self.tag, self.attrib())
+ return cur_ind + open_tag
+
+ def render(self, out_file, cur_ind=""):
+ out_file.write(cur_ind)
+ out_file.write(self.make_open_tag())
+ out_file.write("\n")
+ for content in self.contents:
+ try:
+ content.render(out_file, cur_ind + self.indent)
+ except AttributeError:
+ out_file.write(cur_ind + self.indent)
+ out_file.write(str(content) + "\n")
+ out_file.write(cur_ind)
+ out_file.write("{}>\n".format(self.tag))
+
+
+# Process HTML tags
+class OneLineTag(Element):
+ tag = 'onelinetag'
+
+ def append(self, new_content):
+ raise NotImplementedError
+
+ def _open_tag(self):
+ open_tag = ["<{}".format(self.tag)]
+ for key, value in self.attributes.items():
+ open_tag.append(' ' + key + '="' + str(value) + '"')
+ open_tag.append(">")
+ return "".join(open_tag)
+
+ def _close_tag(self):
+ return "{}>".format(self.tag)
+
+ def render(self, out_file, cur_ind=""):
+ out_file.write(cur_ind + self._open_tag())
+ out_file.write(self.contents[0])
+ out_file.write(self._close_tag())
+ out_file.write('\n')
+
+
+# Render tags without content
+class SelfClosingTag(Element):
+ def __init__(self, content=None, **kwargs):
+ if content is not None:
+ raise TypeError("SelfClosingTag can not contain any content")
+ super().__init__(content=content, **kwargs)
+
+ def render(self, outfile, cur_ind=""):
+ tag = cur_ind + self._open_tag()[:-1] + " />\n"
+ outfile.write(tag)
+
+ def append(self, *args):
+ raise TypeError("You can not add content to a SelfClosingTag")
+
+
+class Title(OneLineTag):
+ tag = "title"
+
+
+class Br(SelfClosingTag):
+
+ tag = "br"
+
+
+class Hr(SelfClosingTag):
+
+ tag = "hr"
+
+
+class Html(Element):
+ tag = 'html'
+
+ def render(self, out_file, cur_ind=""):
+ out_file.write(cur_ind + "\n")
+ super().render(out_file, cur_ind)
+
+
+class Body(Element):
+ tag = 'body'
+
+
+class P(Element):
+ tag = 'p'
+
+
+class Head(Element):
+ tag = 'head'
+
+
+class A(OneLineTag):
+ tag = "a"
+
+ def __init__(self, link, content=None, **kwargs):
+ kwargs['href'] = link
+ super().__init__(content, **kwargs)
+
+
+class H(OneLineTag):
+ tag = 'H'
+
+ def __init__(self, level, content=None, **kwargs):
+ self.tag = "h" + str(int(level))
+ super().__init__(content, **kwargs)
+
+
+class Ul(Element):
+ tag = 'Ul'
+
+
+class Li(Element):
+ tag = 'Li'
+
+
+class Meta(SelfClosingTag):
+ tag = "meta"
\ No newline at end of file
diff --git a/students/WooseokJ/Lesson 7/run_html_render.py b/students/WooseokJ/Lesson 7/run_html_render.py
new file mode 100644
index 00000000..b7b8451b
--- /dev/null
+++ b/students/WooseokJ/Lesson 7/run_html_render.py
@@ -0,0 +1,226 @@
+#!/usr/bin/env python3
+
+#a simple script can run and test your html rendering classes.
+#Uncomment the steps as you add to your rendering.
+
+from io import StringIO
+
+# importing the html_rendering code with a short name for easy typing.
+import html_render as hr
+
+
+# writing the file out:
+def render_page(page, filename, indent=None):
+ """
+ render the tree of elements
+ This uses StringIO to render to memory, then dump to console and
+ write to file -- very handy!
+ """
+
+ f = StringIO()
+ if indent is None:
+ page.render(f)
+ else:
+ page.render(f, indent)
+
+ print(f.getvalue())
+ with open(filename, 'w') as outfile:
+ outfile.write(f.getvalue())
+
+
+# Step 1
+#########
+
+page = hr.Element()
+
+page.append("Here is a paragraph of text -- there could be more of them, "
+ "but this is enough to show that we can do some text")
+
+page.append("And here is another piece of text -- you should be able to add any number")
+
+render_page(page, "test_html_output1.html")
+
+# The rest of the steps have been commented out.
+# Uncomment them as you move along with the assignment.
+
+## Step 2
+##########
+
+page = hr.Html()
+
+body = hr.Body()
+
+body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+ "but this is enough to show that we can do some text"))
+
+body.append(hr.P("And here is another piece of text -- you should be able to add any number"))
+
+page.append(body)
+
+render_page(page, "test_html_output2.html")
+
+# # Step 3
+# ##########
+
+page = hr.Html()
+
+head = hr.Head()
+head.append(hr.Title("PythonClass = Revision 1087:"))
+
+page.append(head)
+
+body = hr.Body()
+
+body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+ "but this is enough to show that we can do some text"))
+body.append(hr.P("And here is another piece of text -- you should be able to add any number"))
+
+page.append(body)
+
+render_page(page, "test_html_output3.html")
+
+# # Step 4
+# ##########
+
+page = hr.Html()
+
+head = hr.Head()
+head.append(hr.Title("PythonClass = Revision 1087:"))
+
+page.append(head)
+
+body = hr.Body()
+
+body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+ "but this is enough to show that we can do some text",
+ style="text-align: center; font-style: oblique;"))
+
+page.append(body)
+
+render_page(page, "test_html_output4.html")
+
+# # Step 5
+# #########
+
+page = hr.Html()
+
+head = hr.Head()
+head.append(hr.Title("PythonClass = Revision 1087:"))
+
+page.append(head)
+
+body = hr.Body()
+
+body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+ "but this is enough to show that we can do some text",
+ style="text-align: center; font-style: oblique;"))
+
+body.append(hr.Hr())
+
+page.append(body)
+
+render_page(page, "test_html_output5.html")
+
+# # Step 6
+# #########
+
+page = hr.Html()
+
+head = hr.Head()
+head.append(hr.Title("PythonClass = Revision 1087:"))
+
+page.append(head)
+
+body = hr.Body()
+
+body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+ "but this is enough to show that we can do some text",
+ style="text-align: center; font-style: oblique;"))
+
+body.append(hr.Hr())
+
+body.append("And this is a ")
+body.append( hr.A("http://google.com/", "link") )
+body.append("to google")
+
+page.append(body)
+
+render_page(page, "test_html_output6.html")
+
+# # Step 7
+# #########
+
+page = hr.Html()
+
+head = hr.Head()
+head.append(hr.Title("PythonClass = Revision 1087:"))
+
+page.append(head)
+
+body = hr.Body()
+
+body.append( hr.H(2, "PythonClass - Class 6 example") )
+
+body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+ "but this is enough to show that we can do some text",
+ style="text-align: center; font-style: oblique;"))
+
+body.append(hr.Hr())
+
+list = hr.Ul(id="TheList", style="line-height:200%")
+
+list.append( hr.Li("The first item in a list") )
+list.append( hr.Li("This is the second item", style="color: red") )
+
+item = hr.Li()
+item.append("And this is a ")
+item.append( hr.A("http://google.com/", "link") )
+item.append("to google")
+
+list.append(item)
+
+body.append(list)
+
+page.append(body)
+
+render_page(page, "test_html_output7.html")
+
+# # Step 8 and 9
+# ##############
+
+page = hr.Html()
+
+
+head = hr.Head()
+head.append( hr.Meta(charset="UTF-8") )
+head.append(hr.Title("PythonClass = Revision 1087:"))
+
+page.append(head)
+
+body = hr.Body()
+
+body.append( hr.H(2, "PythonClass - Example") )
+
+body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+ "but this is enough to show that we can do some text",
+ style="text-align: center; font-style: oblique;"))
+
+body.append(hr.Hr())
+
+list = hr.Ul(id="TheList", style="line-height:200%")
+
+list.append( hr.Li("The first item in a list") )
+list.append( hr.Li("This is the second item", style="color: red") )
+
+item = hr.Li()
+item.append("And this is a ")
+item.append( hr.A("http://google.com/", "link") )
+item.append("to google")
+
+list.append(item)
+
+body.append(list)
+
+page.append(body)
+
+render_page(page, "test_html_output8.html")
diff --git a/students/WooseokJ/Lesson 7/test_html_render.py b/students/WooseokJ/Lesson 7/test_html_render.py
new file mode 100644
index 00000000..f1ab51da
--- /dev/null
+++ b/students/WooseokJ/Lesson 7/test_html_render.py
@@ -0,0 +1,351 @@
+'''
+test code for html_render.py
+This is just a start -- you will need more tests!
+'''
+
+import io
+import pytest
+
+# import * is often bad form, but makes it easier to test everything in a module.
+from html_render import *
+
+
+# utility function for testing render methods
+# needs to be used in multiple tests, so we write it once here.
+def render_result(element, ind=''):
+ '''
+ calls the element's render method, and returns what got rendered as a
+ string
+ '''
+ # the StringIO object is a 'file-like' object -- something that
+ # provides the methods of a file, but keeps everything in memory
+ # so it can be used to test code that writes to a file, without
+ # having to actually write to disk.
+ outfile = io.StringIO()
+ # this so the tests will work before we tackle indentation
+ if ind:
+ element.render(outfile, ind)
+ else:
+ element.render(outfile)
+ return outfile.getvalue()
+
+########
+# Step 1
+########
+
+
+def test_init():
+ '''
+ This only tests that it can be initialized with and without
+ some content -- but it's a start
+ '''
+ e = Element()
+
+ e = Element('this is some text')
+
+
+def test_append():
+ '''
+ This tests that you can append text
+ It doesn't test if it works --
+ that will be covered by the render test later
+ '''
+ e = Element('this is some text')
+ e.append('some more text')
+
+
+def test_render_element():
+ e = Element('this is some text')
+ e.append('and this is some more text')
+
+ # This uses the render_results utility above
+ file_contents = render_result(e).strip()
+
+ # making sure the content got in there.
+ assert'this is some text' in file_contents
+ assert'and this is some more text' in file_contents
+
+ # make sure it's in the right order
+ assert file_contents.index('this is') < file_contents.index('and this')
+
+ # making sure the opening and closing tags are right.
+ assert file_contents.startswith('')
+ assert file_contents.endswith('')
+ assert file_contents.count('') == 1
+ assert file_contents.count('') == 1
+
+# Uncomment this one after you get the one above to pass
+# Does it pass right away?
+def test_render_element2():
+ '''
+ Tests whether the Element can render two pieces of text
+ So it is also testing that the append method works correctly.
+ It is not testing whether indentation or line feeds are correct.
+ '''
+ e = Element()
+ e.append('this is some text')
+ e.append('and this is some more text')
+
+ # This uses the render_results utility above
+ file_contents = render_result(e).strip()
+
+ # making sure the content got in there.
+ assert'this is some text' in file_contents
+ assert'and this is some more text' in file_contents
+
+ # make sure it's in the right order
+ assert file_contents.index('this is') < file_contents.index('and this')
+
+ # making sure the opening and closing tags are right.
+ assert file_contents.startswith('')
+ assert file_contents.endswith('')
+
+
+# ########
+# # Step 2
+# ########
+
+# tests for the new tags
+def test_html():
+ e = Html('this is some text')
+ e.append('and this is some more text')
+
+ file_contents = render_result(e).strip()
+
+ assert'this is some text' in file_contents
+ assert'and this is some more text' in file_contents
+ print(file_contents)
+ assert file_contents.endswith('')
+
+
+def test_body():
+ e = Body('this is some text')
+ e.append('and this is some more text')
+
+ file_contents = render_result(e).strip()
+
+ assert'this is some text' in file_contents
+ assert'and this is some more text' in file_contents
+
+ assert file_contents.startswith('')
+ assert file_contents.endswith('')
+
+
+def test_p():
+ e = P('this is some text')
+ e.append('and this is some more text')
+
+ file_contents = render_result(e).strip()
+
+ assert'this is some text' in file_contents
+ assert'and this is some more text' in file_contents
+
+ assert file_contents.startswith('')
+ assert file_contents.endswith('
')
+
+
+def test_sub_element():
+ '''
+ tests that you can add another element and still render properly
+ '''
+ page = Html()
+ page.append('some plain text.')
+ page.append(P('A simple paragraph of text'))
+ page.append('Some more plain text.')
+
+ file_contents = render_result(page)
+ print(file_contents) # so we can see it if the test fails
+
+ # note: The previous tests should make sure that the tags are getting
+ # properly rendered, so we don't need to test that here.
+ assert 'some plain text' in file_contents
+ assert 'A simple paragraph of text' in file_contents
+ assert 'Some more plain text.' in file_contents
+ assert 'some plain text' in file_contents
+ # but make sure the embedded element's tags get rendered!
+ assert '' in file_contents
+ assert '
' in file_contents
+
+
+########
+# Step 3
+########
+
+def test_head():
+ e = Head('this is some text')
+ e.append('and this is some more text')
+
+ file_contents = render_result(e).strip()
+
+ assert'this is some text' in file_contents
+ assert'and this is some more text' in file_contents
+
+ assert file_contents.startswith('')
+ assert file_contents.endswith('')
+
+
+def test_title():
+ e = Title('This is a Title')
+
+ file_contents = render_result(e).strip()
+
+ assert'This is a Title' in file_contents
+ print(file_contents)
+ assert file_contents.startswith('')
+ assert file_contents.endswith('')
+ assert '\n' not in file_contents
+
+
+def test_one_line_tag_append():
+ """
+ You should not be able to append content to a OneLineTag
+ """
+ e = OneLineTag("the initial content")
+ with pytest.raises(NotImplementedError):
+ e.append("some more content")
+
+
+def test_attributes():
+ '''
+ Testing attribute passing
+ '''
+ e = P('A paragraph of text', style='text-align: center', id='intro')
+
+ file_contents = render_result(e).strip()
+ print(file_contents) # so we can see it if the test fails
+
+ # note: The previous tests should make sure that the tags are getting
+ # properly rendered, so we don't need to test that here.
+ # so using only a 'P' tag is fine
+ assert 'A paragraph of text' in file_contents
+ # but make sure the embedded element's tags get rendered!
+ # first test the end tag is there -- same as always:
+ assert file_contents.endswith('')
+
+ # but now the opening tag is far more complex
+ # but it starts the same:
+ assert file_contents.startswith('") > file_contents.index('id="intro"')
+ assert file_contents[:file_contents.index(">")].count(" ") == 3
+ assert file_contents.startswith("
\n'
+
+
+def test_hr_attr():
+ """a horizontal rule with an attribute"""
+ hr = Hr(width=400)
+ file_contents = render_result(hr)
+ print(file_contents)
+ assert file_contents == '
\n'
+
+
+def test_br():
+ br = Br()
+ file_contents = render_result(br)
+ print(file_contents)
+ assert file_contents == "
\n"
+
+
+def test_content_in_br():
+ with pytest.raises(TypeError):
+ br = Br("some content")
+
+
+def test_append_content_in_br():
+ with pytest.raises(TypeError):
+ br = Br()
+ br.append("some content")
+
+def test_anchor():
+ a = A("http://google.com/", "link to google")
+ file_contents = render_result(a)
+ print(file_contents)
+ assert file_contents.startswith(' tag
+ assert lines[i + 1].startswith(i * Element.indent + '<')
+
+ assert lines[4].startswith(3 * Element.indent + 'some')
+
+
+def test_element_indent1():
+ '''
+ Tests whether the Element indents at least simple content
+ we are expecting to to look like this:
+
+ this is some text
+ <\html>
+ More complex indentation should be tested later.
+ '''
+ e = Element('this is some text')
+
+ # This uses the render_results utility above
+ file_contents = render_result(e).strip()
+
+ # making sure the content got in there.
+ assert'this is some text' in file_contents
+
+ # break into lines to check indentation
+ lines = file_contents.split('\n')
+ # making sure the opening and closing tags are right.
+ assert lines[0] == ''
+ # this line should be indented by the amount specified
+ # by the class attribute: 'indent'
+ assert lines[1].startswith(Element.indent + 'thi')
+ assert lines[2] == ''
+ assert file_contents.endswith('')
\ No newline at end of file
From 2edbcd7ab5d7959d455495cbd490daf505cb2af4 Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Mon, 4 Mar 2019 08:40:05 -0800
Subject: [PATCH 048/367] Session07 files
---
students/jeff_shabani/session07/html_render.py | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index c7021b50..106637ba 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -8,7 +8,8 @@
# This is the framework for the base class
class Element(object):
- indent = " "*2
+ indent = ''
+ tag = 'html'
def __init__(self, content=None, tag=None, **attrs):
self.attrs = attrs
@@ -17,16 +18,12 @@ def __init__(self, content=None, tag=None, **attrs):
else:
self.tag = ''
if content:
- self.content = content
+ self.content = [content]
else:
- self.content = ''
+ self.content = []
def append(self, new_content):
- result = list()
- result.append(new_content)
- for i in result:
- self.content += f'\n{i}\n'
- return self.content
+ self.content.append(new_content)
def render(self, file_name, cur_indent=''):
if cur_indent:
From 6a4866e4c5bb396c284baf1cfe700ef4aa46d813 Mon Sep 17 00:00:00 2001
From: Douglas Klos
Date: Mon, 4 Mar 2019 10:28:40 -0800
Subject: [PATCH 049/367] circle.py through step8, reflected numerics
---
students/douglas_klos/session8/lab/circle.py | 33 ++++-
.../douglas_klos/session8/lab/run_circle.py | 59 ++++++++
.../douglas_klos/session8/lab/test_circle.py | 131 ++++++++++++++++--
3 files changed, 213 insertions(+), 10 deletions(-)
create mode 100755 students/douglas_klos/session8/lab/run_circle.py
mode change 100644 => 100755 students/douglas_klos/session8/lab/test_circle.py
diff --git a/students/douglas_klos/session8/lab/circle.py b/students/douglas_klos/session8/lab/circle.py
index 0f6d3bb9..d7362180 100755
--- a/students/douglas_klos/session8/lab/circle.py
+++ b/students/douglas_klos/session8/lab/circle.py
@@ -30,6 +30,33 @@ def __ne__(self, other):
def __str__(self):
return f'Circle with radius: {self.radius}'
+ def __repr__(self):
+ return f'Circle({self.radius})'
+
+ def __add__(self, other):
+ if hasattr(other, '_radius'):
+ return self.__class__(self._radius + other.radius)
+ return self.__class__(self.radius + other)
+
+ def __radd__(self, other):
+ return self.__class__(other + self.radius)
+
+ def __sub__(self, other):
+ if hasattr(other, '_radius'):
+ return self.__class__(self._radius - other.radius)
+ return self.__class__(self.radius - other)
+
+ def __rsub__(self, other):
+ return self.__class__(other - self._radius)
+
+ def __mul__(self, other):
+ if hasattr(other, '_radius'):
+ return self.__class__(self._radius * other.radius)
+ return self.__class__(self.radius * other)
+
+ def __rmul__(self, other):
+ return self.__class__(other * self._radius)
+
@property
def radius(self):
return self._radius
@@ -44,7 +71,7 @@ def radius(self):
@property
def diameter(self):
- return self._radius * 2
+ return self._radius * 2
@diameter.setter
def diameter(self, value):
@@ -52,10 +79,12 @@ def diameter(self, value):
@property
def area(self):
+ """ Returns the area """
return 2 * math.pi * self.radius ** 2
@classmethod
def from_diameter(cls, diameter):
+ """ Initializes class from diameter instead of radius """
self = cls()
- self._radius = diameter * .5
+ self.radius = diameter * .5
return self
diff --git a/students/douglas_klos/session8/lab/run_circle.py b/students/douglas_klos/session8/lab/run_circle.py
new file mode 100755
index 00000000..e70eeb32
--- /dev/null
+++ b/students/douglas_klos/session8/lab/run_circle.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python3
+
+from circle import *
+
+
+def main():
+ c1 = Circle(5)
+ c2 = Circle(10)
+ c3 = c1 * c2
+
+ print("---------------str--------------------")
+
+ print(c1)
+ print(c2)
+
+ print(str(c1))
+ print(str(c2))
+
+ print("---------------repr-------------------")
+
+ print(repr(c1))
+ print(repr(c2))
+
+ print("---------------sort-------------------")
+
+ c_list = [c2, c3, c1]
+ circle_list = [Circle(5), Circle(10), Circle(2)]
+
+ print(c_list)
+ c_list.sort()
+ print(c_list)
+
+ print(circle_list)
+ circle_list.sort()
+ print(circle_list)
+
+ print("---------------add--------------------")
+
+ print(3 + c1)
+ print(c1 + 3)
+ print(c1 + c2)
+
+ print("---------------sub--------------------")
+
+ print(c1 - 2)
+ print(10 - c1)
+ print(c2 - c1)
+
+ print("---------------mul--------------------")
+
+ print(5 * c1)
+ print(c1 * c2)
+ print(c1 * 5.0)
+ print(10.2 * c1)
+
+
+if __name__ == '__main__':
+ main()
+
\ No newline at end of file
diff --git a/students/douglas_klos/session8/lab/test_circle.py b/students/douglas_klos/session8/lab/test_circle.py
old mode 100644
new mode 100755
index edcb564f..cfce851e
--- a/students/douglas_klos/session8/lab/test_circle.py
+++ b/students/douglas_klos/session8/lab/test_circle.py
@@ -7,19 +7,17 @@
def test_set_radius_init():
""" Tests that you can set the radius of a circle during init """
-
circle1 = Circle()
+ circle2 = Circle(5)
+
assert circle1.radius == 0
assert circle1.diameter == 0
-
- circle2 = Circle(5)
assert circle2.radius == 5
assert circle2.diameter == 10
def test_set_diameter():
""" Tests that you can set the diameter of circle and that radius updates """
-
circle1 = Circle()
circle1.diameter = 10
@@ -28,33 +26,150 @@ def test_set_diameter():
def test_area():
-
+ """ Tests that the area of a circle is computed properly """
circle1 = Circle(10)
assert circle1.radius == 10
assert circle1.diameter == 20
assert circle1.area == 2 * math.pi * circle1.radius ** 2
+
def test_set_area():
""" Tests that setting the area fails and returns an AttributeError """
-
circle1 = Circle(10)
with pytest.raises(AttributeError):
circle1.area = 100
+
def test_from_diameter():
""" Tests that a circle can be created from a diameter """
-
circle1 = Circle.from_diameter(10)
assert circle1.radius == 5
assert circle1.diameter == 10
assert circle1.area == 2 * math.pi * circle1.radius ** 2
+
def test_str():
""" Tests that __str__ is working """
-
circle1 = Circle(10)
assert 'Circle with radius: 10' == str(circle1)
+
+
+def test_repr():
+ """ Tests that __repr__ is working """
+ circle1 = Circle(10)
+
+ assert 'Circle(10)' == repr(circle1)
+
+
+def test_addition():
+ """ Tests that __add___ is working """
+ circle1 = Circle(10)
+ circle2 = Circle(20)
+ circle3 = circle1 + circle2
+
+ assert circle3.radius == 30
+ assert circle1 + 5 == Circle(15)
+
+
+def test_radd():
+ """ Tests that reflected addition works """
+ circle1 = Circle(2)
+ circle2 = Circle(4)
+
+ assert circle1 + 2 == 2 + circle1
+ assert 2 + circle1 == circle2
+ assert 5 + circle1 == Circle(7)
+
+
+def test_subtraction():
+ """ Tests that __sub___ is working """
+ circle1 = Circle(10)
+ circle2 = Circle(6)
+ circle3 = circle1 - circle2
+
+ assert circle3.radius == 4
+ assert circle1 - 5 == Circle(5)
+ assert circle2 - 2 == Circle(4)
+
+
+def test_rsub():
+ circle1 = Circle(10)
+ circle2 = Circle(6)
+
+ assert 10 - circle1 == circle1 - 10
+ assert 10 - circle2 == Circle(4)
+ assert 10.0 - circle2 == Circle(4)
+
+
+def test_multiplication():
+ """ Tests that __mul__ is working """
+ circle1 = Circle(2)
+ circle2 = Circle(4)
+ circle3 = circle1 * circle2
+
+ assert circle3.radius == 8
+ assert circle1 * 2 == Circle(4)
+ assert circle2 * 2 == Circle(8)
+
+
+def test_rmul():
+ circle1 = Circle(2)
+ circle2 = Circle(4)
+
+ assert 2 * circle1 == circle1 * 2
+ assert 2 * circle1 == Circle(4)
+ assert 2 * circle2 == Circle(8)
+
+
+def test_comparisons1():
+ """ Tests comparison operations when circle1 is less than circle 2 """
+ circle1 = Circle(2)
+ circle2 = Circle(4)
+
+ assert not circle1 > circle2
+ assert not circle1 >= circle2
+ assert circle1 < circle2
+ assert circle1 <= circle2
+ assert not circle1 == circle2
+ assert circle1 != circle2
+
+
+def test_comparisons2():
+ """ Tests comparison operations when circle1 is greater than circle 2 """
+ circle1 = Circle(4)
+ circle2 = Circle(2)
+
+ assert circle1 > circle2
+ assert circle1 >= circle2
+ assert not circle1 < circle2
+ assert not circle1 <= circle2
+ assert not circle1 == circle2
+ assert circle1 != circle2
+
+
+def test_comparisons3():
+ """ Tests comparison operations when circle1 is equal to circle 2 """
+ circle1 = Circle(2)
+ circle2 = Circle(2)
+
+ assert not circle1 > circle2
+ assert circle1 >= circle2
+ assert not circle1 < circle2
+ assert circle1 <= circle2
+ assert circle1 == circle2
+ assert not circle1 != circle2
+
+
+def test_sort():
+ """ Tests that .sort() functions properly """
+ circle1 = Circle(10)
+ circle2 = Circle(5)
+ circle3 = Circle(2)
+ circle_list = [circle1, circle2, circle3]
+ circle_list.sort()
+
+ assert circle_list == [circle3, circle2, circle1]
From c020c0ddab1f0e72af8f91164edc31f6dfd6022f Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Mon, 4 Mar 2019 10:55:54 -0800
Subject: [PATCH 050/367] Session07 files
---
.../jeff_shabani/session07/html_render.py | 40 ++++++++++---------
1 file changed, 21 insertions(+), 19 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 106637ba..89479027 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -8,32 +8,34 @@
# This is the framework for the base class
class Element(object):
- indent = ''
+ indent = ' '*2
tag = 'html'
- def __init__(self, content=None, tag=None, **attrs):
+ def __init__(self, content=None, **attrs):
self.attrs = attrs
- if tag:
- self.tag = tag
- else:
- self.tag = ''
if content:
self.content = [content]
else:
self.content = []
+ def front_tag(self):
+ """Creates the front tag"""
+ return f'<{self.tag}>'
+
+ def end_tag(self):
+ """Creates the ending tag"""
+ return f'{self.tag}>'
+
+
def append(self, new_content):
self.content.append(new_content)
def render(self, file_name, cur_indent=''):
- if cur_indent:
- cur_indent = ' '*cur_indent
- head = f'{self.tag.ljust(len(self.tag) + 1)}'
- for k, v in self.attrs.items():
- head += f'{k.rjust(len(k) + 1)}="{v}"'
- outtext = f'<{cur_indent}{head}>\n{self.content}\n{self.tag}>'
- with open(f'{file_name}.html', 'w') as file:
- file.write(outtext)
+ file_name.write(f'{self.front_tag()}\n')
+ for content_line in self.content:
+ file_name.write(f'{content_line}\n')
+ file_name.write(f'{self.end_tag()}\n')
+
"""
@@ -41,7 +43,7 @@ def render(self, file_name, cur_indent=''):
"""
-class HTML(Element):
+class Html(Element):
"""
html sublcass
"""
@@ -156,12 +158,12 @@ def __init__(self, content=None, tag = 'meta charset="UTF-8"'):
if __name__ == '__main__':
- # e = Element("this is some text", 'body')
- # e.append("and this is some more text")
- # e.render('test')
+ e = Element("this is some text")
+ e.append("and this is some more text")
+ e.render(e,'test')
#html sub-class
- # html_sub = HTML('HTML subclass 1st line', 'html')
+ # html_sub = Html('HTML subclass 1st line')
# html_sub.append('HTML subclass 2nd line')
# html_sub.render('html_subclass')
#
From d0f7594ad5e2bbd4a4d2349fe8d5c4a8a64deb70 Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Mon, 4 Mar 2019 13:20:51 -0800
Subject: [PATCH 051/367] html_render update
---
.../jeff_shabani/session07/html_render.py | 240 +++++++-----------
1 file changed, 90 insertions(+), 150 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 89479027..8135ef7e 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -7,8 +7,7 @@
# This is the framework for the base class
class Element(object):
-
- indent = ' '*2
+ indent = ' ' * 2
tag = 'html'
def __init__(self, content=None, **attrs):
@@ -18,29 +17,24 @@ def __init__(self, content=None, **attrs):
else:
self.content = []
- def front_tag(self):
- """Creates the front tag"""
+ def _front_tag(self):
+ """Creates the front/opening tag"""
return f'<{self.tag}>'
- def end_tag(self):
+ def _end_tag(self):
"""Creates the ending tag"""
return f'{self.tag}>'
-
def append(self, new_content):
self.content.append(new_content)
def render(self, file_name, cur_indent=''):
- file_name.write(f'{self.front_tag()}\n')
+ # Writes the opening tag
+ file_name.write(f'{self._front_tag()}\n')
for content_line in self.content:
file_name.write(f'{content_line}\n')
- file_name.write(f'{self.end_tag()}\n')
-
-
-
-"""
-Step 2 part B
-"""
+ # Writes the ending tag
+ file_name.write(f'{self._end_tag()}\n')
class Html(Element):
@@ -50,162 +44,108 @@ class Html(Element):
tag = 'html'
def render(self, file_name):
- head = f'!DOCTYPE {self.tag.ljust(len(self.tag) + 1)}'
- #super().render(file_name)
- for k, v in self.attrs.items():
- head += f'{k.rjust(len(k) + 1)}="{v}"'
- outtext = f'<{head}>\n{self.content}\n{self.tag}>'
- with open(f'{file_name}.html', 'w') as file:
- file.write(outtext)
+ file_name.write(f'\n')
+ super().render(file_name)
-class PTag(Element):
+class P(Element):
"""
class for p tag
"""
tag = 'p'
+class Body(Element):
+ """
+ class for p tag
+ """
+ tag = 'body'
+
+
"""
Step 3: print on one line
"""
-
-class OneLineTag(Element):
-
- def render(self, file_name):
- self.tag = f'{self.tag}>'
- head = f'{self.tag.ljust(len(self.tag) + 1)}'
- for k, v in self.attrs.items():
- head += f'{k.rjust(len(k) + 1)}="{v}"'
- outtext = f'<{head}{self.content}{self.tag}>'
- with open(f'{file_name}.html', 'w') as file:
- file.write(outtext)
+# class OneLineTag(Element):
+#
+# def render(self, file_name):
+# self.tag = f'{self.tag}>'
+# head = f'{self.tag.ljust(len(self.tag) + 1)}'
+# for k, v in self.kwargs.items():
+# head += f'{k.rjust(len(k) + 1)}="{v}"'
+# outtext = f'<{head}{self.content}{self.tag}>'
+# with open(f'{file_name}.html', 'w') as file:
+# file.write(outtext)
"""
Step 5: Self closing tag
"""
-
-class SelfClosingTag(Element):
-
- def render(self, file_name):
-
- """
- if conent is entered this tells user that self closing tags
- can't have conent and resets the conent to an empty string.
- """
-
- if self.content:
- print('Self closing tags cannot have content')
- else:
- self.content = ''
-
- head = f'{self.tag.ljust(len(self.tag) + 1)}'
- for k, v in self.attrs.items():
- head += f'{k.rjust(len(k) + 1)}="{v}"'
- outtext = f'<{head}/>'
- with open(f'{file_name}.html', 'w') as file:
- file.write(outtext)
+# class SelfClosingTag(Element):
+#
+# def render(self, file_name):
+#
+# """
+# if conent is entered this tells user that self closing tags
+# can't have conent and resets the conent to an empty string.
+# """
+#
+# if self.content:
+# print('Self closing tags cannot have content')
+# else:
+# self.content = ''
+#
+# head = f'{self.tag.ljust(len(self.tag) + 1)}'
+# for k, v in self.kwargs.items():
+# head += f'{k.rjust(len(k) + 1)}="{v}"'
+# outtext = f'<{head}/>'
+# with open(f'{file_name}.html', 'w') as file:
+# file.write(outtext)
"""
Step 6
"""
-class A(Element):
-
- def __init__(self, link, content):
- self.link = link
- self.content = content
- super(Element).__init__()
-
- def render(self, file_name):
- head = 'a href='
- tail = 'a'
- outtext = f'<{head}"{self.link}">{self.content}{tail}>'
- with open(f'{file_name}.html', 'w') as file:
- file.write(outtext)
-
-class Ul(Element):
- """
- Step 7: Ul class
- """
- ul = []
-
-class Li(Element):
- """
- Step 7: Li class
- """
- list_element = ''
-
-class Header(OneLineTag):
-
- def __init__(self, level, content, tag=None, **attrs):
- self.level = level
- self.content = content
- self.tag = f'h{level}'
- self.attrs = attrs
- super(OneLineTag).__init__(list, tag, **attrs)
-
-class Meta(SelfClosingTag):
- """
- add meta tag
- """
-
- def __init__(self, content=None, tag = 'meta charset="UTF-8"'):
- super().__init__(content, tag)
-
-
-if __name__ == '__main__':
- e = Element("this is some text")
- e.append("and this is some more text")
- e.render(e,'test')
-
- #html sub-class
- # html_sub = Html('HTML subclass 1st line')
- # html_sub.append('HTML subclass 2nd line')
- # html_sub.render('html_subclass')
- #
- # #p subclass
- # p_sub = PTag('p subclass 1st line', 'p')
- # p_sub.append('p subclass 2nd line')
- # p_sub.render('p_subclass')
- #
- """
- Step 3
- """
-
- # p = PTag('p')
- # p.render('ptag')
- # olt = OneLineTag('PythonClass - oneliner', 'title', style='text-align')
- # olt.render('OneLingTagTest')
- #
- # """
- # step 4
- # """
- # attrs_test = Element('kwargs test', 'html',style='text-align', id='intro')
- # attrs_test.append('kwargstest line 2')
- # attrs_test.render('kwargs_test')
-
- """
- step 5 self closing tag
- """
- # sct_test = SelfClosingTag('_','html')
- # sct_test.render('sct_test')
- # print(dir(sct_test))
-
- """
- step 6 A class
- """
- # A = A("http://google.com/", "link to google")
- # A.render('google_test')
-
- """
- step 7
- """
- # h=Header(3, 'Dies ist Kopfebene')
- # h.render('header_test')
- #
- # meta_test = Meta()
- # meta_test.render('meta_test')
+# class A(Element):
+#
+# def __init__(self, link, content):
+# self.link = link
+# self.content = content
+# super(Element).__init__()
+#
+# def render(self, file_name):
+# head = 'a href='
+# tail = 'a'
+# outtext = f'<{head}"{self.link}">{self.content}{tail}>'
+# with open(f'{file_name}.html', 'w') as file:
+# file.write(outtext)
+#
+# class Ul(Element):
+# """
+# Step 7: Ul class
+# """
+# ul = []
+#
+# class Li(Element):
+# """
+# Step 7: Li class
+# """
+# list_element = ''
+#
+# class Head(OneLineTag):
+#
+# def __init__(self, level, content, tag=None, **kwargs):
+# self.level = level
+# self.content = content
+# self.tag = f'h{level}'
+# self.kwargs = kwargs
+# super(OneLineTag).__init__(list, tag, **kwargs)
+#
+# class Meta(SelfClosingTag):
+# """
+# add meta tag
+# """
+#
+# def __init__(self, content=None, tag = 'meta charset="UTF-8"'):
+# super().__init__(content, tag)
From 2e7dbf1ca6a9c696d34993780d5a300fab3dbc5c Mon Sep 17 00:00:00 2001
From: UncleanlyCleric
Date: Mon, 4 Mar 2019 17:11:23 -0800
Subject: [PATCH 052/367] Initial commit
---
students/jesse_miller/session08/circle.py | 12 ++++++++++++
1 file changed, 12 insertions(+)
create mode 100644 students/jesse_miller/session08/circle.py
diff --git a/students/jesse_miller/session08/circle.py b/students/jesse_miller/session08/circle.py
new file mode 100644
index 00000000..2b0716b8
--- /dev/null
+++ b/students/jesse_miller/session08/circle.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python3
+'''
+Class based circle calculation exercise
+'''
+
+'''
+Setting this space for the modules I'm certainly importing
+'''
+
+class Circle:
+ def __init__(self, radius):
+ self.radius = radius
From 2c3e33f36ac297e9b7965b53f46fbb86b960091b Mon Sep 17 00:00:00 2001
From: Douglas Klos
Date: Mon, 4 Mar 2019 18:36:23 -0800
Subject: [PATCH 053/367] Session8 done with requirements + optionals
---
students/douglas_klos/session8/lab/circle.py | 83 +++++-
.../douglas_klos/session8/lab/run_circle.py | 3 +
.../douglas_klos/session8/lab/test_circle.py | 239 +++++++++++++++++-
3 files changed, 312 insertions(+), 13 deletions(-)
diff --git a/students/douglas_klos/session8/lab/circle.py b/students/douglas_klos/session8/lab/circle.py
index d7362180..5ed9e966 100755
--- a/students/douglas_klos/session8/lab/circle.py
+++ b/students/douglas_klos/session8/lab/circle.py
@@ -1,10 +1,26 @@
#!/usr/bin/env python3
+#pylint: disable=E1101
+
+""" Circle class """
+
+# Douglas Klos
+# March 4th, 2019
+# Python 210, Session 8
+# circle.py
+
import math
class Circle():
- """ Circle class """
+ """
+ Circle class
+
+ Properties:
+ radius The radius of the circle
+ diameter Returns the diameter calculated from radius
+ area Returns the area calculated from radius
+ """
def __init__(self, radius=0):
self._radius = radius
@@ -41,6 +57,11 @@ def __add__(self, other):
def __radd__(self, other):
return self.__class__(other + self.radius)
+ def __iadd__(self, other):
+ if hasattr(other, '_radius'):
+ return self.__class__(self._radius + other.radius)
+ return self.__class__(self.radius + other)
+
def __sub__(self, other):
if hasattr(other, '_radius'):
return self.__class__(self._radius - other.radius)
@@ -49,6 +70,11 @@ def __sub__(self, other):
def __rsub__(self, other):
return self.__class__(other - self._radius)
+ def __isub__(self, other):
+ if hasattr(other, '_radius'):
+ return self.__class__(self._radius - other.radius)
+ return self.__class__(self.radius - other)
+
def __mul__(self, other):
if hasattr(other, '_radius'):
return self.__class__(self._radius * other.radius)
@@ -57,8 +83,40 @@ def __mul__(self, other):
def __rmul__(self, other):
return self.__class__(other * self._radius)
+ def __imul__(self, other):
+ if hasattr(other, '_radius'):
+ return self.__class__(self._radius * other.radius)
+ return self.__class__(self.radius * other)
+
+ def __truediv__(self, other):
+ if hasattr(other, '_radius'):
+ return self.__class__(self._radius / other.radius)
+ return self.__class__(self.radius / other)
+
+ def __rtruediv__(self, other):
+ return self.__class__(other / self._radius)
+
+ def __itruediv__(self, other):
+ if hasattr(other, '_radius'):
+ return self.__class__(self._radius / other.radius)
+ return self.__class__(self.radius / other)
+
+ def __floordiv__(self, other):
+ if hasattr(other, '_radius'):
+ return self.__class__(self._radius // other.radius)
+ return self.__class__(self.radius // other)
+
+ def __rfloordiv__(self, other):
+ return self.__class__(other // self._radius)
+
+ def __ifloordiv__(self, other):
+ if hasattr(other, '_radius'):
+ return self.__class__(self._radius // other.radius)
+ return self.__class__(self.radius // other)
+
@property
def radius(self):
+ """ Sets or returns the radius """
return self._radius
@radius.setter
@@ -71,6 +129,7 @@ def radius(self):
@property
def diameter(self):
+ """ Returns the diameter calculated from radius """
return self._radius * 2
@diameter.setter
@@ -79,7 +138,7 @@ def diameter(self, value):
@property
def area(self):
- """ Returns the area """
+ """ Returns the area calculated from radius """
return 2 * math.pi * self.radius ** 2
@classmethod
@@ -88,3 +147,23 @@ def from_diameter(cls, diameter):
self = cls()
self.radius = diameter * .5
return self
+
+
+class Sphere(Circle):
+ """ Sphere class, inherits from Circle """
+
+ def __str__(self):
+ return f'Sphere with radius: {self.radius}'
+
+ def __repr__(self):
+ return f'Sphere({self.radius})'
+
+ @Circle.area.getter
+ def area(self):
+ """ Returns the area of the sphere """
+ return 4 * math.pi * self.radius ** 2
+
+ @property
+ def volume(self):
+ """ Returns the Volume of the sphere """
+ return (4/3) * math.pi * self.radius ** 3
diff --git a/students/douglas_klos/session8/lab/run_circle.py b/students/douglas_klos/session8/lab/run_circle.py
index e70eeb32..cfb1a503 100755
--- a/students/douglas_klos/session8/lab/run_circle.py
+++ b/students/douglas_klos/session8/lab/run_circle.py
@@ -53,6 +53,9 @@ def main():
print(c1 * 5.0)
print(10.2 * c1)
+ del(c1)
+
+
if __name__ == '__main__':
main()
diff --git a/students/douglas_klos/session8/lab/test_circle.py b/students/douglas_klos/session8/lab/test_circle.py
index cfce851e..679a9729 100755
--- a/students/douglas_klos/session8/lab/test_circle.py
+++ b/students/douglas_klos/session8/lab/test_circle.py
@@ -1,8 +1,17 @@
#!/usr/bin/env python3
+#pylint: disable=C0113
+
+""" Pytest file for circle.py """
+
+# Douglas Klos
+# March 4th, 2019
+# Python 210, Session 8
+# test_circle.py
+
import math
import pytest
-from circle import *
+from circle import Circle, Sphere
def test_set_radius_init():
@@ -37,7 +46,7 @@ def test_area():
def test_set_area():
""" Tests that setting the area fails and returns an AttributeError """
circle1 = Circle(10)
-
+
with pytest.raises(AttributeError):
circle1.area = 100
@@ -46,7 +55,7 @@ def test_from_diameter():
""" Tests that a circle can be created from a diameter """
circle1 = Circle.from_diameter(10)
- assert circle1.radius == 5
+ assert circle1.radius == 5
assert circle1.diameter == 10
assert circle1.area == 2 * math.pi * circle1.radius ** 2
@@ -54,23 +63,23 @@ def test_from_diameter():
def test_str():
""" Tests that __str__ is working """
circle1 = Circle(10)
-
- assert 'Circle with radius: 10' == str(circle1)
-
+ assert str(circle1) == 'Circle with radius: 10'
+
+
def test_repr():
""" Tests that __repr__ is working """
circle1 = Circle(10)
- assert 'Circle(10)' == repr(circle1)
-
+ assert repr(circle1) == 'Circle(10)'
+
def test_addition():
""" Tests that __add___ is working """
circle1 = Circle(10)
circle2 = Circle(20)
circle3 = circle1 + circle2
-
+
assert circle3.radius == 30
assert circle1 + 5 == Circle(15)
@@ -85,25 +94,48 @@ def test_radd():
assert 5 + circle1 == Circle(7)
+def test_iadd():
+ """ Tests that += works """
+ circle1 = Circle(2)
+ circle2 = Circle(4)
+ circle1 += circle2
+ circle2 += 2
+
+ assert circle1 == Circle(6)
+ assert circle2 == Circle(6)
+
+
def test_subtraction():
""" Tests that __sub___ is working """
circle1 = Circle(10)
circle2 = Circle(6)
circle3 = circle1 - circle2
-
+
assert circle3.radius == 4
assert circle1 - 5 == Circle(5)
assert circle2 - 2 == Circle(4)
def test_rsub():
+ """ Tests that reflected subtractions works """
circle1 = Circle(10)
circle2 = Circle(6)
assert 10 - circle1 == circle1 - 10
assert 10 - circle2 == Circle(4)
assert 10.0 - circle2 == Circle(4)
-
+
+
+def test_isub():
+ """ Tests that -= works """
+ circle1 = Circle(2)
+ circle2 = Circle(4)
+ circle2 -= circle1
+ circle1 -= 1
+
+ assert circle1 == Circle(1)
+ assert circle2 == Circle(2)
+
def test_multiplication():
""" Tests that __mul__ is working """
@@ -117,6 +149,7 @@ def test_multiplication():
def test_rmul():
+ """ Tests that reflected multiplication works """
circle1 = Circle(2)
circle2 = Circle(4)
@@ -125,6 +158,101 @@ def test_rmul():
assert 2 * circle2 == Circle(8)
+def test_imul():
+ """ Tests that *= works """
+ circle1 = Circle(2)
+ circle2 = Circle(4)
+ circle2 *= circle1
+ circle1 *= 5
+
+ assert circle1 == Circle(10)
+ assert circle2 == Circle(8)
+
+
+def test_truediv():
+ """ Tests that division works """
+ circle1 = Circle(10)
+ circle2 = Circle(5)
+ circle3 = circle1 / circle2
+ circle4 = circle2 / circle1
+ circle5 = circle1 / 5
+ circle6 = circle2 / 10
+
+ assert circle1 / circle2 == Circle(2)
+ assert circle2 / circle1 == Circle(.5)
+ assert circle3.radius == 2
+ assert circle4.radius == .5
+ assert circle5.radius == 2
+ assert circle6.radius == .5
+
+
+def test_rtruediv():
+ """ Tests that reflected division works """
+ circle1 = Circle(10)
+ circle2 = Circle(5)
+ circle3 = 5 / circle1
+ circle4 = 10 / circle2
+
+ assert 2 / circle1 == Circle(0.2)
+ assert circle3 == Circle(.5)
+ assert circle3.radius == 0.5
+ assert circle4 == Circle(2)
+ assert circle4.radius == 2
+
+
+def test_itruediv():
+ """ Tests that /= works """
+ circle1 = Circle(2)
+ circle2 = Circle(4)
+ circle2 /= circle1
+ circle1 /= 10
+
+ assert circle1 == Circle(.2)
+ assert circle2 == Circle(2)
+
+
+def test_floordiv():
+ """ Tests that classical floor division works """
+ circle1 = Circle(10)
+ circle2 = Circle(5)
+ circle3 = circle1 // circle2
+ circle4 = circle2 // circle1
+ circle5 = circle1 // 5
+ circle6 = circle2 // 10
+
+ assert circle3 == Circle(2)
+ assert circle4 == Circle(0)
+ assert circle3.radius == 2
+ assert circle4.radius == 0
+ assert circle5.radius == 2
+ assert circle6.radius == 0
+
+
+def test_rfloordiv():
+ """ Tests that reflected classical floor division works """
+ circle1 = Circle(10)
+ circle2 = Circle(5)
+ circle3 = 5 // circle1
+ circle4 = 10 // circle2
+
+ assert 2 // circle1 == Circle(0)
+ assert circle3.radius == 0
+ assert circle3 == Circle(0)
+ assert circle4.radius == 2
+ assert circle4 == Circle(2)
+
+
+def test_ifloordiv():
+ """ Tests that //= works """
+ circle1 = Circle(2)
+ circle2 = Circle(4)
+ circle2 //= circle1
+ circle1 //= 10
+
+ assert circle1 == Circle(0)
+ assert circle2 == Circle(2)
+
+
def test_comparisons1():
""" Tests comparison operations when circle1 is less than circle 2 """
circle1 = Circle(2)
@@ -173,3 +301,92 @@ def test_sort():
circle_list.sort()
assert circle_list == [circle3, circle2, circle1]
+
+
+def test_deleter():
+ """ Tests that the deleter works for radius """
+ circle1 = Circle(10)
+ del circle1.radius
+
+ with pytest.raises(AttributeError):
+ print(circle1.radius)
+
+
+def test_sphere_init():
+ """ Tests that a Sphere object can be created """
+ sphere1 = Sphere()
+ sphere2 = Sphere(10)
+
+ assert sphere1.radius == 0
+ assert sphere1.diameter == 0
+ assert sphere2.radius == 10
+ assert sphere2.diameter == 20
+
+
+def test_sphere_area():
+ """ Tests that the area of the sphere is calculated correctly """
+ sphere1 = Sphere(10)
+
+ assert sphere1.area == 4 * math.pi * 10 ** 2
+
+
+def test_sphere_volume():
+ """ Tests that the volume of the sphere is calculated correctly """
+ sphere1 = Sphere(10)
+
+ assert sphere1.volume == (4/3) * math.pi * 10 ** 3
+
+
+def test_sphere_str():
+ """ Tests that __str__ is working """
+ sphere1 = Sphere(10)
+
+ print(str(sphere1))
+ assert str(sphere1) == 'Sphere with radius: 10'
+
+
+def test_sphere_repr():
+ """ Tests that __repr__ is working """
+ sphere1 = Sphere(10)
+
+ print(repr(sphere1))
+ assert repr(sphere1) == 'Sphere(10)'
+
+
+def test_sphere_from_diameter():
+ """ Tests you can create a sphere from diameter """
+ sphere1 = Sphere.from_diameter(10)
+
+ assert sphere1.radius == 5
+
+
+def test_sphere_math():
+ """ Tests that operators work on spheres """
+ sphere1 = Sphere(10)
+ sphere2 = Sphere(20)
+
+ assert sphere1 + sphere2 == Sphere(30)
+ assert sphere2 - sphere1 == Sphere(10)
+ assert sphere1 * sphere2 == Sphere(200)
+ assert sphere1 / sphere2 == Sphere(0.5)
+ assert sphere1 // sphere2 == Sphere(0)
+
+ assert 10 + sphere1 == Sphere(20)
+ assert 20 - sphere1 == Sphere(10)
+ assert 10 * sphere2 == Sphere(200)
+ assert 10 / sphere2 == Sphere(.5)
+ assert 10 // sphere2 == Sphere(0)
+
+
+def test_sphere_comparisons():
+ """ Tests that comparisons work on spheres """
+ sphere1 = Sphere(10)
+ sphere2 = Sphere(20)
+ sphere3 = Sphere(20)
+
+ assert sphere1 < sphere2
+ assert sphere1 <= sphere2
+ assert sphere2 > sphere1
+ assert sphere2 >= sphere1
+ assert sphere2 == sphere3
+ assert sphere1 != sphere2
From 9365b2e6270c62a4bffdcf03baf0af6bb0864959 Mon Sep 17 00:00:00 2001
From: mjchang14
Date: Mon, 4 Mar 2019 21:40:03 -0800
Subject: [PATCH 054/367] adding html_render through step 7
---
students/mjchang/session07/html_render.py | 18 +++--
students/mjchang/session07/run_html_render.py | 78 +++++++++----------
.../mjchang/session07/test_html_render.py | 46 +++++++++++
3 files changed, 98 insertions(+), 44 deletions(-)
diff --git a/students/mjchang/session07/html_render.py b/students/mjchang/session07/html_render.py
index 7c27a67f..b507d974 100644
--- a/students/mjchang/session07/html_render.py
+++ b/students/mjchang/session07/html_render.py
@@ -47,12 +47,12 @@ def _close_tag(self):
class OneLineTag(Element):
def render(self, out_file):
for content in self.contents:
- out_file.write("<{}>".format(self.tag)) #removed newline
+ out_file.write(self._open_tag()) #removed newline
try:
content.render(out_file)
except AttributeError:
out_file.write(content) #removed newline from Element
- out_file.write("{}>\n".format(self.tag))
+ out_file.write(self._close_tag())
def append(self, content):
raise NotImplementedError
@@ -93,12 +93,20 @@ class Head(Element):
class Title(OneLineTag):
tag = "title"
+class A(OneLineTag):
+ tag = "a"
+
+ def __init__(self, link, content=None, **kwargs):
+ kwargs['href'] = link
+ super().__init__(content, **kwargs)
+
class Ul(Element):
tag = "ul"
class List(Element):
tag = "li"
-class Anchor(Element):
- tag = "a"
-
+class H(OneLineTag):
+ def __init__(self, level, content, **kwargs):
+ self.tag = "h{}".format(level)
+ super().__init__(content, **kwargs)
\ No newline at end of file
diff --git a/students/mjchang/session07/run_html_render.py b/students/mjchang/session07/run_html_render.py
index 05e5453b..054cb8e3 100644
--- a/students/mjchang/session07/run_html_render.py
+++ b/students/mjchang/session07/run_html_render.py
@@ -126,69 +126,69 @@ def render_page(page, filename, indent=None):
render_page(page, "test_html_output5.html")
-# # Step 6
-# #########
+# Step 6
+#########
-# page = hr.Html()
+page = hr.Html()
-# head = hr.Head()
-# head.append(hr.Title("PythonClass = Revision 1087:"))
+head = hr.Head()
+head.append(hr.Title("PythonClass = Revision 1087:"))
-# page.append(head)
+page.append(head)
-# body = hr.Body()
+body = hr.Body()
-# body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
-# "but this is enough to show that we can do some text",
-# style="text-align: center; font-style: oblique;"))
+body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+ "but this is enough to show that we can do some text",
+ style="text-align: center; font-style: oblique;"))
-# body.append(hr.Hr())
+body.append(hr.Hr())
-# body.append("And this is a ")
-# body.append( hr.A("http://google.com/", "link") )
-# body.append("to google")
+body.append("And this is a ")
+body.append( hr.A("http://google.com/", "link") )
+body.append("to google")
-# page.append(body)
+page.append(body)
-# render_page(page, "test_html_output6.html")
+render_page(page, "test_html_output6.html")
-# # Step 7
-# #########
+# Step 7
+#########
-# page = hr.Html()
+page = hr.Html()
-# head = hr.Head()
-# head.append(hr.Title("PythonClass = Revision 1087:"))
+head = hr.Head()
+head.append(hr.Title("PythonClass = Revision 1087:"))
-# page.append(head)
+page.append(head)
-# body = hr.Body()
+body = hr.Body()
-# body.append( hr.H(2, "PythonClass - Class 6 example") )
+body.append( hr.H(2, "PythonClass - Class 6 example") )
-# body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
-# "but this is enough to show that we can do some text",
-# style="text-align: center; font-style: oblique;"))
+body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+ "but this is enough to show that we can do some text",
+ style="text-align: center; font-style: oblique;"))
-# body.append(hr.Hr())
+body.append(hr.Hr())
-# list = hr.Ul(id="TheList", style="line-height:200%")
+list = hr.Ul(id="TheList", style="line-height:200%")
-# list.append( hr.Li("The first item in a list") )
-# list.append( hr.Li("This is the second item", style="color: red") )
+list.append( hr.Li("The first item in a list") )
+list.append( hr.Li("This is the second item", style="color: red") )
-# item = hr.Li()
-# item.append("And this is a ")
-# item.append( hr.A("http://google.com/", "link") )
-# item.append("to google")
+item = hr.Li()
+item.append("And this is a ")
+item.append( hr.A("http://google.com/", "link") )
+item.append("to google")
-# list.append(item)
+list.append(item)
-# body.append(list)
+body.append(list)
-# page.append(body)
+page.append(body)
-# render_page(page, "test_html_output7.html")
+render_page(page, "test_html_output7.html")
# # Step 8 and 9
# ##############
diff --git a/students/mjchang/session07/test_html_render.py b/students/mjchang/session07/test_html_render.py
index ac8dc97d..9566f211 100644
--- a/students/mjchang/session07/test_html_render.py
+++ b/students/mjchang/session07/test_html_render.py
@@ -262,6 +262,52 @@ def test_append_content_in_br():
+#######
+# Step 6
+#######
+
+def test_anchor():
+ a = A("http://google.com/", "link to Google")
+ file_contents = render_result(a)
+ print(file_contents)
+ assert file_contents.startswith("")
+
+ e2 = List("This is the second item", style="color: red")
+ file_contents = render_result(e2).strip()
+ print(file_contents)
+ assert ("This is the second item") in file_contents
+ assert ('\n') in file_contents
+
+
+def test_unordered_list():
+ e = Ul("This is the second item")
+ # print(file_contents)
+ file_contents = render_result(e).strip()
+
+ assert("This is the second item") in file_contents
+ assert file_contents.startswith("")
+ assert file_contents.endswith("
")
+
+def test_header():
+ e = H(2, "PythonClass - Class 6 example")
+ file_contents = render_result(e).strip()
+ print(file_contents)
+ assert file_contents.startswith("")
+ assert ("PythonClass - Class 6 example") in file_contents
+
+
#####################
# indentation testing
# Uncomment for Step 9 -- adding indentation
From f3ae584183502ef136bc0bac784c1bb500478734 Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Tue, 5 Mar 2019 07:49:01 -0800
Subject: [PATCH 055/367] Update to html_render
---
students/jeff_shabani/session07/html_render.py | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 8135ef7e..d3a09347 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -31,9 +31,12 @@ def append(self, new_content):
def render(self, file_name, cur_indent=''):
# Writes the opening tag
file_name.write(f'{self._front_tag()}\n')
+
for content_line in self.content:
- file_name.write(f'{content_line}\n')
- # Writes the ending tag
+ if hasattr(content_line, 'render'):
+ content_line.render(file_name)
+ else:
+ file_name.write(f'{content_line}\n')
file_name.write(f'{self._end_tag()}\n')
From 83126b40d8369bc5aad422ff3979e7942d56ff99 Mon Sep 17 00:00:00 2001
From: UncleanlyCleric
Date: Tue, 5 Mar 2019 08:06:08 -0800
Subject: [PATCH 056/367] Yea, I'm still not sure I get OO programming at all.
This is very complicated to me.
---
students/jesse_miller/session08/circle.py | 31 ++++++++++++++++++++---
1 file changed, 28 insertions(+), 3 deletions(-)
diff --git a/students/jesse_miller/session08/circle.py b/students/jesse_miller/session08/circle.py
index 2b0716b8..c01ae371 100644
--- a/students/jesse_miller/session08/circle.py
+++ b/students/jesse_miller/session08/circle.py
@@ -3,10 +3,35 @@
Class based circle calculation exercise
'''
+from math import pi
'''
-Setting this space for the modules I'm certainly importing
+Imported the math module for calculation
'''
-class Circle:
+class Circle(object):
+ '''
+ Defining the circle class
+ '''
def __init__(self, radius):
- self.radius = radius
+ self.radius = radius
+
+ @property
+ def diameter(self):
+ '''
+ Defining diameter, I think I'm doing this right.
+ '''
+ return self.radius * 2
+
+ @diameter.setter
+ def diameter(self, value):
+ '''
+ This seems like the right time to use a setter
+ '''
+ self.radius = value / 2
+
+ @property
+ def area(self):
+ '''
+ Defining area, I'm a tad more confident in this one
+ '''
+ return pi * self.radius**2
From 59aee24d44ecd3551bcf0af4a13cd46f36de8acb Mon Sep 17 00:00:00 2001
From: Douglas Klos
Date: Tue, 5 Mar 2019 09:18:02 -0800
Subject: [PATCH 057/367] Began work on SparseArray class
---
.../{lab => exercises/circle}/circle.py | 0
.../{lab => exercises/circle}/run_circle.py | 4 +-
.../{lab => exercises/circle}/test_circle.py | 0
.../exercises/sparsearray/sparsearray.py | 34 +++++++++++++++++
.../exercises/sparsearray/test_sparsearray.py | 38 +++++++++++++++++++
5 files changed, 75 insertions(+), 1 deletion(-)
rename students/douglas_klos/session8/{lab => exercises/circle}/circle.py (100%)
rename students/douglas_klos/session8/{lab => exercises/circle}/run_circle.py (89%)
rename students/douglas_klos/session8/{lab => exercises/circle}/test_circle.py (100%)
create mode 100755 students/douglas_klos/session8/exercises/sparsearray/sparsearray.py
create mode 100755 students/douglas_klos/session8/exercises/sparsearray/test_sparsearray.py
diff --git a/students/douglas_klos/session8/lab/circle.py b/students/douglas_klos/session8/exercises/circle/circle.py
similarity index 100%
rename from students/douglas_klos/session8/lab/circle.py
rename to students/douglas_klos/session8/exercises/circle/circle.py
diff --git a/students/douglas_klos/session8/lab/run_circle.py b/students/douglas_klos/session8/exercises/circle/run_circle.py
similarity index 89%
rename from students/douglas_klos/session8/lab/run_circle.py
rename to students/douglas_klos/session8/exercises/circle/run_circle.py
index cfb1a503..f2a20ebc 100755
--- a/students/douglas_klos/session8/lab/run_circle.py
+++ b/students/douglas_klos/session8/exercises/circle/run_circle.py
@@ -2,6 +2,8 @@
from circle import *
+# This file was briefly used for testing.
+# It's not part of the assignment requirements and can be safely ignored.
def main():
c1 = Circle(5)
@@ -53,7 +55,7 @@ def main():
print(c1 * 5.0)
print(10.2 * c1)
- del(c1)
+
diff --git a/students/douglas_klos/session8/lab/test_circle.py b/students/douglas_klos/session8/exercises/circle/test_circle.py
similarity index 100%
rename from students/douglas_klos/session8/lab/test_circle.py
rename to students/douglas_klos/session8/exercises/circle/test_circle.py
diff --git a/students/douglas_klos/session8/exercises/sparsearray/sparsearray.py b/students/douglas_klos/session8/exercises/sparsearray/sparsearray.py
new file mode 100755
index 00000000..312f56e8
--- /dev/null
+++ b/students/douglas_klos/session8/exercises/sparsearray/sparsearray.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+
+""" SparseArray Class """
+
+# Douglas Klos
+# March 5th, 2019
+# Python 210, Session 8
+# sparsearray.py
+
+
+class SparseArray():
+ """ SparseArray class """
+
+ def __init__(self, values):
+ self.array = {}
+ self.length = len(values)
+
+ for i in range(len(values)):
+ if values[i] != 0:
+ self.array[i] = values[i]
+
+ def __str__(self):
+ values = [value for key, value in sorted(self.array.items())]
+ return str(values)
+
+ def __len__(self):
+ return self.length
+
+ def __getitem__(self, key):
+ return self.array[key]
+
+ def __setitem__(self, key, value):
+ if value:
+ self.array[key] = value
diff --git a/students/douglas_klos/session8/exercises/sparsearray/test_sparsearray.py b/students/douglas_klos/session8/exercises/sparsearray/test_sparsearray.py
new file mode 100755
index 00000000..afa0c5df
--- /dev/null
+++ b/students/douglas_klos/session8/exercises/sparsearray/test_sparsearray.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+
+""" Pytest file for sparsearray.py """
+
+# Douglas Klos
+# March 5th, 2019
+# Python 210, Session 8
+# test_sparsearray.py
+
+
+import pytest
+from sparsearray import SparseArray
+
+
+def test_sparsearray_init():
+ """ Tests that a sparsearray can be initialized """
+ sa = SparseArray([1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0])
+ print(sa.array)
+ assert sa.array[0] == sa.array[4] == sa.array[5] == sa.array[10] == sa.array[14] == 1
+
+
+def test_sparsearray_len():
+ list1 = [1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0]
+ sa = SparseArray([1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0])
+ print(sa)
+ assert len(sa) == len(list1)
+ assert False
+
+
+def test_sparsearray_set_value():
+ list1 = [1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0]
+ sa = SparseArray(list1)
+
+ print(sa)
+ sa[1] = 2
+ sa[2] = 0
+ print(sa)
+ assert False
\ No newline at end of file
From e044b38e97918b9ec524cb65b7028edc93b9db9b Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Tue, 5 Mar 2019 10:12:58 -0800
Subject: [PATCH 058/367] Update to html_render
---
.../jeff_shabani/session07/html_render.py | 30 ++++++++++++-------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index d3a09347..441b4f17 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -69,16 +69,26 @@ class for p tag
Step 3: print on one line
"""
-# class OneLineTag(Element):
-#
-# def render(self, file_name):
-# self.tag = f'{self.tag}>'
-# head = f'{self.tag.ljust(len(self.tag) + 1)}'
-# for k, v in self.kwargs.items():
-# head += f'{k.rjust(len(k) + 1)}="{v}"'
-# outtext = f'<{head}{self.content}{self.tag}>'
-# with open(f'{file_name}.html', 'w') as file:
-# file.write(outtext)
+class OneLineTag(Element):
+
+ def render(self, file_name, cur_indent=''):
+ # Writes the opening tag
+ file_name.write(f'{self._front_tag().ljust(len(self._front_tag()+1))}')
+ for k, v in self.attrs.items():
+ file_name.write(f'{k.rjust(len(k) + 1)}="{v}"')
+ file_name.write(f'{self._end_tag()}\n')
+
+
+
+
+ # def render_alt(self, file_name):
+ # self.tag = f'{self.tag}>'
+ # head = f'{self.tag.ljust(len(self.tag) + 1)}'
+ # for k, v in self.kwargs.items():
+ # head += f'{k.rjust(len(k) + 1)}="{v}"'
+ # outtext = f'<{head}{self.content}{self.tag}>'
+ # with open(f'{file_name}.html', 'w') as file:
+ # file.write(outtext)
"""
From b9b655eef4f9c4f24e3fd60803369c1ebcbdf328 Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Tue, 5 Mar 2019 10:14:27 -0800
Subject: [PATCH 059/367] Update to html_render
---
students/jeff_shabani/session07/html_render.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 441b4f17..53928996 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -72,7 +72,11 @@ class for p tag
class OneLineTag(Element):
def render(self, file_name, cur_indent=''):
- # Writes the opening tag
+ """
+ Renders elements on a single line.
+ :param file_name:
+ :param cur_indent:
+ """
file_name.write(f'{self._front_tag().ljust(len(self._front_tag()+1))}')
for k, v in self.attrs.items():
file_name.write(f'{k.rjust(len(k) + 1)}="{v}"')
From d7e97a9f060125b892bf06b41ef01b6d7b4046eb Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Tue, 5 Mar 2019 10:53:01 -0800
Subject: [PATCH 060/367] Update to html_render
---
students/jeff_shabani/session07/html_render.py | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 53928996..8330de62 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -71,16 +71,22 @@ class for p tag
class OneLineTag(Element):
+
+ def append(self, new_content):
+ raise BaseException
+
def render(self, file_name, cur_indent=''):
"""
Renders elements on a single line.
:param file_name:
:param cur_indent:
"""
- file_name.write(f'{self._front_tag().ljust(len(self._front_tag()+1))}')
+ file_name.write(f'{self._front_tag()} ')
for k, v in self.attrs.items():
- file_name.write(f'{k.rjust(len(k) + 1)}="{v}"')
- file_name.write(f'{self._end_tag()}\n')
+ file_name.write(f'{k}="{v}"')
+ file_name.write(f'{self._front_tag()}')
+ file_name.write(f'{self.content[0]}')
+ file_name.write(f'{self._end_tag()}')
@@ -166,3 +172,8 @@ def render(self, file_name, cur_indent=''):
#
# def __init__(self, content=None, tag = 'meta charset="UTF-8"'):
# super().__init__(content, tag)
+
+# if __name__ == '__main__':
+#
+# olt = OneLineTag('this is william')
+# olt.render(olt, 'tag')
From 34800447393a7030a7dd80c502a25b6e65ea2a25 Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Tue, 5 Mar 2019 12:05:40 -0800
Subject: [PATCH 061/367] Update to html_render
---
students/jeff_shabani/session07/html_render.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index 8330de62..c0e224ce 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -3,7 +3,7 @@
"""
A class-based system for rendering html.
"""
-
+import functools
# This is the framework for the base class
class Element(object):
@@ -68,12 +68,9 @@ class for p tag
"""
Step 3: print on one line
"""
-
class OneLineTag(Element):
-
- def append(self, new_content):
- raise BaseException
+ Tag = 'Title'
def render(self, file_name, cur_indent=''):
"""
@@ -88,6 +85,9 @@ def render(self, file_name, cur_indent=''):
file_name.write(f'{self.content[0]}')
file_name.write(f'{self._end_tag()}')
+ def append(self, new_content):
+ raise NotImplementedError
+
From d7cb909589d7f5222598a42f91c7880fc155f078 Mon Sep 17 00:00:00 2001
From: Douglas Klos
Date: Tue, 5 Mar 2019 13:58:57 -0800
Subject: [PATCH 062/367] Dictionary based SparseArray working
---
.../exercises/sparsearray/sparsearray.py | 46 +++++++++--
.../exercises/sparsearray/test_sparsearray.py | 79 ++++++++++++++++---
2 files changed, 107 insertions(+), 18 deletions(-)
diff --git a/students/douglas_klos/session8/exercises/sparsearray/sparsearray.py b/students/douglas_klos/session8/exercises/sparsearray/sparsearray.py
index 312f56e8..8f9f2bbd 100755
--- a/students/douglas_klos/session8/exercises/sparsearray/sparsearray.py
+++ b/students/douglas_klos/session8/exercises/sparsearray/sparsearray.py
@@ -15,20 +15,54 @@ def __init__(self, values):
self.array = {}
self.length = len(values)
- for i in range(len(values)):
- if values[i] != 0:
- self.array[i] = values[i]
+ for key, value in enumerate(values):
+ if value:
+ self.array[key] = value
+
+ def full_array(self):
+ """ Returns the sparse array including 0's """
+ return_array = []
+ sorted_values = {key: value for key, value in sorted(self.array.items())}
+ for counter in range(self.length):
+ try:
+ return_array.append(sorted_values[counter])
+ except KeyError:
+ return_array.append(0)
+ return return_array
def __str__(self):
- values = [value for key, value in sorted(self.array.items())]
- return str(values)
+ return str(self.full_array())
+
+ def __repr__(self):
+ return str(self.full_array())
def __len__(self):
return self.length
def __getitem__(self, key):
- return self.array[key]
+ if isinstance(key, slice):
+ return self.full_array()[key.start:key.stop:key.step]
+ if key > self.length:
+ raise IndexError
+ try:
+ return self.array[key]
+ except KeyError:
+ return 0
def __setitem__(self, key, value):
+ if key > self.length:
+ raise IndexError
if value:
self.array[key] = value
+ elif key in self.array:
+ del self.array[key]
+
+ def __delitem__(self, key):
+ del self.array[key]
+
+ def append(self, values):
+ """ Appends new values to the end of the sparse array """
+ for key, value in enumerate(values):
+ if value:
+ self.array[key + self.length] = value
+ self.length += len(values)
diff --git a/students/douglas_klos/session8/exercises/sparsearray/test_sparsearray.py b/students/douglas_klos/session8/exercises/sparsearray/test_sparsearray.py
index afa0c5df..3cace501 100755
--- a/students/douglas_klos/session8/exercises/sparsearray/test_sparsearray.py
+++ b/students/douglas_klos/session8/exercises/sparsearray/test_sparsearray.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-
+#pylint: disable=C0103
""" Pytest file for sparsearray.py """
# Douglas Klos
@@ -11,28 +11,83 @@
import pytest
from sparsearray import SparseArray
+LIST1 = [1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0]
+LIST2 = [2, 0, 0]
+
def test_sparsearray_init():
""" Tests that a sparsearray can be initialized """
- sa = SparseArray([1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0])
+ sa = SparseArray(LIST1)
print(sa.array)
assert sa.array[0] == sa.array[4] == sa.array[5] == sa.array[10] == sa.array[14] == 1
def test_sparsearray_len():
- list1 = [1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0]
- sa = SparseArray([1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0])
+ """ Tests that length is returned properly """
+ sa = SparseArray(LIST1)
print(sa)
- assert len(sa) == len(list1)
- assert False
-
+ assert len(sa) == len(LIST1)
-def test_sparsearray_set_value():
- list1 = [1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0]
- sa = SparseArray(list1)
- print(sa)
+def test_sparsearray_set_get_value():
+ """ Tests that you can get and set values to the sparse array """
+ sa = SparseArray(LIST1)
sa[1] = 2
sa[2] = 0
+
+ with pytest.raises(IndexError):
+ print(sa[20])
+ with pytest.raises(IndexError):
+ sa[20] = 10
+
+ sa[0] = 0
+ assert sa[0] == 0
+
+ assert sa[1] == 2
+ assert sa[2] == 0
+
+
+def test_sparsearray_str():
+ """ Tests that str(SparseArray) is correctly implemented """
+ sa = SparseArray(LIST1)
+
+ assert str(sa) == str(LIST1)
+
+
+def test_sparsearray_repr():
+ """ Tests that repr(SparseArray) is correctly implemented """
+ sa = SparseArray(LIST1)
+
+ print(repr(LIST1))
+ assert repr(sa) == repr(LIST1)
+
+
+def test_sparsearray_append():
+ """ Tests that you can append to the sparse array """
+ sa = SparseArray(LIST1)
+ sa.append(LIST2)
+
+ assert str(sa) == str(LIST1 + LIST2)
+ assert len(sa) == 21
+
+
+def test_sparsearray_del():
+ """ Tests that you can delete an element from the sparse array """
+ sa = SparseArray(LIST1)
+ del sa[4]
print(sa)
- assert False
\ No newline at end of file
+
+ assert sa[4] == 0
+ assert len(sa) == 18
+
+
+def test_sparsearray_slice():
+ """ Tests that you can get slices from the sparse array """
+ sa = SparseArray(LIST1)
+ sa.append(LIST2)
+ list3 = LIST1 + LIST2
+
+ assert sa[0:4] == list3[0:4]
+ assert sa[5:10] == list3[5:10]
+ assert sa[10:21] == list3[10:21]
+ assert sa[-1::2] == list3[-1::2]
From 4e9a6a79c2eec7431a59196b349b4b2037d094d5 Mon Sep 17 00:00:00 2001
From: Jeff Shabani
Date: Tue, 5 Mar 2019 14:29:36 -0800
Subject: [PATCH 063/367] Update to html_render
---
.../jeff_shabani/session07/html_render.py | 96 +++++++++----------
1 file changed, 46 insertions(+), 50 deletions(-)
diff --git a/students/jeff_shabani/session07/html_render.py b/students/jeff_shabani/session07/html_render.py
index c0e224ce..23aaba5a 100644
--- a/students/jeff_shabani/session07/html_render.py
+++ b/students/jeff_shabani/session07/html_render.py
@@ -70,7 +70,7 @@ class for p tag
"""
class OneLineTag(Element):
- Tag = 'Title'
+ tag = 'Title'
def render(self, file_name, cur_indent=''):
"""
@@ -89,60 +89,63 @@ def append(self, new_content):
raise NotImplementedError
+class Head(Element):
+ tag = "head"
- # def render_alt(self, file_name):
- # self.tag = f'{self.tag}>'
- # head = f'{self.tag.ljust(len(self.tag) + 1)}'
- # for k, v in self.kwargs.items():
- # head += f'{k.rjust(len(k) + 1)}="{v}"'
- # outtext = f'<{head}{self.content}{self.tag}>'
- # with open(f'{file_name}.html', 'w') as file:
- # file.write(outtext)
"""
Step 5: Self closing tag
"""
-# class SelfClosingTag(Element):
-#
-# def render(self, file_name):
-#
-# """
-# if conent is entered this tells user that self closing tags
-# can't have conent and resets the conent to an empty string.
-# """
-#
-# if self.content:
-# print('Self closing tags cannot have content')
-# else:
-# self.content = ''
-#
-# head = f'{self.tag.ljust(len(self.tag) + 1)}'
-# for k, v in self.kwargs.items():
-# head += f'{k.rjust(len(k) + 1)}="{v}"'
-# outtext = f'<{head}/>'
-# with open(f'{file_name}.html', 'w') as file:
-# file.write(outtext)
+class SelfClosingTag(Element):
+ tag = 'br'
+
+ def append(self, new_content):
+ raise NotImplementedError
+
+ def render(self, file_name):
+
+ """
+ if conent is entered this tells user that self closing tags
+ can't have conent and resets the conent to an empty string.
+ """
+
+ if self.content:
+ raise TypeError
+ file_name.write(f'{self._front_tag()[:-1]}')
+ for k, v in self.attrs.items():
+ file_name.write(f'{k.rjust(len(k) + 1)}="{v}" />')
"""
Step 6
"""
-# class A(Element):
-#
-# def __init__(self, link, content):
-# self.link = link
-# self.content = content
-# super(Element).__init__()
-#
-# def render(self, file_name):
-# head = 'a href='
-# tail = 'a'
-# outtext = f'<{head}"{self.link}">{self.content}{tail}>'
-# with open(f'{file_name}.html', 'w') as file:
-# file.write(outtext)
+class A(OneLineTag):
+
+ tag = 'a'
+
+ def __init__(self, link, content=None, **attrs):
+ if not (content and link): raise TypeError
+
+ attrs['href'] = link
+ super().__init__(content, **attrs)
+
+ tag = 'a'
+
+ # def __init__(self, link, content):
+ # self.link = link
+ # self.content = content
+ # #super(Element).__init__()
+ #
+ # def render(self, file_name):
+ # filename.write()
+ # head = 'a href='
+ # tail = 'a'
+ # outtext = f'<{head}"{self.link}">{self.content}{tail}>'
+ # with open(f'{file_name}.html', 'w') as file:
+ # file.write(outtext)
#
# class Ul(Element):
# """
@@ -156,14 +159,7 @@ def append(self, new_content):
# """
# list_element = ''
#
-# class Head(OneLineTag):
-#
-# def __init__(self, level, content, tag=None, **kwargs):
-# self.level = level
-# self.content = content
-# self.tag = f'h{level}'
-# self.kwargs = kwargs
-# super(OneLineTag).__init__(list, tag, **kwargs)
+
#
# class Meta(SelfClosingTag):
# """
From fac9bea042ac2801eb049478166e7489b54a58ae Mon Sep 17 00:00:00 2001
From: JRockwell70
Date: Tue, 5 Mar 2019 17:32:52 -0800
Subject: [PATCH 064/367] session 08 material
---
students/jeff_shabani/session08/Circle.py | 15 +++++++++++++++
students/jeff_shabani/session08/__init__.py | 0
students/jeff_shabani/session08/test_circle.py | 6 ++++++
3 files changed, 21 insertions(+)
create mode 100644 students/jeff_shabani/session08/Circle.py
create mode 100644 students/jeff_shabani/session08/__init__.py
create mode 100644 students/jeff_shabani/session08/test_circle.py
diff --git a/students/jeff_shabani/session08/Circle.py b/students/jeff_shabani/session08/Circle.py
new file mode 100644
index 00000000..7619efa8
--- /dev/null
+++ b/students/jeff_shabani/session08/Circle.py
@@ -0,0 +1,15 @@
+
+
+
+
+
+class Circle(object):
+ def __init__(self, radius):
+ self.radius = radius
+
+ def __repr__(self):
+ return f'The radius is {self.radius}'
+
+
+c = Circle(5)
+print(c)
\ No newline at end of file
diff --git a/students/jeff_shabani/session08/__init__.py b/students/jeff_shabani/session08/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/students/jeff_shabani/session08/test_circle.py b/students/jeff_shabani/session08/test_circle.py
new file mode 100644
index 00000000..a5ba9adf
--- /dev/null
+++ b/students/jeff_shabani/session08/test_circle.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import io
+import pytest
+
+from Circle import *
\ No newline at end of file
From f524f0d22c982cd7598cd2d485a808d6ca12bca5 Mon Sep 17 00:00:00 2001
From: JRockwell70
Date: Tue, 5 Mar 2019 17:55:24 -0800
Subject: [PATCH 065/367] session 08 material
---
students/jeff_shabani/session08/Circle.py | 5 +++--
.../jeff_shabani/session08/test_circle.py | 20 ++++++++++++++++++-
2 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/students/jeff_shabani/session08/Circle.py b/students/jeff_shabani/session08/Circle.py
index 7619efa8..02c9a178 100644
--- a/students/jeff_shabani/session08/Circle.py
+++ b/students/jeff_shabani/session08/Circle.py
@@ -11,5 +11,6 @@ def __repr__(self):
return f'The radius is {self.radius}'
-c = Circle(5)
-print(c)
\ No newline at end of file
+if __name__ =='__main__':
+ c = Circle(5)
+ print(c)
\ No newline at end of file
diff --git a/students/jeff_shabani/session08/test_circle.py b/students/jeff_shabani/session08/test_circle.py
index a5ba9adf..ef3f53d5 100644
--- a/students/jeff_shabani/session08/test_circle.py
+++ b/students/jeff_shabani/session08/test_circle.py
@@ -2,5 +2,23 @@
import io
import pytest
+import unittest
-from Circle import *
\ No newline at end of file
+from Circle import *
+
+
+def test_init():
+ c = Circle(5)
+
+ assert print(c) == 6, 'Not equal'
+
+# c = Circle(8)
+# print(c.radius)
+# class mailroomTests(unittest.TestCase):
+#
+# def test_init(self):
+# c=Circle(5)
+# self.assertEqual(print(c.radius), 5)
+#
+# if __name__ == '__main__':
+# unittest.main()
\ No newline at end of file
From 11f9b59b9f07ec36d1ec38e48d4ad6af38c6d55e Mon Sep 17 00:00:00 2001
From: admin <23247076+Rockwell70@users.noreply.github.com>
Date: Tue, 5 Mar 2019 18:18:06 -0800
Subject: [PATCH 066/367] html_render update
---
.../jeff_shabani/session08/test_circle.py | 26 ++++++++-----------
1 file changed, 11 insertions(+), 15 deletions(-)
diff --git a/students/jeff_shabani/session08/test_circle.py b/students/jeff_shabani/session08/test_circle.py
index ef3f53d5..a7edb78b 100644
--- a/students/jeff_shabani/session08/test_circle.py
+++ b/students/jeff_shabani/session08/test_circle.py
@@ -7,18 +7,14 @@
from Circle import *
-def test_init():
- c = Circle(5)
-
- assert print(c) == 6, 'Not equal'
-
-# c = Circle(8)
-# print(c.radius)
-# class mailroomTests(unittest.TestCase):
-#
-# def test_init(self):
-# c=Circle(5)
-# self.assertEqual(print(c.radius), 5)
-#
-# if __name__ == '__main__':
-# unittest.main()
\ No newline at end of file
+c=Circle(5)
+
+class mailroomTests(unittest.TestCase):
+
+
+ def test_init(self):
+ #c=Circle(5)
+ self.assertEqual(c.radius, 5)
+
+if __name__ == '__main__':
+ unittest.main()
\ No newline at end of file
From 48fbdab47df7367dfea0a7acc0f2fb3d85ead20b Mon Sep 17 00:00:00 2001
From: mjchang14
Date: Tue, 5 Mar 2019 19:39:00 -0800
Subject: [PATCH 067/367] adding completed HTML assignment
---
students/mjchang/session07/html_render.py | 34 ++--
students/mjchang/session07/run_html_render.py | 48 +++---
.../mjchang/session07/test_html_render.py | 148 ++++++++++--------
3 files changed, 133 insertions(+), 97 deletions(-)
diff --git a/students/mjchang/session07/html_render.py b/students/mjchang/session07/html_render.py
index b507d974..a2f4454e 100644
--- a/students/mjchang/session07/html_render.py
+++ b/students/mjchang/session07/html_render.py
@@ -9,6 +9,7 @@
class Element(object):
tag = "html"
+ indent = " "
def __init__(self, content=None, **kwargs):
self.attributes = kwargs
@@ -20,16 +21,16 @@ def append(self, new_content):
self.contents.append(new_content)
- def render(self, out_file):
- out_file.write(self._open_tag())
+ def render(self, out_file, cur_ind=""):
+ out_file.write(cur_ind + self._open_tag())
out_file.write("\n")
for content in self.contents:
try:
- content.render(out_file)
+ content.render(out_file, cur_ind + self.indent)
except AttributeError:
- out_file.write(content)
+ out_file.write(cur_ind + self.indent + content)
out_file.write("\n")
- out_file.write(self._close_tag())
+ out_file.write(cur_ind + self._close_tag())
out_file.write("\n")
def _open_tag(self):
@@ -45,11 +46,11 @@ def _close_tag(self):
class OneLineTag(Element):
- def render(self, out_file):
+ def render(self, out_file, cur_ind=""):
for content in self.contents:
- out_file.write(self._open_tag()) #removed newline
+ out_file.write(cur_ind + self._open_tag()) #removed newline
try:
- content.render(out_file)
+ content.render(out_file, cur_ind)
except AttributeError:
out_file.write(content) #removed newline from Element
out_file.write(self._close_tag())
@@ -64,8 +65,8 @@ def __init__(self, content=None, **kwargs):
raise TypeError("SelfClosingTag cannot contain any content")
super().__init__(content=content, **kwargs)
- def render(self, out_file):
- tag = self._open_tag()[:-1] + " />\n"
+ def render(self, out_file, cur_ind=""):
+ tag = cur_ind + self._open_tag()[:-1] + " />\n"
out_file.write(tag)
def append(self, *args):
@@ -80,6 +81,12 @@ class Br(SelfClosingTag):
class Html(Element):
tag = "html"
+ doctype = ""
+
+ def render(self, out_file, cur_ind=""):
+ out_file.write(cur_ind + self.doctype)
+ out_file.write("\n")
+ super().render(out_file, cur_ind)
class Body(Element):
tag = "body"
@@ -103,10 +110,13 @@ def __init__(self, link, content=None, **kwargs):
class Ul(Element):
tag = "ul"
-class List(Element):
+class Li(Element):
tag = "li"
class H(OneLineTag):
def __init__(self, level, content, **kwargs):
self.tag = "h{}".format(level)
- super().__init__(content, **kwargs)
\ No newline at end of file
+ super().__init__(content, **kwargs)
+
+class Meta(SelfClosingTag):
+ tag = 'meta charset="UTF-8"'
\ No newline at end of file
diff --git a/students/mjchang/session07/run_html_render.py b/students/mjchang/session07/run_html_render.py
index 054cb8e3..718ec63b 100644
--- a/students/mjchang/session07/run_html_render.py
+++ b/students/mjchang/session07/run_html_render.py
@@ -190,42 +190,42 @@ def render_page(page, filename, indent=None):
render_page(page, "test_html_output7.html")
-# # Step 8 and 9
-# ##############
+# Step 8 and 9
+##############
-# page = hr.Html()
+page = hr.Html()
-# head = hr.Head()
-# head.append( hr.Meta(charset="UTF-8") )
-# head.append(hr.Title("PythonClass = Revision 1087:"))
+head = hr.Head()
+head.append( hr.Meta(charset="UTF-8") )
+head.append(hr.Title("PythonClass = Revision 1087:"))
-# page.append(head)
+page.append(head)
-# body = hr.Body()
+body = hr.Body()
-# body.append( hr.H(2, "PythonClass - Example") )
+body.append( hr.H(2, "PythonClass - Example") )
-# body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
-# "but this is enough to show that we can do some text",
-# style="text-align: center; font-style: oblique;"))
+body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+ "but this is enough to show that we can do some text",
+ style="text-align: center; font-style: oblique;"))
-# body.append(hr.Hr())
+body.append(hr.Hr())
-# list = hr.Ul(id="TheList", style="line-height:200%")
+list = hr.Ul(id="TheList", style="line-height:200%")
-# list.append( hr.Li("The first item in a list") )
-# list.append( hr.Li("This is the second item", style="color: red") )
+list.append( hr.Li("The first item in a list") )
+list.append( hr.Li("This is the second item", style="color: red") )
-# item = hr.Li()
-# item.append("And this is a ")
-# item.append( hr.A("http://google.com/", "link") )
-# item.append("to google")
+item = hr.Li()
+item.append("And this is a ")
+item.append( hr.A("http://google.com/", "link") )
+item.append("to google")
-# list.append(item)
+list.append(item)
-# body.append(list)
+body.append(list)
-# page.append(body)
+page.append(body)
-# render_page(page, "test_html_output8.html")
+render_page(page, "test_html_output8.html")
diff --git a/students/mjchang/session07/test_html_render.py b/students/mjchang/session07/test_html_render.py
index 9566f211..3dc0ae16 100644
--- a/students/mjchang/session07/test_html_render.py
+++ b/students/mjchang/session07/test_html_render.py
@@ -277,14 +277,14 @@ def test_anchor():
#######
def test_list():
- e = List("The first item is a list")
+ e = Li("The first item is a list")
# print(file_contents)
file_contents = render_result(e).strip()
print(file_contents)
assert ("The first item is a list") in file_contents
assert file_contents.startswith("")
- e2 = List("This is the second item", style="color: red")
+ e2 = Li("This is the second item", style="color: red")
file_contents = render_result(e2).strip()
print(file_contents)
assert ("This is the second item") in file_contents
@@ -308,83 +308,109 @@ def test_header():
assert ("PythonClass - Class 6 example") in file_contents
-#####################
+#######
+# Step 8
+#######
+
+def test_doctype():
+ e = Html("this is some text")
+ e.append("and this is some more text")
+
+ file_contents = render_result(e).strip()
+
+ assert("this is some text") in file_contents
+ assert("and this is some more text") in file_contents
+ print(file_contents)
+ assert("") in file_contents
+ assert file_contents.endswith("