From daa83fc207a66c83d01128ee0e09c84de3c25ada Mon Sep 17 00:00:00 2001 From: A D Date: Wed, 16 Jan 2019 18:15:02 -0800 Subject: [PATCH 01/12] adding test file --- students/aaron/testfile.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 students/aaron/testfile.txt diff --git a/students/aaron/testfile.txt b/students/aaron/testfile.txt new file mode 100644 index 0000000..9daeafb --- /dev/null +++ b/students/aaron/testfile.txt @@ -0,0 +1 @@ +test From 887fe5b97122c204665edb22675e152136fc717f Mon Sep 17 00:00:00 2001 From: A D Date: Wed, 16 Jan 2019 18:36:18 -0800 Subject: [PATCH 02/12] Adding lesson1 (session1) homework files --- students/aaron/README.md | 9 +++++++++ students/aaron/homework_lesson1/break_me.py | 18 ++++++++++++++++++ .../lesson1_task2_exercise1.py | 9 +++++++++ .../lesson1_task2_exercise2.py | 9 +++++++++ .../lesson1_task2_exercise3.py | 10 ++++++++++ 5 files changed, 55 insertions(+) create mode 100644 students/aaron/README.md create mode 100644 students/aaron/homework_lesson1/break_me.py create mode 100644 students/aaron/homework_lesson1/lesson1_task2_exercise1.py create mode 100644 students/aaron/homework_lesson1/lesson1_task2_exercise2.py create mode 100644 students/aaron/homework_lesson1/lesson1_task2_exercise3.py diff --git a/students/aaron/README.md b/students/aaron/README.md new file mode 100644 index 0000000..0337c5e --- /dev/null +++ b/students/aaron/README.md @@ -0,0 +1,9 @@ +# Readme for Student Aaron + +This is a readme file. + +I wrote it in an editor. + +It's not as long as a mile. + +Shorter is bett...itdor? diff --git a/students/aaron/homework_lesson1/break_me.py b/students/aaron/homework_lesson1/break_me.py new file mode 100644 index 0000000..d126124 --- /dev/null +++ b/students/aaron/homework_lesson1/break_me.py @@ -0,0 +1,18 @@ +#--------------------------------- +# Title: Explore Errors (Task 1) +# Change Log: +# Aaron Devey,2018-01-12,Created +#--------------------------------- + + +def NameError(): + raise NameError + +def TypeError(): + raise TypeError + +def SyntaxError(): + raise SyntaxError + +def AttributeError(): + raise AttributeError diff --git a/students/aaron/homework_lesson1/lesson1_task2_exercise1.py b/students/aaron/homework_lesson1/lesson1_task2_exercise1.py new file mode 100644 index 0000000..d2edcba --- /dev/null +++ b/students/aaron/homework_lesson1/lesson1_task2_exercise1.py @@ -0,0 +1,9 @@ +#----------------------- +# Title: Lesson 1, Task 2, Exercise 1 (Codingbat Warmup-1: sleep_in) +# Changelog +# Aaron Devey,2018-09-12,New file +#----------------------- + +def sleep_in(weekday, vacation): + return ( not weekday ) or vacation + diff --git a/students/aaron/homework_lesson1/lesson1_task2_exercise2.py b/students/aaron/homework_lesson1/lesson1_task2_exercise2.py new file mode 100644 index 0000000..00c8d9e --- /dev/null +++ b/students/aaron/homework_lesson1/lesson1_task2_exercise2.py @@ -0,0 +1,9 @@ +#-------------------- +# Title: Lesson 1, Task 2, Exercise 2 (Codingbat Warmup-1: monkey_trouble) +# Changelog: +# Aaron Devey,2019-01-12,New File +#--------------------- + +def monkey_trouble(a_smile, b_smile): + # using xor since it fits well here + return not (a_smile ^ b_smile) diff --git a/students/aaron/homework_lesson1/lesson1_task2_exercise3.py b/students/aaron/homework_lesson1/lesson1_task2_exercise3.py new file mode 100644 index 0000000..82f52cc --- /dev/null +++ b/students/aaron/homework_lesson1/lesson1_task2_exercise3.py @@ -0,0 +1,10 @@ +#---------------------- +# Title: Lesson 1, Task2, Exercise 3 (Codingbat Warmup-1: sum_double) +# Changelog: +# Aaron Devey,2019-01-12,new file +#---------------------- + +def sum_double(a, b): + if a == b: + return (a+b) * 2 + return (a+b) From 8f85aaad3b2526084dac89fb64aaa54c56066a96 Mon Sep 17 00:00:00 2001 From: A D Date: Sun, 20 Jan 2019 18:36:39 -0800 Subject: [PATCH 03/12] Adding homework exercises from lesson 2 --- students/aaron/homework_lesson2/fizzbuzz.py | 26 ++++++ .../aaron/homework_lesson2/grid_printer.py | 62 ++++++++++++++ students/aaron/homework_lesson2/pushup4.py | 10 +++ students/aaron/homework_lesson2/pushup5.py | 10 +++ students/aaron/homework_lesson2/pushup6.py | 12 +++ students/aaron/homework_lesson2/series.py | 80 +++++++++++++++++++ 6 files changed, 200 insertions(+) create mode 100644 students/aaron/homework_lesson2/fizzbuzz.py create mode 100644 students/aaron/homework_lesson2/grid_printer.py create mode 100644 students/aaron/homework_lesson2/pushup4.py create mode 100644 students/aaron/homework_lesson2/pushup5.py create mode 100644 students/aaron/homework_lesson2/pushup6.py create mode 100644 students/aaron/homework_lesson2/series.py diff --git a/students/aaron/homework_lesson2/fizzbuzz.py b/students/aaron/homework_lesson2/fizzbuzz.py new file mode 100644 index 0000000..bbc9957 --- /dev/null +++ b/students/aaron/homework_lesson2/fizzbuzz.py @@ -0,0 +1,26 @@ +#----------------------------------# +# Title: Fizz Buzz (from lesson 2) +# Changelog: +# Aaron Devey,2019-01-20,Created +#----------------------------------# + + +''' + fizzbuzz(n): return a number (as a str), or return Fizz, or Buzz, or FizzBuzz for multiples of 3, 5, or 15 respectively. + n: the number to return + returns: string +''' +def fizzbuzz(n): + if n % 15 == 0: + return("FizzBuzz") + if n % 5 == 0: + return("Buzz") + if n % 3 == 0: + return("Fizz") + return(str(n)) + + +''' The instructions specifically want 1 through 100, so range(1, 101) is exactly that. ''' +for n in range(1, 101): + print(fizzbuzz(n)) + diff --git a/students/aaron/homework_lesson2/grid_printer.py b/students/aaron/homework_lesson2/grid_printer.py new file mode 100644 index 0000000..370aab4 --- /dev/null +++ b/students/aaron/homework_lesson2/grid_printer.py @@ -0,0 +1,62 @@ +#--------------------------------- +# Title: grid_printer (from lesson 2) +# Changelog: +# Aaron Devey,2019-01-20,Created +#--------------------------------- + +''' Note: The definition of the side of a cell is re-defined in a different + way 3 separate times in this assignment. Since it's not consistent, + just trying to make a good approximation of what they're looking for + here based on part 3. +''' + +# prints a seperator or bottom/top row +def print_seperator(cells, size): + line = "" + for i in range(cells): + line += "+" + " -" * size + " " + line += "+" + print(line) + +# prints a line that forms a cell +def print_line(cells, size): + line = "" + for i in range(cells): + line += "|" + " " * size + " " + line += "|" + print(line) + +# from part2, prints a 2x2 grid with cells of "size" +def print_grid(size): + for height in range(2): + print_seperator(2, size) + for lines in range(size): + print_line(2, size) + print_seperator(2, size) + +# from part3, prints a grid of (cells)*(cells) and each cell sized at "size" +def print_grid2(cells, size): + for height in range(cells): + print_seperator(cells, size) + for i in range(size): + print_line(cells, size) + print_seperator(cells, size) + +# from part1, prints a static grid +def static_grid(): + print('''+ - - - - + - - - - + +| | | +| | | +| | | +| | | ++ - - - - + - - - - + +| | | +| | | +| | | +| | | ++ - - - - + - - - - +''') + +static_grid() +print_grid(3) +print_grid(15) +print_grid2(5, 3) diff --git a/students/aaron/homework_lesson2/pushup4.py b/students/aaron/homework_lesson2/pushup4.py new file mode 100644 index 0000000..abbd450 --- /dev/null +++ b/students/aaron/homework_lesson2/pushup4.py @@ -0,0 +1,10 @@ +#-------------------------------- +# Title: diff21 (from python pushups 2 of 2) +# Changelog: +# Aaron Devey,2019-01-20,Created +#-------------------------------- + +def diff21(n): + if n > 21: + return((n - 21) * 2) + return(abs(n - 21)) diff --git a/students/aaron/homework_lesson2/pushup5.py b/students/aaron/homework_lesson2/pushup5.py new file mode 100644 index 0000000..c5442db --- /dev/null +++ b/students/aaron/homework_lesson2/pushup5.py @@ -0,0 +1,10 @@ +#-------------------------------- +# Title: parrot_trouble (from python pushups 2 of 2) +# Changelog: +# Aaron Devey,2019-01-20,Created +#-------------------------------- + +def parrot_trouble(talking, hour): + if talking and (hour > 20 or hour < 7): + return True + return False diff --git a/students/aaron/homework_lesson2/pushup6.py b/students/aaron/homework_lesson2/pushup6.py new file mode 100644 index 0000000..c24960a --- /dev/null +++ b/students/aaron/homework_lesson2/pushup6.py @@ -0,0 +1,12 @@ +#-------------------------------- +# Title: makes10 (from python pushups 2 of 2) +# Changelog: +# Aaron Devey,2019-01-20,Created +#-------------------------------- + +def makes10(a, b): + if a + b == 10: + return True + if a == 10 or b == 10: + return True + return False diff --git a/students/aaron/homework_lesson2/series.py b/students/aaron/homework_lesson2/series.py new file mode 100644 index 0000000..6acac8f --- /dev/null +++ b/students/aaron/homework_lesson2/series.py @@ -0,0 +1,80 @@ +#-----------------------------------# +# Title: series.py (from lesson 2) +# Changelog: +# Aaron Devey,2019-01-20,Created +#-----------------------------------# +''' + note: For each function I used a cache, for fun. I was noticing + that a large number of the recursive calls run multiple times, + and that the functions could be made more efficient with a cache. +''' + + +''' + fibonacci(n): calculate the Nth index of the fibonacci sequence + n: the desired index of the fibonacci squence + returns: int +''' +fibCache = {0: 0, 1: 1} +def fibonacci(n): + if n in fibCache: + return fibCache[n] + fibCache[n] = fibonacci(n - 1) + fibonacci(n - 2) + return fibCache[n] + +''' + lucas(n): calculate the Nth index of the lucas sequence + n: the desired index of the lucas squence + returns: int +''' +lucasCache = {0: 2, 1: 1} +def lucas(n): + if n in lucasCache: + return lucasCache[n] + lucasCache[n] = lucas(n - 1) + lucas(n - 2) + return lucasCache[n] + +''' + sum_series(n, [n0, [n1]]): calculate the Nth index of the fibonacci-like sequence + n: the desired index of the series + n0: the pre-defined index at 0 + n1: the pre-defined index at 1 + returns: int + note: defaults to the fibonacci sequence +''' +cache = {0: 0, 1: 1} +def sum_series(n, n0=0, n1=1): + # reset the cache if the starting values differ + if cache[0] != n0 or cache[1] != n1: + cache.clear() + cache[0] = n0 + cache[1] = n1 + if n in cache: + return cache[n] + cache[n] = sum_series(n - 1, n0, n1) + sum_series(n - 2, n0, n1) + return cache[n] + + +# tests +if __name__ == "__main__": + # run some tests + assert fibonacci(0) == 0 + assert fibonacci(1) == 1 + assert fibonacci(2) == 1 + assert fibonacci(3) == 2 + assert fibonacci(4) == 3 + assert fibonacci(5) == 5 + assert fibonacci(6) == 8 + assert fibonacci(7) == 13 + + assert lucas(0) == 2 + assert lucas(1) == 1 + + assert lucas(4) == 7 + + assert sum_series(5) == fibonacci(5) + + # test if sum_series matched lucas + assert sum_series(5, 2, 1) == lucas(5) + + print("tests passed") From db6de4aa9573a1ac63353fafd975c2d010d71fbf Mon Sep 17 00:00:00 2001 From: A D Date: Tue, 29 Jan 2019 16:44:28 -0800 Subject: [PATCH 04/12] Adding homework from lesson 3 --- students/aaron/homework_lesson3/list_lab.py | 62 +++++++++++++ students/aaron/homework_lesson3/mailroom.py | 90 +++++++++++++++++++ students/aaron/homework_lesson3/slicing.py | 48 ++++++++++ .../aaron/homework_lesson3/strformat_lab.py | 44 +++++++++ 4 files changed, 244 insertions(+) create mode 100755 students/aaron/homework_lesson3/list_lab.py create mode 100755 students/aaron/homework_lesson3/mailroom.py create mode 100644 students/aaron/homework_lesson3/slicing.py create mode 100755 students/aaron/homework_lesson3/strformat_lab.py diff --git a/students/aaron/homework_lesson3/list_lab.py b/students/aaron/homework_lesson3/list_lab.py new file mode 100755 index 0000000..bc02401 --- /dev/null +++ b/students/aaron/homework_lesson3/list_lab.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 + +#--------------------------------- +# Title: List Lab (from lesson 3 homework) +# Changelog: +# Aaron Devey,2019-01-29,Created +#--------------------------------- + + +# Series 1 +originalFruits = ["Apples", "Pears", "Oranges", "Peaches"] +fruits = originalFruits.copy() +print(fruits) +fruits = fruits + [input("Enter a new fruit: ")] +print(fruits) +index = input("Enter a fruit number (1 indexed): ") +print("You entered: " + fruits[int(index) - 1]) +fruits = ["Bananas"] + fruits +print(fruits) +fruits.insert(0, "Honeydew") +print(fruits) +for fruit in fruits: + if fruit[0] == "P": + print(fruit) + +# Series 2 +print(fruits) +fruits = fruits[:-1] +print(fruits) +deleted = False + +## bonus: multiply list * 2 and keep asking. +## using a copy here or it messes up Series 3. +fruitsCopy = fruits.copy() +while not deleted: + fruitsCopy = fruitsCopy + fruitsCopy + toDelete = input("Enter a fruit to delete: ").lower() + for fruit in fruitsCopy: + if fruit.lower() == toDelete: + deleted = True + fruitsCopy.remove(fruit) + +# Series 3 +for fruit in fruits.copy(): + like = "maybe" + while like != "yes" and like != "no": + like = input("Do you like " + fruit.lower() + "? ").lower() + if like == "no": + fruits.remove(fruit) + elif like != "yes": + print("This is a yes or no question, try again.") + +print(fruits) + +# Series 4 +newFruits = [] +for fruit in originalFruits: + newFruits += [fruit[::-1]] + +newFruits = newFruits[:-1] +print("Original: " + str(originalFruits)) +print("Copy: " + str(newFruits)) diff --git a/students/aaron/homework_lesson3/mailroom.py b/students/aaron/homework_lesson3/mailroom.py new file mode 100755 index 0000000..81f7b64 --- /dev/null +++ b/students/aaron/homework_lesson3/mailroom.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 + +donors = {'Bob Barker': {'donations': 2, 'total': 24456.24}, + 'Roger Rabbit': {'donations': 1, 'total': 4930.26}, + 'Bruce Lee': {'donations': 3, 'total': 52246.75}, + 'Frodo Baggins': {'donations': 1, 'total': 1249.44}, + 'Kermit the Frog': {'donations': 2, 'total': 23475.20}} + +# prints a main menu +def show_main_menu(): + print("-------------------") + print("1. Send a Thank You") + print("2. Create a Report") + print("3. Quit") + +# gets a menu selection +def get_main_selection(): + user_in = "" + while user_in == "": + show_main_menu() + user_in = input("Enter a menu number: ") + if user_in != "1" and user_in != "2" and user_in != "3": + print("Invalid selection. Enter a menu selection. 1, 2, or 3.") + user_in = "" + return user_in + +# logic for inputting a new donation +def send_thankyou(): + user_in = "" + names = list(donors.keys()) + while user_in == "": + print("----------------------------------------------------------------") + user_in = input("Enter a full name or type 'list' for a list of names: ") + if user_in == 'list': + print("Donors: ") + for name in names: + print(" " + name) + user_in = "" + elif user_in not in names: + donors[user_in] = {'donations': 0, 'total': 0} + amount = float(input("Enter a donation amount: ")) + donors[user_in]['donations'] += 1 + donors[user_in]['total'] += amount + output_thankyou(user_in, amount) + +# print a report +def output_report(): + table_headerfmt = "{:<19s}|{:>15s} |{:>14s} |{:>15s}" + table_formatter = "{:<19s} ${:13.2f} {:14d} ${:13.2f}" + table_seperator = "-" * 68 + print(table_headerfmt.format("Donor Name", "Total Given", "Num Gifts", "Average Gift")) + print(table_seperator) + + # unpack to a list of lists + donor_list = [] + for donor in donors: + donor_list.insert(0, [donor, donors[donor]['donations'], donors[donor]['total']]) + + # sort the list + donor_list = sorted(donor_list, key = lambda x: x[2] * -1) + + # print the list + for donor in donor_list: + print(table_formatter.format(donor[0], donor[2], donor[1], donor[2] / donor[1])) + +# print a thank you note for a new donation +def output_thankyou(donor_name, latest_amount): + print("-" * 70) + print("From: Me ") + print(f'To: {donor_name} ') + print("Subject: Thank you.") + print("") + print(f'Dear {donor_name},') + print(f' Thank you for your generous donation of {latest_amount:.2f}!') + print(f'That brings your total of {donors[donor_name]["donations"]} donation(s) to ${donors[donor_name]["total"]:.2f}') + print("Sincerely,") + print(" -Me") + +# the main loop +def main(): + selection = "" + while selection != "3": + selection = get_main_selection() + if selection == "1": + send_thankyou() + elif selection == "2": + output_report() + +if __name__ == '__main__': + main() diff --git a/students/aaron/homework_lesson3/slicing.py b/students/aaron/homework_lesson3/slicing.py new file mode 100644 index 0000000..2acacb0 --- /dev/null +++ b/students/aaron/homework_lesson3/slicing.py @@ -0,0 +1,48 @@ +#----------------------------------- +# Title: Slicing (from lesson 3) +# Changelog: +# Aaron Devey,2019-01-28,Created +#----------------------------------- + +# exchanges the first and last item of a sequence +def exchange_first_last(seq): + return seq[-1:] + seq[1:-1] + seq[0:1] + +# removes every other item of a sequence +def remove_every_other_item(seq): + return seq[0::2] + +# removes the first four and last four items of a sequence +# and then returns every other item in between +def remove_first_last_four(seq): + return seq[4:-4:2] + +# reverses a sequence +def reverse(seq): + return seq[::-1] + +# splits a sequence into thirds and re-orders the thirds +def reorder_by_thirds(seq): + return seq[int((len(seq) / 3) * 2):] + seq[:int(len(seq) / 3)] + seq[int(len(seq) / 3):int(len(seq) / 3 * -1)] + + +# tests +test_string = "This is a test string" +test_tuple = (99, 98, 1, 2, 0, "zero", 7, 23, 24, 5) + +assert exchange_first_last(test_string) == "ghis is a test strinT" +assert exchange_first_last(test_tuple) == (5, 98, 1, 2, 0, "zero", 7, 23, 24, 99) + +assert remove_every_other_item(test_string) == "Ti sats tig" +assert remove_every_other_item(test_tuple) == (99, 1, 0, 7, 24) + +assert remove_first_last_four(test_string) == " sats t" +assert remove_first_last_four(test_tuple) == (0,) + +assert reverse(test_string) == "gnirts tset a si sihT" +assert reverse(test_tuple) == (5, 24, 23, 7, "zero", 0, 2, 1, 98, 99) + +assert reorder_by_thirds(test_string) == " stringThis is a test" +assert reorder_by_thirds(test_tuple) == (7, 23, 24, 5, 99, 98, 1, 2, 0, 'zero', 7) + +print("Tests passed") diff --git a/students/aaron/homework_lesson3/strformat_lab.py b/students/aaron/homework_lesson3/strformat_lab.py new file mode 100755 index 0000000..50fd604 --- /dev/null +++ b/students/aaron/homework_lesson3/strformat_lab.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 + +#----------------------------------- +# Title: String Formatting Lab (from lesson 3) +# Changelog: +# Aaron Devey,2019-01-28,Created +#----------------------------------- + +# task 1 +tuple = (2, 123.4567, 10000, 12345.67) +formatStr = "file_{:03d} : {:.2f}, {:.2e}, {:3.2e}" +print(formatStr.format(tuple[0], tuple[1], tuple[2], tuple[3])) + +# task 2 +formatStr = "file_0{:02d} : {:.2f}, {:.2e}, {:3.2e}" +print(formatStr.format(*tuple)) + +# task 3 +def formatter(in_tuple): + form_string = "the " + str(len(in_tuple)) + " numbers are: {:d}" + form_string += ", {:d}" * (len(in_tuple) - 1) + return form_string.format(*in_tuple) + +print(formatter((1, 2, 3, 4, 5, 6, 7, 8))) + +# task 4 +tuple = ( 4, 30, 2017, 2, 27) +print("{3:02d} {4:02d} {2:02d} {0:02d} {1:02d}".format(*tuple)) + +# task 5 +list = ['oranges', 1.3, 'lemons', 1.1] +print(f'The weight of an {list[0][:-1]} is {list[1]} and the weight of a {list[2][:-1]} is {list[3]}') +print(f'The weight of an {list[0][:-1].upper()} is {list[1] * 1.2} and the weight of a {list[2][:-1].upper()} is {list[3] * 1.2}') + +# task 6 +input = [['Name', 'Age', 'Cost'], + ['Honda', '2 years', '$12345.45'], + ['BMW', '5 years', '$9844.11'], + ['Pontiac', '24 years', '$899.42'], + ['Mercedes', '8 years', '$22402.84']] + +str = "{:10s} {:10s} {:10s}" +for row in input: + print(str.format(*row)) From 3def4c907d5799b5b046f6e649e2000984fe9df7 Mon Sep 17 00:00:00 2001 From: Aaron D Date: Tue, 5 Feb 2019 02:05:26 -0800 Subject: [PATCH 05/12] Adding kata14_trigrams.py from lesson 4 --- .../aaron/homework_lesson4/kata14_trigrams.py | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 students/aaron/homework_lesson4/kata14_trigrams.py diff --git a/students/aaron/homework_lesson4/kata14_trigrams.py b/students/aaron/homework_lesson4/kata14_trigrams.py new file mode 100644 index 0000000..b250603 --- /dev/null +++ b/students/aaron/homework_lesson4/kata14_trigrams.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 + +#-------------------------------------------- +# Title: kata 14, trigrams (from lesson 4) +# Changelog: +# 2019-02-04,Aaron Devey,Created +#-------------------------------------------- + +import re +import random + +trigrams = {} + +def ingest_file(filename): + f = open(filename, "r") + contents = f.read() + sentences = re.split(r'[.?!;]+', contents) + for sentence in sentences: + process_sentence(sentence) + +def process_sentence(sentence): + words = re.split(r'\s+', sentence) + counter = 0 + while len(words[counter:counter+3]) == 3: + process_trigram(words[counter:counter+3]) + counter += 1 + +def process_trigram(trigram): + tup = tuple(trigram[0:2]) + word = trigram[2:3] + if tup in trigrams: + trigrams[tup] += word + else: + trigrams[tup] = word + +def pick_next_word(pair): + if pair in trigrams: + choices = trigrams[pair] + return(random.choice(choices)) + return(None) + +def generate_sentence(): + start_words = list(random.choice(list(trigrams.keys()))) + sentence = start_words[0] + " " + start_words[1] + next_word = pick_next_word(tuple(start_words)) + previous_words = start_words + while next_word != None: + sentence = sentence + " " + next_word + previous_words = [previous_words[1], next_word] + next_word = pick_next_word(tuple(previous_words)) + return(sentence.capitalize()) + +def main(): + i = None + while i != "3": + print("-" * 70) + print("Choose:") + print("1. Ingest a text file") + print("2. Generate a sentence") + print("3. Quit") + i = input("Enter a choice, 1,2,3: ") + if i == "1": + file = input("Enter a filename: ") + print("Ingesting file: " + file) + ingest_file(file) + print("Ingest complete.") + elif i == "2": + print("Here is your sentence: " + generate_sentence()) + elif i == "3": + print("Ok, goodbye!") + else: + print("Sorry, '" + i + "' is not a valid selection.") + +if __name__ == "__main__": + main() From dc197455c98fb419cec37f3e5d7a15e95baeba29 Mon Sep 17 00:00:00 2001 From: Aaron D Date: Tue, 5 Feb 2019 02:29:32 -0800 Subject: [PATCH 06/12] Adding comments to the trigrams homework --- students/aaron/homework_lesson4/kata14_trigrams.py | 6 ++++++ 1 file changed, 6 insertions(+) mode change 100644 => 100755 students/aaron/homework_lesson4/kata14_trigrams.py diff --git a/students/aaron/homework_lesson4/kata14_trigrams.py b/students/aaron/homework_lesson4/kata14_trigrams.py old mode 100644 new mode 100755 index b250603..464056d --- a/students/aaron/homework_lesson4/kata14_trigrams.py +++ b/students/aaron/homework_lesson4/kata14_trigrams.py @@ -11,6 +11,7 @@ trigrams = {} +# reads a file and parses sentences def ingest_file(filename): f = open(filename, "r") contents = f.read() @@ -18,6 +19,7 @@ def ingest_file(filename): for sentence in sentences: process_sentence(sentence) +# parses a sentence into trigrams def process_sentence(sentence): words = re.split(r'\s+', sentence) counter = 0 @@ -25,6 +27,7 @@ def process_sentence(sentence): process_trigram(words[counter:counter+3]) counter += 1 +# adds a trigram to the trigram dict def process_trigram(trigram): tup = tuple(trigram[0:2]) word = trigram[2:3] @@ -33,12 +36,14 @@ def process_trigram(trigram): else: trigrams[tup] = word +# picks a random next word based on the tuple pair provided def pick_next_word(pair): if pair in trigrams: choices = trigrams[pair] return(random.choice(choices)) return(None) +# generates an entire sentence randomly using trigrams def generate_sentence(): start_words = list(random.choice(list(trigrams.keys()))) sentence = start_words[0] + " " + start_words[1] @@ -50,6 +55,7 @@ def generate_sentence(): next_word = pick_next_word(tuple(previous_words)) return(sentence.capitalize()) +# presents a menu and processes user input def main(): i = None while i != "3": From a33a5f8f86a6e34946a350c247605b3dc7cb416b Mon Sep 17 00:00:00 2001 From: Aaron D Date: Tue, 5 Feb 2019 02:38:14 -0800 Subject: [PATCH 07/12] Adding first draft of mailroom_v2.py --- .../aaron/homework_lesson4/mailroom_v2.py | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100755 students/aaron/homework_lesson4/mailroom_v2.py diff --git a/students/aaron/homework_lesson4/mailroom_v2.py b/students/aaron/homework_lesson4/mailroom_v2.py new file mode 100755 index 0000000..2351000 --- /dev/null +++ b/students/aaron/homework_lesson4/mailroom_v2.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python3 + +donors = {'Bob Barker': {'donations': 2, 'total': 24456.24}, + 'Roger Rabbit': {'donations': 1, 'total': 4930.26}, + 'Bruce Lee': {'donations': 3, 'total': 52246.75}, + 'Frodo Baggins': {'donations': 1, 'total': 1249.44}, + 'Kermit the Frog': {'donations': 2, 'total': 23475.20}} + +# prints a main menu +def show_main_menu(): + print("-------------------") + print("1. Send a Thank You") + print("2. Create a Report") + print("3. Quit") + +menu_opts = {'1': send_thankyou, '2': output_report, '3': quit} + +# gets a menu selection +def get_main_selection(): + user_in = "" + while user_in == "": + show_main_menu() + user_in = input("Enter a menu number: ") + if user_in not in menu_opts.keys(): + print("Invalid selection. Enter a menu selection:", list(menu_opts.keys())) + user_in = "" + return user_in + +# logic for inputting a new donation +def send_thankyou(): + user_in = "" + names = list(donors.keys()) + while user_in == "": + print("----------------------------------------------------------------") + user_in = input("Enter a full name or type 'list' for a list of names: ") + if user_in == 'list': + print("Donors: ") + for name in names: + print(" " + name) + user_in = "" + elif user_in not in names: + donors[user_in] = {'donations': 0, 'total': 0} + amount = float(input("Enter a donation amount: ")) + donors[user_in]['donations'] += 1 + donors[user_in]['total'] += amount + output_thankyou(user_in, amount) + +# print a report +def output_report(): + table_headerfmt = "{:<19s}|{:>15s} |{:>14s} |{:>15s}" + table_formatter = "{:<19s} ${:13.2f} {:14d} ${:13.2f}" + table_seperator = "-" * 68 + print(table_headerfmt.format("Donor Name", "Total Given", "Num Gifts", "Average Gift")) + print(table_seperator) + + # unpack to a list of lists + donor_list = [] + for donor in donors: + donor_list.insert(0, [donor, donors[donor]['donations'], donors[donor]['total']]) + + # sort the list + donor_list = sorted(donor_list, key = lambda x: x[2] * -1) + + # print the list + for donor in donor_list: + print(table_formatter.format(donor[0], donor[2], donor[1], donor[2] / donor[1])) + +# print a thank you note for a new donation +def output_thankyou(donor_name, latest_amount): + print("-" * 70) + print("From: Me ") + print(f'To: {donor_name} ') + print("Subject: Thank you.") + print("") + print(f'Dear {donor_name},') + print(f' Thank you for your generous donation of {latest_amount:.2f}!') + print(f'That brings your total of {donors[donor_name]["donations"]} donation(s) to ${donors[donor_name]["total"]:.2f}') + print("Sincerely,") + print(" -Me") + +# the main loop +def main(): + selection = "" + while selection != "3": + selection = get_main_selection() + menu_opts[selection]() + +if __name__ == '__main__': + main() From ecbf9f4d28f8522efac6ac4e1f6780126d9e528d Mon Sep 17 00:00:00 2001 From: A D Date: Tue, 5 Feb 2019 16:04:38 -0800 Subject: [PATCH 08/12] Updating mailroom_v2.py to complete the assignment --- .../aaron/homework_lesson4/mailroom_v2.py | 77 ++++++++++++++----- 1 file changed, 58 insertions(+), 19 deletions(-) diff --git a/students/aaron/homework_lesson4/mailroom_v2.py b/students/aaron/homework_lesson4/mailroom_v2.py index 2351000..fd03d2a 100755 --- a/students/aaron/homework_lesson4/mailroom_v2.py +++ b/students/aaron/homework_lesson4/mailroom_v2.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +import re + donors = {'Bob Barker': {'donations': 2, 'total': 24456.24}, 'Roger Rabbit': {'donations': 1, 'total': 4930.26}, 'Bruce Lee': {'donations': 3, 'total': 52246.75}, @@ -8,12 +10,9 @@ # prints a main menu def show_main_menu(): - print("-------------------") - print("1. Send a Thank You") - print("2. Create a Report") - print("3. Quit") - -menu_opts = {'1': send_thankyou, '2': output_report, '3': quit} + print("-" * 70) + for number, func in menu_opts.items(): + print(f'{number}. {menu_opts_text[func]}') # gets a menu selection def get_main_selection(): @@ -65,25 +64,65 @@ def output_report(): for donor in donor_list: print(table_formatter.format(donor[0], donor[2], donor[1], donor[2] / donor[1])) -# print a thank you note for a new donation +# print a thank you for a recent donation def output_thankyou(donor_name, latest_amount): - print("-" * 70) - print("From: Me ") - print(f'To: {donor_name} ') - print("Subject: Thank you.") - print("") - print(f'Dear {donor_name},') - print(f' Thank you for your generous donation of {latest_amount:.2f}!') - print(f'That brings your total of {donors[donor_name]["donations"]} donation(s) to ${donors[donor_name]["total"]:.2f}') - print("Sincerely,") - print(" -Me") + print(generate_thankyou(donor_name, latest_amount, True)) + +# write a thank you note to disk for a donor +def write_letters(): + for donor_name in donors.keys(): + # convert any non-alphanumeric characters to _ for the filename + donor_file = re.sub(r"[^a-zA-Z0-9_-]+", "_", donor_name) + ".txt" + + note = generate_thankyou(donor_name) + f = open(donor_file, 'w') + f.write(note) + f.close() + print(f'>>> Wrote thank you note for {donor_name} to {donor_file}') + +# generate a thank you note for a donor +def generate_thankyou(donor_name, latest_amount=0, recent=False): + donations_total = donors[donor_name]["total"] + donations_count = donors[donor_name]["donations"] + format_values = {'donations_total': donations_total, + 'donations_count': donations_count, + 'donor_name': donor_name, + 'latest_amount': latest_amount} + if recent: + template = '''---------------------------------------------------------------------- +Dear {donor_name}, + Thank you for your generous donation of {latest_amount:.2f}! +That brings your total of {donations_count} donation(s) to ${donations_total:.2f} +Sincerely, + -Me +''' + else: + template = '''---------------------------------------------------------------------- +Dear {donor_name}, + Thank you for all {donations_count} of your generous donations for a total of {donations_total:.2f}! +We will put the money to good use. +Sincerely, + -Me +''' + letter = template.format(**format_values) + return(letter) # the main loop def main(): - selection = "" - while selection != "3": + selection = "2" + while menu_opts[selection] != quit: selection = get_main_selection() menu_opts[selection]() +# a dict for mapping user selection to functions +menu_opts = {'1': send_thankyou, + '2': output_report, + '3': write_letters, + '4': quit} +menu_opts_text = {send_thankyou: "Send a Thank You to a single donor.", + output_report: "Create a report.", + write_letters: "Send letters to all donors.", + quit: "Quit."} + if __name__ == '__main__': main() From 5a6be3a7dc518fd9b5e995345d2cfa6a4e77932e Mon Sep 17 00:00:00 2001 From: Aaron D Date: Tue, 12 Feb 2019 17:22:07 -0800 Subject: [PATCH 09/12] Updating mailroom_v3 with an exception handler and another comprehension --- .../aaron/homework_lesson5/mailroom_v3.py | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100755 students/aaron/homework_lesson5/mailroom_v3.py diff --git a/students/aaron/homework_lesson5/mailroom_v3.py b/students/aaron/homework_lesson5/mailroom_v3.py new file mode 100755 index 0000000..f4696fa --- /dev/null +++ b/students/aaron/homework_lesson5/mailroom_v3.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python3 + +import re + +donors = {'bob barker': {'donations': 2, 'total': 24456.24, 'name': 'Bob Barker'}, + 'roger rabbit': {'donations': 1, 'total': 4930.26, 'name': 'Roger Rabbit'}, + 'bruce lee': {'donations': 3, 'total': 52246.75, 'name': 'Bruce Lee'}, + 'frodo baggins': {'donations': 1, 'total': 1249.44, 'name': 'Frodo Baggins'}, + 'kermit the frog': {'donations': 2, 'total': 23475.20, 'name': 'Kermit the Frogg'}} + +# prints a main menu +def show_main_menu(): + print("-" * 70) + for number, func in sorted(menu_opts.items()): + print('{}. {}'.format(number, menu_opts_text[func])) + +# gets a menu selection +def get_main_selection(): + user_in = "" + while user_in == "": + show_main_menu() + user_in = input("Enter a menu number: ") + if user_in not in menu_opts.keys(): + print("Invalid selection. Enter a menu selection:", list(menu_opts.keys())) + user_in = "" + return user_in + +# logic for inputting a new donation +def send_thankyou(): + user_in = "" + names = [n.lower() for n in list(donors.keys())] + while user_in == "": + print("----------------------------------------------------------------") + user_in = input("Enter a full name or type 'list' for a list of names: ") + user_lower = user_in.lower() + if user_lower == 'list': + print("Donors: ") + for name in names: + print(" " + name) + user_in = "" + elif user_lower not in names: + donors[user_lower] = {'donations': 0, 'total': 0, 'name': user_in} + amount = 0 + while amount == 0: + try: + amount = float(input("Enter a donation amount: ")) + except: + amount = 0 + print("-> ERROR: Please enter a valid floating point number.") + donors[user_lower]['donations'] += 1 + donors[user_lower]['total'] += amount + output_thankyou(user_in, amount) + +# print a report +def output_report(): + table_headerfmt = "{:<19s}|{:>15s} |{:>14s} |{:>15s}" + table_formatter = "{:<19s} ${:13.2f} {:14d} ${:13.2f}" + table_seperator = "-" * 68 + print(table_headerfmt.format("Donor Name", "Total Given", "Num Gifts", "Average Gift")) + print(table_seperator) + + # unpack to a list of lists + donor_list = [[donors[donor]['name'], donors[donor]['donations'], donors[donor]['total']] for donor in donors] + + # sort the list + donor_list = sorted(donor_list, key = lambda x: x[2] * -1) + + # print the list + for donor in donor_list: + print(table_formatter.format(donor[0], donor[2], donor[1], donor[2] / donor[1])) + +# print a thank you for a recent donation +def output_thankyou(donor_name, latest_amount): + print(generate_thankyou(donor_name, latest_amount, True)) + +# write a thank you note to disk for a donor +def write_letters(): + for donor_name in donors.keys(): + # convert any non-alphanumeric characters to _ for the filename + donor_file = re.sub(r"[^a-zA-Z0-9_-]+", "_", donor_name) + ".txt" + + note = generate_thankyou(donor_name) + f = open(donor_file, 'w') + f.write(note) + f.close() + print('>>> Wrote thank you note for {} to {}'.format(donor_name, donor_file)) + +# generate a thank you note for a donor +def generate_thankyou(donor_name, latest_amount=0, recent=False): + donations_total = donors[donor_name]["total"] + donations_count = donors[donor_name]["donations"] + format_values = {'donations_total': donations_total, + 'donations_count': donations_count, + 'donor_name': donor_name, + 'latest_amount': latest_amount} + if recent: + template = '''---------------------------------------------------------------------- +Dear {donor_name}, + Thank you for your generous donation of {latest_amount:.2f}! +That brings your total of {donations_count} donation(s) to ${donations_total:.2f} +Sincerely, + -Me +''' + else: + template = '''---------------------------------------------------------------------- +Dear {donor_name}, + Thank you for all {donations_count} of your generous donations for a total of {donations_total:.2f}! +We will put the money to good use. +Sincerely, + -Me +''' + letter = template.format(**format_values) + return(letter) + +# the main loop +def main(): + selection = "2" + while menu_opts[selection] != quit: + selection = get_main_selection() + menu_opts[selection]() + +# a dict for mapping user selection to functions +menu_opts = {'1': send_thankyou, + '2': output_report, + '3': write_letters, + '4': quit} +menu_opts_text = {send_thankyou: "Send a Thank You to a single donor.", + output_report: "Create a report.", + write_letters: "Send letters to all donors.", + quit: "Quit."} + +if __name__ == '__main__': + main() From b53e8e8c75c329deb4851c46238ab8f0599a4b82 Mon Sep 17 00:00:00 2001 From: A D Date: Tue, 12 Feb 2019 17:34:08 -0800 Subject: [PATCH 10/12] Adding the exceptions exercise --- .../aaron/homework_lesson5/except_exercise.py | 55 +++++++++++++++++++ .../aaron/homework_lesson5/except_test.py | 41 ++++++++++++++ 2 files changed, 96 insertions(+) create mode 100755 students/aaron/homework_lesson5/except_exercise.py create mode 100755 students/aaron/homework_lesson5/except_test.py diff --git a/students/aaron/homework_lesson5/except_exercise.py b/students/aaron/homework_lesson5/except_exercise.py new file mode 100755 index 0000000..0f9e245 --- /dev/null +++ b/students/aaron/homework_lesson5/except_exercise.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 + +""" +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 as e: + more_joke = more_fun(langs[1]) +else: + more_joke = more_fun(langs[2]) +finally: + last_fun() diff --git a/students/aaron/homework_lesson5/except_test.py b/students/aaron/homework_lesson5/except_test.py new file mode 100755 index 0000000..905dd67 --- /dev/null +++ b/students/aaron/homework_lesson5/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 9d4980c97e48c42c877d774fc767ccace3b31beb Mon Sep 17 00:00:00 2001 From: A D Date: Tue, 19 Feb 2019 17:44:11 -0800 Subject: [PATCH 11/12] Adding mailroom_v4 files from lesson 6 --- .../aaron/homework_lesson6/mailroom_v4.py | 178 ++++++++++++++++++ .../homework_lesson6/mailroom_v4_test.py | 123 ++++++++++++ 2 files changed, 301 insertions(+) create mode 100755 students/aaron/homework_lesson6/mailroom_v4.py create mode 100755 students/aaron/homework_lesson6/mailroom_v4_test.py diff --git a/students/aaron/homework_lesson6/mailroom_v4.py b/students/aaron/homework_lesson6/mailroom_v4.py new file mode 100755 index 0000000..9b213ce --- /dev/null +++ b/students/aaron/homework_lesson6/mailroom_v4.py @@ -0,0 +1,178 @@ +#!/usr/bin/env python3 + +#------------------------------------- +# Assignment: mailroom (version 4, from lesson 6) +# Changelog: +# 2019-02-19,Aaron Devey,Created +#------------------------------------- + +import re + +donors = {'bob barker': {'donations': 2, 'total': 24456.24, 'name': 'Bob Barker'}, + 'roger rabbit': {'donations': 1, 'total': 4930.26, 'name': 'Roger Rabbit'}, + 'bruce lee': {'donations': 3, 'total': 52246.75, 'name': 'Bruce Lee'}, + 'frodo baggins': {'donations': 1, 'total': 1249.44, 'name': 'Frodo Baggins'}, + 'kermit the frog': {'donations': 2, 'total': 23475.20, 'name': 'Kermit the Frogg'}} + +# prints a main menu +def show_main_menu(): + print(generate_main_menu()) + +# moving the actual menu text into a testable def +def generate_main_menu(): + menu = ("-" * 70) + "\n" + for number, func in sorted(menu_opts.items()): + menu += "{}. {}\n".format(number, menu_opts_text[func]) + return menu + +# gets a menu selection +def get_main_selection(): + user_in = "" + while user_in == "": + show_main_menu() + user_in = input("Enter a menu number: ") + if user_in not in menu_opts.keys(): + print("Invalid selection. Enter a menu selection:", list(menu_opts.keys())) + user_in = "" + return user_in + +# used for testing, returns the entire donors dict +def get_donors(): + return donors + +# logic for user-interaction of a new donation +# moved testable pieces into different defs +def send_thankyou(): + user_in = "" + names = [n.lower() for n in list(donors.keys())] + while user_in == "": + print("----------------------------------------------------------------") + user_in = input("Enter a full name or type 'list' for a list of names: ") + user_lower = user_in.lower() + if user_lower == 'list': + print("Donors: ") + for name in names: + print(" " + name) + user_in = "" + amount = 0 + while amount == 0: + try: + amount = float(input("Enter a donation amount: ")) + except: + amount = 0 + print("-> ERROR: Please enter a valid floating point number.") + add_donation(user_in, amount) + output_thankyou(user_in, amount) + +# adds a new donor +def new_donor(donor_name): + donors[donor_name.lower()] = {'donations': 0, 'total': 0, 'name': donor_name} + return donors[donor_name.lower()] + +# adds a new donation for a donor +def add_donation(donor_name, amount): + lower_donor_name = donor_name.lower() + if lower_donor_name not in list(donors.keys()): + new_donor(donor_name) + donors[donor_name.lower()]['donations'] += 1 + donors[donor_name.lower()]['total'] += amount + return donors[donor_name.lower()] + +# print a report +def output_report(): + print(generate_report()) + +def generate_report(): + table_headerfmt = "{:<19s}|{:>15s} |{:>14s} |{:>15s}\n" + table_formatter = "{:<19s} ${:13.2f} {:14d} ${:13.2f}\n" + table_seperator = "-" * 68 + "\n" + generated_text = "" + + generated_text += table_headerfmt.format("Donor Name", "Total Given", "Num Gifts", "Average Gift") + generated_text += table_seperator + + # unpack to a list of lists + donor_list = [[donors[donor]['name'], donors[donor]['donations'], donors[donor]['total']] for donor in donors] + + # sort the list + donor_list = sorted(donor_list, key = lambda x: x[2] * -1) + + # add the list to the generated text + for donor in donor_list: + generated_text += table_formatter.format(donor[0], donor[2], donor[1], donor[2] / donor[1]) + + # return the generated report + return generated_text + +# print a thank you for a recent donation +def output_thankyou(donor_name, latest_amount): + print(generate_thankyou(donor_name, latest_amount, True)) + +# moved the writing logic to a separate def, just printing in this one. +def write_letters(): + for donor, file in write_letter_files().items(): + print('>>> Wrote thank you note for {} to {}'.format(donor, file)) + +# write a thank you note to disk for a donor +# return a dict of {donor_name: donor_file} +def write_letter_files(): + files_written = {} + for donor_name in donors.keys(): + # convert any non-alphanumeric characters to _ for the filename + donor_file = re.sub(r"[^a-zA-Z0-9_-]+", "_", donor_name) + ".txt" + + note = generate_thankyou(donor_name) + f = open(donor_file, 'w') + f.write(note) + f.close() + files_written[donor_name] = donor_file + return files_written + +# generate a thank you note for a donor +def generate_thankyou(donor_name, latest_amount=0, recent=False): + lower_donor_name = donor_name.lower() + donations_total = donors[lower_donor_name]["total"] + donations_count = donors[lower_donor_name]["donations"] + cased_donor_name = donors[lower_donor_name]["name"] + format_values = {'donations_total': donations_total, + 'donations_count': donations_count, + 'donor_name': cased_donor_name, + 'latest_amount': latest_amount} + if recent: + template = '''---------------------------------------------------------------------- +Dear {donor_name}, + Thank you for your generous donation of {latest_amount:.2f}! +That brings your total of {donations_count} donation(s) to ${donations_total:.2f} +Sincerely, + -Me +''' + else: + template = '''---------------------------------------------------------------------- +Dear {donor_name}, + Thank you for all {donations_count} of your generous donations for a total of {donations_total:.2f}! +We will put the money to good use. +Sincerely, + -Me +''' + letter = template.format(**format_values) + return(letter) + +# the main loop +def main(): + selection = "2" + while menu_opts[selection] != quit: + selection = get_main_selection() + menu_opts[selection]() + +# a dict for mapping user selection to functions +menu_opts = {'1': send_thankyou, + '2': output_report, + '3': write_letters, + '4': quit} +menu_opts_text = {send_thankyou: "Send a Thank You to a single donor.", + output_report: "Create a report.", + write_letters: "Send letters to all donors.", + quit: "Quit."} + +if __name__ == '__main__': + main() diff --git a/students/aaron/homework_lesson6/mailroom_v4_test.py b/students/aaron/homework_lesson6/mailroom_v4_test.py new file mode 100755 index 0000000..72aae4e --- /dev/null +++ b/students/aaron/homework_lesson6/mailroom_v4_test.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python3 +# +#------------------------------------- +# Assignment: mailroom tests (mailroom version 4, from lesson 6) +# Description: This file contains tests for mailroom_v4.py +# Changelog: +# 2019-02-19,Aaron Devey,Created +#------------------------------------- +# +# + +import pytest +import glob +from mailroom_v4 import generate_main_menu, generate_report, generate_thankyou, write_letter_files, new_donor, add_donation, get_donors + + +def test_generate_main_menu_text(): + test_text = '''---------------------------------------------------------------------- +1. Send a Thank You to a single donor. +2. Create a report. +3. Send letters to all donors. +4. Quit. +''' + assert(generate_main_menu() == test_text) + +def test_generate_report_text(): + test_text = '''Donor Name | Total Given | Num Gifts | Average Gift +-------------------------------------------------------------------- +Bruce Lee $ 52246.75 3 $ 17415.58 +Bob Barker $ 24456.24 2 $ 12228.12 +Kermit the Frogg $ 23475.20 2 $ 11737.60 +Roger Rabbit $ 4930.26 1 $ 4930.26 +Frodo Baggins $ 1249.44 1 $ 1249.44 +''' + assert(generate_report() == test_text) + +def test_generate_thankyou_report_text(): + test_text = '''---------------------------------------------------------------------- +Dear Bruce Lee, + Thank you for all 3 of your generous donations for a total of 52246.75! +We will put the money to good use. +Sincerely, + -Me +''' + assert(generate_thankyou("Bruce Lee") == test_text) + +def test_generate_thankyou_new_donation(): + test_text = '''---------------------------------------------------------------------- +Dear Bruce Lee, + Thank you for your generous donation of 232.12! +That brings your total of 3 donation(s) to $52246.75 +Sincerely, + -Me +''' + assert(generate_thankyou("Bruce Lee", 232.12, True) == test_text) + +def test_generate_thankyou_unknown_donor(): + with pytest.raises(KeyError): + generate_thankyou("Adam West") + with pytest.raises(KeyError): + generate_thankyou("Adam West", 1232.12, True) + +def test_write_letter_files(): + test_written = {'bob barker': 'bob_barker.txt', + 'bruce lee': 'bruce_lee.txt', + 'frodo baggins': 'frodo_baggins.txt', + 'kermit the frog': 'kermit_the_frog.txt', + 'roger rabbit': 'roger_rabbit.txt'} + assert(write_letter_files() == test_written) + +def test_new_donor(): + test_donor = {'name': 'Adam West', 'total': 0, 'donations': 0} + test_all_donors = {'adam west': {'donations': 0, 'name': 'Adam West', 'total': 0}, + 'bob barker': {'donations': 2, 'name': 'Bob Barker', 'total': 24456.24}, + 'bruce lee': {'donations': 3, 'name': 'Bruce Lee', 'total': 52246.75}, + 'frodo baggins': {'donations': 1, 'name': 'Frodo Baggins', 'total': 1249.44}, + 'kermit the frog': {'donations': 2, 'name': 'Kermit the Frogg', 'total': 23475.2}, + 'roger rabbit': {'donations': 1, 'name': 'Roger Rabbit', 'total': 4930.26}} + assert(new_donor('Adam West') == test_donor) + assert(get_donors() == test_all_donors) + +def test_add_donation(): + test_donor = {'donations': 1, 'name': 'Adam West', 'total': 1122.33} + test_all_donors = {'adam west': {'donations': 1, 'name': 'Adam West', 'total': 1122.33}, + 'bob barker': {'donations': 2, 'name': 'Bob Barker', 'total': 24456.24}, + 'bruce lee': {'donations': 3, 'name': 'Bruce Lee', 'total': 52246.75}, + 'frodo baggins': {'donations': 1, 'name': 'Frodo Baggins', 'total': 1249.44}, + 'kermit the frog': {'donations': 2, 'name': 'Kermit the Frogg', 'total': 23475.2}, + 'roger rabbit': {'donations': 1, 'name': 'Roger Rabbit', 'total': 4930.26}} + assert(add_donation('Adam West', 1122.33) == test_donor) + assert(get_donors() == test_all_donors) + +def test_add_donation_new_donor(): + test_donor = {'donations': 1, 'name': 'Han Solo', 'total': 3322.11} + test_all_donors = {'adam west': {'donations': 1, 'name': 'Adam West', 'total': 1122.33}, + 'bob barker': {'donations': 2, 'name': 'Bob Barker', 'total': 24456.24}, + 'bruce lee': {'donations': 3, 'name': 'Bruce Lee', 'total': 52246.75}, + 'frodo baggins': {'donations': 1, 'name': 'Frodo Baggins', 'total': 1249.44}, + 'kermit the frog': {'donations': 2, 'name': 'Kermit the Frogg', 'total': 23475.2}, + 'roger rabbit': {'donations': 1, 'name': 'Roger Rabbit', 'total': 4930.26}, + 'han solo': test_donor} + + assert(add_donation('Han Solo', 3322.11) == test_donor) + assert(get_donors() == test_all_donors) + +def test_written_file_outputs(): + test_written = {'adam west': 'adam_west.txt', + 'bob barker': 'bob_barker.txt', + 'bruce lee': 'bruce_lee.txt', + 'frodo baggins': 'frodo_baggins.txt', + 'han solo': 'han_solo.txt', + 'kermit the frog': 'kermit_the_frog.txt', + 'roger rabbit': 'roger_rabbit.txt'} + assert(write_letter_files() == test_written) + +def test_written_file_contents(): + test_first_line = "-" * 70 + "\n" + test_second_line = "Dear Adam West,\n" + f = open("adam_west.txt", "r") + actual_first_line = f.readline() + actual_second_line = f.readline() + assert(actual_first_line == test_first_line) + assert(actual_second_line == test_second_line) From b99c1921a81a473d8067c14a6fb21ed64ace9ab2 Mon Sep 17 00:00:00 2001 From: Aaron D Date: Tue, 26 Feb 2019 03:34:53 -0800 Subject: [PATCH 12/12] Adding lesson7 homework --- .../aaron/homework_lesson7/html_render.py | 120 ++++++++ .../aaron/homework_lesson7/run_html_render.py | 231 +++++++++++++++ .../aaron/homework_lesson7/sample_html.html | 27 ++ .../homework_lesson7/test_html_output1.html | 2 + .../homework_lesson7/test_html_output2.html | 9 + .../homework_lesson7/test_html_output3.html | 16 ++ .../homework_lesson7/test_html_output4.html | 13 + .../homework_lesson7/test_html_output5.html | 14 + .../homework_lesson7/test_html_output6.html | 15 + .../homework_lesson7/test_html_output7.html | 28 ++ .../homework_lesson7/test_html_output8.html | 32 +++ .../homework_lesson7/test_html_render.py | 263 ++++++++++++++++++ 12 files changed, 770 insertions(+) create mode 100644 students/aaron/homework_lesson7/html_render.py create mode 100755 students/aaron/homework_lesson7/run_html_render.py create mode 100644 students/aaron/homework_lesson7/sample_html.html create mode 100644 students/aaron/homework_lesson7/test_html_output1.html create mode 100644 students/aaron/homework_lesson7/test_html_output2.html create mode 100644 students/aaron/homework_lesson7/test_html_output3.html create mode 100644 students/aaron/homework_lesson7/test_html_output4.html create mode 100644 students/aaron/homework_lesson7/test_html_output5.html create mode 100644 students/aaron/homework_lesson7/test_html_output6.html create mode 100644 students/aaron/homework_lesson7/test_html_output7.html create mode 100644 students/aaron/homework_lesson7/test_html_output8.html create mode 100644 students/aaron/homework_lesson7/test_html_render.py diff --git a/students/aaron/homework_lesson7/html_render.py b/students/aaron/homework_lesson7/html_render.py new file mode 100644 index 0000000..f327d73 --- /dev/null +++ b/students/aaron/homework_lesson7/html_render.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 + +#------------------------------------------------ +# Title: html_render.py (homework from lesson 7) +# Changelog: +# 2019-02-25,Aaron Devey,Created +#------------------------------------------------ + + +""" +A class-based system for rendering html. +""" + +from io import StringIO + +# This is the framework for the base class +class Element(object): + contents = [] + indent = 0 + indent_width = 4 + tag_name = "html" + tag_attrs = {} + render_format = "{}\n{}{}\n" + open_format = "<{}{}>" + close_format = "" + + + def __init__(self, content="", **kwargs): + self.contents = [] + self.contents.append(content) + self.tag_attrs = kwargs + + def append(self, new_content): + self.contents.append(new_content) + + def render(self, out_file, current_indent = 0): + out_file.write(self.prerender(current_indent)) + + def render_indent(self, depth): + return " " * (depth * self.indent_width) + + def close_tag(self): + return self.close_format.format(self.tag_name) + + def open_tag(self): + props = "" + for key, val in self.tag_attrs.items(): + props += " {}=\"{}\"".format(key, val) + return self.open_format.format(self.tag_name, props) + + def prerender(self, current_indent = 0): + self.indent = current_indent + output = "" + for content in self.contents: + if type(content) == str: + output += self.render_indent(self.indent + 1) + content + "\n" + else: + output += content.prerender(self.indent + 1) + return self.render_format.format(self.render_indent(self.indent) + self.open_tag(), output, self.render_indent(self.indent) + self.close_tag()) + + def __str__(self): + return self.prerender() + + +class Html(Element): + tag_name = "html" + open_format = "\n<{}{}>" + +class Body(Element): + tag_name = "body" + +class P(Element): + tag_name = "p" + +class Head(Element): + tag_name = "head" + +class OneLineTag(Element): + render_format = "{}{}{}\n" + def prerender(self, current_indent = 0): + self.indent = current_indent + output = "" + return self.render_format.format(self.render_indent(self.indent) + self.open_tag(), " ".join(self.contents), self.close_tag()) + +class Title(OneLineTag): + tag_name = "title" + +class SelfClosingTag(Element): + render_format = "{}\n" + open_format = "<{}{} />" + def append(self, content): + raise TypeError("Cannot add content to self closing tag type") + + def __init__(self, **kwargs): + self.tag_attrs = kwargs + +class Hr(SelfClosingTag): + tag_name = "hr" + +class A(OneLineTag): + tag_name = "a" + def __init__(self, link, content): + self.tag_attrs = {'href': str(link)} + super().__init__(content) + +class Ul(Element): + tag_name = "ul" + +class Li(Element): + tag_name = "li" + +class H(OneLineTag): + tag_name = "h" + def __init__(self, size, content): + self.tag_name += str(size) + super().__init__(content) + +class Meta(SelfClosingTag): + tag_name = "meta" + diff --git a/students/aaron/homework_lesson7/run_html_render.py b/students/aaron/homework_lesson7/run_html_render.py new file mode 100755 index 0000000..8054677 --- /dev/null +++ b/students/aaron/homework_lesson7/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/aaron/homework_lesson7/sample_html.html b/students/aaron/homework_lesson7/sample_html.html new file mode 100644 index 0000000..9c2e675 --- /dev/null +++ b/students/aaron/homework_lesson7/sample_html.html @@ -0,0 +1,27 @@ + + + + + Python Class Sample page + + +

Python Class - Html rendering example

+

+ Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text +

+
+
    +
  • + The first item in a list +
  • +
  • + This is the second item +
  • +
  • + And this is a + link + to google +
  • +
+ + \ No newline at end of file diff --git a/students/aaron/homework_lesson7/test_html_output1.html b/students/aaron/homework_lesson7/test_html_output1.html new file mode 100644 index 0000000..1b4050c --- /dev/null +++ b/students/aaron/homework_lesson7/test_html_output1.html @@ -0,0 +1,2 @@ + +Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some textAnd here is another piece of text -- you should be able to add any number diff --git a/students/aaron/homework_lesson7/test_html_output2.html b/students/aaron/homework_lesson7/test_html_output2.html new file mode 100644 index 0000000..2a7e7a1 --- /dev/null +++ b/students/aaron/homework_lesson7/test_html_output2.html @@ -0,0 +1,9 @@ + + +

+Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text +

+And here is another piece of text -- you should be able to add any number +

+ + \ No newline at end of file diff --git a/students/aaron/homework_lesson7/test_html_output3.html b/students/aaron/homework_lesson7/test_html_output3.html new file mode 100644 index 0000000..6d1a0e5 --- /dev/null +++ b/students/aaron/homework_lesson7/test_html_output3.html @@ -0,0 +1,16 @@ + + +PythonClass = Revision 1087: + + + +

+Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text +

+

+And here is another piece of text -- you should be able to add any number +

+ + + + diff --git a/students/aaron/homework_lesson7/test_html_output4.html b/students/aaron/homework_lesson7/test_html_output4.html new file mode 100644 index 0000000..076332f --- /dev/null +++ b/students/aaron/homework_lesson7/test_html_output4.html @@ -0,0 +1,13 @@ + + +PythonClass = Revision 1087: + + + +

+Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text +

+ + + + diff --git a/students/aaron/homework_lesson7/test_html_output5.html b/students/aaron/homework_lesson7/test_html_output5.html new file mode 100644 index 0000000..20cfe0c --- /dev/null +++ b/students/aaron/homework_lesson7/test_html_output5.html @@ -0,0 +1,14 @@ + + +PythonClass = Revision 1087: + + + +

+Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text +

+
+ + + + diff --git a/students/aaron/homework_lesson7/test_html_output6.html b/students/aaron/homework_lesson7/test_html_output6.html new file mode 100644 index 0000000..1329a7f --- /dev/null +++ b/students/aaron/homework_lesson7/test_html_output6.html @@ -0,0 +1,15 @@ + + +PythonClass = Revision 1087: + + + +

+Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text +

+
+And this is a link +to google + + + diff --git a/students/aaron/homework_lesson7/test_html_output7.html b/students/aaron/homework_lesson7/test_html_output7.html new file mode 100644 index 0000000..685ba3c --- /dev/null +++ b/students/aaron/homework_lesson7/test_html_output7.html @@ -0,0 +1,28 @@ + + +PythonClass = Revision 1087: + + + +

PythonClass - Class 6 example

+

+Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text +

+
+
    +
  • +The first item in a list +
  • +
  • +This is the second item +
  • +
  • +And this is a link +to google +
  • + +
+ + + + diff --git a/students/aaron/homework_lesson7/test_html_output8.html b/students/aaron/homework_lesson7/test_html_output8.html new file mode 100644 index 0000000..ee3b5b9 --- /dev/null +++ b/students/aaron/homework_lesson7/test_html_output8.html @@ -0,0 +1,32 @@ + + + + + + + PythonClass = Revision 1087: + + + +

PythonClass - Example

+

+ Here is a paragraph of text -- there could be more of them, but this is enough to show that we can do some text +

+
+
    + +
  • + The first item in a list +
  • +
  • + This is the second item +
  • +
  • + + And this is a + link + to google +
  • +
+ + diff --git a/students/aaron/homework_lesson7/test_html_render.py b/students/aaron/homework_lesson7/test_html_render.py new file mode 100644 index 0000000..8249d25 --- /dev/null +++ b/students/aaron/homework_lesson7/test_html_render.py @@ -0,0 +1,263 @@ +""" +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=0): + """ + 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 +######## + +# Add your tests here! + +# ##################### +# # 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, 1).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, 0) + + print(file_contents) + lines = file_contents.split("\n") + assert lines[1].startswith(" ") + + +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") + assert("") in file_contents + assert(" ") in file_contents + assert("

") in file_contents + assert(" some") in file_contents + + +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(" " + "thi") + assert lines[2] == "" + assert file_contents.endswith("")