From 90fa8565df68e913ea3719649fa383da1bc9d72b Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 19 Jan 2019 16:31:40 -0800 Subject: [PATCH 01/41] added reason for creating file --- students/johnwachter/README.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 students/johnwachter/README.txt diff --git a/students/johnwachter/README.txt b/students/johnwachter/README.txt new file mode 100644 index 0000000..9177a8f --- /dev/null +++ b/students/johnwachter/README.txt @@ -0,0 +1 @@ +git status From 3685ed9c96cda11350b1bcc18fe8f39babe82191 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 19 Jan 2019 16:38:53 -0800 Subject: [PATCH 02/41] moving mailroom.py to proper folder --- students/johnwachter/mailroom/mailroom.py | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 students/johnwachter/mailroom/mailroom.py diff --git a/students/johnwachter/mailroom/mailroom.py b/students/johnwachter/mailroom/mailroom.py new file mode 100644 index 0000000..339ec27 --- /dev/null +++ b/students/johnwachter/mailroom/mailroom.py @@ -0,0 +1,3 @@ +#Title: mailroom.py +#Change Log: (Who, When, What) +#JWachter, 1/19/2019, creating file to upload to github From 33619b119c743244dc4b5641d8022c289fe1e5d9 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Mon, 21 Jan 2019 09:04:41 -0800 Subject: [PATCH 03/41] added 3 homework files --- students/johnwachter/session02/FizzBuzz.py | 16 +++++ .../session02/GridPrinterExercise.py | 45 ++++++++++++++ students/johnwachter/session02/series.py | 60 +++++++++++++++++++ 3 files changed, 121 insertions(+) create mode 100644 students/johnwachter/session02/FizzBuzz.py create mode 100644 students/johnwachter/session02/GridPrinterExercise.py create mode 100644 students/johnwachter/session02/series.py diff --git a/students/johnwachter/session02/FizzBuzz.py b/students/johnwachter/session02/FizzBuzz.py new file mode 100644 index 0000000..e591a72 --- /dev/null +++ b/students/johnwachter/session02/FizzBuzz.py @@ -0,0 +1,16 @@ +#Title: Lab GridPrinterExercise.py +#Change Log: (Who, When, What) +#JWachter, 2019-01-19, created file and function, fizbuzz, to demonstrate 'if' and 'and' statements + +def fizbuzz(): + """Return values on a list from 1-100 based on the divisibility of 3 and 5""" + for i in range(1,100+1): + if i%3 == 0 and i%5 ==0: + print("FizzBuzz") + elif i %3 == 0: + print("Fizz") + elif i %5 == 0: + print("Buzz") + else: + print(i) +fizbuzz() diff --git a/students/johnwachter/session02/GridPrinterExercise.py b/students/johnwachter/session02/GridPrinterExercise.py new file mode 100644 index 0000000..82c3b13 --- /dev/null +++ b/students/johnwachter/session02/GridPrinterExercise.py @@ -0,0 +1,45 @@ +#Title: Lab GridPrinterExercise.py +#Change Log: (Who, When, What) +#JWachter, 2019-01-19, created file and printed basic grid in part 1 of exercise + +#Data +plusminusrow = '+''-''-''-''-''+''-''-''-''-''+' +piperow = '|'' '' '' '' ''|' ' '' '' '' ''|''\n' +newline = '\n' + +"This is part 1 of the exercise" +print("Part 1") +def printgrid_1(): + """Print a 2x2 grid""" + print(plusminusrow + newline + piperow*4 + plusminusrow + newline + piperow*4 +plusminusrow) +printgrid_1() +"This is part 2 of the exercise" +print("Part 2") +def printgrid_2(n): + """ + Print the visual of a 1x1 grid + :param n: the number of rows in the grid represented by the pipe '|' symbol + :return: Returns True so as to return at least something which follows Pythonic convention. + """ + print(plusminusrow + newline + piperow*n + plusminusrow + newline + piperow*n + plusminusrow) + return True +printgrid_2(1) + + +"This is part 3 of the exercise" +print("Part 3") +def printgrid_3(n_rowsandcolumns = 4, n_sizedunit = 1): + """ + Print the visual of a grid based, whose size is based on arguments fed to parameters in the function. + :param n_rowsandcolumns: Represents the number of times the grid will be repeated across (columns) and down (rows) + :param n_sizedunit: Represents the number of minus '-' symbols that appear across the row of the grid + :return: Returns True so as to return at least something which follows Pythonic convention. + """ + minussymbol = '-' + plusminusrow2 = ('+' + minussymbol * n_sizedunit) + piperow2 = '|' + ' ' * n_sizedunit + grid = (plusminusrow2*n_rowsandcolumns + '+' + newline + piperow2*n_rowsandcolumns + '|' + newline + piperow2 * n_rowsandcolumns + '|' + newline + piperow2 * n_rowsandcolumns + '|' + newline + piperow2 * n_rowsandcolumns + '|' + newline) + print(grid*n_rowsandcolumns, end=plusminusrow2*n_rowsandcolumns +'+') + return True +printgrid_3(4, 9) + diff --git a/students/johnwachter/session02/series.py b/students/johnwachter/session02/series.py new file mode 100644 index 0000000..d9c9abe --- /dev/null +++ b/students/johnwachter/session02/series.py @@ -0,0 +1,60 @@ +#Title: Lab GridPrinterExercise.py +#Change Log: (Who, When, What) +#JWachter, 1/19/2019, creating fibonacci series + +def fibonacci(n): + """Return the nth value in the fibonacci series, starting with zero index""" + if n <= 1: + return n + else: + return fibonacci(n-1)+fibonacci(n-2) + +nterms = 8 +if nterms <= 0: + print("Please enter a positive integer") +else: + print("Fibonacci Sequence: ") + for i in range(nterms): + print(fibonacci(i)) + + +def lucas(n): + """Return the nth value in the Lucas numbers, starting with 2, then 1, then 3, 4, 5....n""" + if n == 0: + return 2 + elif n == 1: + return 1 + else: + return lucas(n - 1) + lucas(n - 2) +iterms = 9 +if iterms <= 0: + print("Please enter a positive integer") +else: + print("Lucas Numbers: ") +for i in range(iterms): + print(lucas(i)) + + +def sumseries(n, n1=0, n2=1): + """ + Return the nth value of a list, based on adding the two previous items in the list to get the next item, in a recursive fashion. + :param n: nth item in the list + :param n1: 0th value in the list + :param n2: 1st value in the list + :return: the value of the nth item in the list + """ + if n == 0: + return n1 + elif n == 1: + return n2 + else: + return sumseries(n - 1, n1, n2) + sumseries(n - 2, n1, n2) + +iterms = 4 +if iterms <= 0: + print("Please enter a positive integer") +else: + print("Sumseries: ") +for i in range(iterms): + print(sumseries(i, 2, 1)) + From 52bf4996367f72473901624fa66797fdcf024f4f Mon Sep 17 00:00:00 2001 From: johnwachter Date: Mon, 21 Jan 2019 21:08:32 -0800 Subject: [PATCH 04/41] running 'assert' tests to ensure the three functions work properly --- students/johnwachter/session02/series.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/students/johnwachter/session02/series.py b/students/johnwachter/session02/series.py index d9c9abe..cb9db43 100644 --- a/students/johnwachter/session02/series.py +++ b/students/johnwachter/session02/series.py @@ -58,3 +58,27 @@ def sumseries(n, n1=0, n2=1): for i in range(iterms): print(sumseries(i, 2, 1)) + +if __name__ == "__main__": + # run tests to ensure funcs above are working properly + 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 sumseries(5) == fibonacci(5) + + # test if sum_series matched lucas + assert sumseries(5, 2, 1) == lucas(5) + + print("tests passed") + From dbbef7ad12a090c610c7d7879231b240dc2422e6 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Mon, 21 Jan 2019 21:11:16 -0800 Subject: [PATCH 05/41] changed the 'assert' test on the lucas function from lucas(0) == 2 to lucas (0) ==3 to make sure I got an error. I did receive an error, which is what I expected --- students/johnwachter/session02/series.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/students/johnwachter/session02/series.py b/students/johnwachter/session02/series.py index cb9db43..ffac38d 100644 --- a/students/johnwachter/session02/series.py +++ b/students/johnwachter/session02/series.py @@ -70,7 +70,8 @@ def sumseries(n, n1=0, n2=1): assert fibonacci(6) == 8 assert fibonacci(7) == 13 - assert lucas(0) == 2 + # run tests on lucas function + assert lucas(0) == 3 assert lucas(1) == 1 assert lucas(4) == 7 From 611c230a3c551ccc415169bde91bf5313d9cfa3f Mon Sep 17 00:00:00 2001 From: johnwachter Date: Mon, 21 Jan 2019 21:16:39 -0800 Subject: [PATCH 06/41] adding verbose comments to describe tests --- students/johnwachter/session02/series.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/students/johnwachter/session02/series.py b/students/johnwachter/session02/series.py index ffac38d..f025e7d 100644 --- a/students/johnwachter/session02/series.py +++ b/students/johnwachter/session02/series.py @@ -71,14 +71,15 @@ def sumseries(n, n1=0, n2=1): assert fibonacci(7) == 13 # run tests on lucas function - assert lucas(0) == 3 + assert lucas(0) == 2 assert lucas(1) == 1 assert lucas(4) == 7 + # test if sumseries function with only the necessary argument == ficonacci series, which should be the case assert sumseries(5) == fibonacci(5) - # test if sum_series matched lucas + # test if sumseries function matched lucas. sumeries is called with all three arguments and matches the values in the lucas function, namely that the zero index value == 2 and the first index value == 1 assert sumseries(5, 2, 1) == lucas(5) print("tests passed") From f449b1e4cf3bccc6229b6019d498f042f2c09903 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Mon, 21 Jan 2019 21:35:49 -0800 Subject: [PATCH 07/41] four more python pushups down! --- .../johnwachter/session02/pythonpushups2.py | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 students/johnwachter/session02/pythonpushups2.py diff --git a/students/johnwachter/session02/pythonpushups2.py b/students/johnwachter/session02/pythonpushups2.py new file mode 100644 index 0000000..f7888fd --- /dev/null +++ b/students/johnwachter/session02/pythonpushups2.py @@ -0,0 +1,45 @@ +#Title: pythonpushups2.py +#Change Log: (Who, When, What) +#JWachter, 1/21/2019, continuing python pushups exercises + +"""Given 2 ints, a and b, return True if one if them is 10 or if their sum is 10.""" + +def makes10(a, b): + if a + b == 10: + return True + elif a == 10 or b == 10: + return True + else: + return False + + +"""Given an int n, return True if it is within 10 of 100 or 200. Note: abs(num) computes the absolute value of a number.""" +def near_hundred(n): + if abs(100 - n) <= 10: + return True + elif abs(200 - n) <=10: + return True + else: + return False + +"""Given 2 int values, return True if one is negative and one is positive. Except if the parameter "negative" is True, then return True only if both are negative.""" +def pos_neg(a, b, negative): + if negative == True: + if a < 0 and b < 0: + return True + else: + return False + elif a > 0 and b < 0: + return True + elif a < 0 and b > 0: + return True + else: + return False + +"""Given a string, return a new string where "not " has been added to the front. However, if the string already begins with "not", return the string unchanged.""" + +def not_string(str): + if len(str) >= 3 and str[:3] == "not": + return str + else: + return "not " + str From e852c4acbc5699ba6b97d1311eb3b89c7248a687 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 26 Jan 2019 14:03:18 -0800 Subject: [PATCH 08/41] Create function to swap the first and last items in a string --- students/johnwachter/session03/slicing_lab.py | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 students/johnwachter/session03/slicing_lab.py diff --git a/students/johnwachter/session03/slicing_lab.py b/students/johnwachter/session03/slicing_lab.py new file mode 100644 index 0000000..5dda431 --- /dev/null +++ b/students/johnwachter/session03/slicing_lab.py @@ -0,0 +1,35 @@ +#Title: slicing_lab.py +#Change Log: (Who, When, What) +#JWachter, 2019-01-26, Created File and finished exercise + +def swap(string): + first = string[0] + last = string[-1] + mid = string[1:-1] + newstring = last + mid + first + return newstring + +swapped = swap("string") +print(swapped) +assert swap("flipped") == "dlippef" +print("Test passed") + + +def remove(tupl): + newtupl = tupl[0:-1:2] + print(newtupl) +mytupl = (1,2,3,4,5,6,7,8,9) +remove(mytupl) + +def thirds(string): + thirds = len(string)/3 + first = thirds + +string = "string" +thirds = int(len(string)/3) +first = string[0:thirds] +print("first {}".format(first)) +last = string[-thirds:] +print("last {}".format(last)) +mid = string[thirds:thirds] +print("mid {}".format(mid)) From ccb3e69eac61db461687ca88748d2815cf3663b3 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 26 Jan 2019 14:11:45 -0800 Subject: [PATCH 09/41] running assert tests to make sure functions work --- students/johnwachter/session03/slicing_lab.py | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/students/johnwachter/session03/slicing_lab.py b/students/johnwachter/session03/slicing_lab.py index 5dda431..ebc7323 100644 --- a/students/johnwachter/session03/slicing_lab.py +++ b/students/johnwachter/session03/slicing_lab.py @@ -10,26 +10,42 @@ def swap(string): return newstring swapped = swap("string") +print("Swap String") print(swapped) assert swap("flipped") == "dlippef" print("Test passed") - +print("="*45) def remove(tupl): newtupl = tupl[0:-1:2] - print(newtupl) + return newtupl mytupl = (1,2,3,4,5,6,7,8,9) -remove(mytupl) +removeditems = remove(mytupl) +print("Remove every other item") +print(removeditems) +print("="*45) + +def remove4everyother(string): + return string[4:-4:2] +everyother4 = (1,2,3,4,5,'dontshow','show', 'dontshow', 'show', 6,7,8,9) +print("first 4 and the last 4 items removed, and then every other item in the remaining sequence") +print(remove4everyother(everyother4)) +print('='*45) def thirds(string): - thirds = len(string)/3 - first = thirds + thirds = int(len(string)/3) + first = string[0:thirds] + last = string[-thirds:] + mid = string[thirds:-thirds] + return last + first + mid +newthirds = thirds("111222333") +print("last third, then first third, then the middle third in the new order") +print(newthirds) +print("="*45) -string = "string" -thirds = int(len(string)/3) -first = string[0:thirds] -print("first {}".format(first)) -last = string[-thirds:] -print("last {}".format(last)) -mid = string[thirds:thirds] -print("mid {}".format(mid)) +def reverse(string): + return string[::-1] +reversedstring = reverse("reverse this string") +print("Reverse a string") +print(reversedstring) +print("="*45) From 3eedf617dffb8c86f63efc3908057b3b66be70d7 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 26 Jan 2019 14:27:49 -0800 Subject: [PATCH 10/41] changing some inputs from strings to tuples to make sure the functions work with both --- students/johnwachter/session03/slicing_lab.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/students/johnwachter/session03/slicing_lab.py b/students/johnwachter/session03/slicing_lab.py index ebc7323..b3ec213 100644 --- a/students/johnwachter/session03/slicing_lab.py +++ b/students/johnwachter/session03/slicing_lab.py @@ -23,6 +23,10 @@ def remove(tupl): removeditems = remove(mytupl) print("Remove every other item") print(removeditems) +assert remove("123456789") == "1357" +asserttupltest = (1, 2, 3, 4) +assert remove(asserttupltest) == (1, 3) +print("Tests passed") print("="*45) def remove4everyother(string): @@ -30,6 +34,8 @@ def remove4everyother(string): everyother4 = (1,2,3,4,5,'dontshow','show', 'dontshow', 'show', 6,7,8,9) print("first 4 and the last 4 items removed, and then every other item in the remaining sequence") print(remove4everyother(everyother4)) +assert remove4everyother("0000123450000") == "135" +print("Test passed") print('='*45) def thirds(string): @@ -41,6 +47,8 @@ def thirds(string): newthirds = thirds("111222333") print("last third, then first third, then the middle third in the new order") print(newthirds) +assert thirds("123") == "312" +print("Test passed") print("="*45) def reverse(string): @@ -48,4 +56,6 @@ def reverse(string): reversedstring = reverse("reverse this string") print("Reverse a string") print(reversedstring) +assert reverse("racecars") == "sracecar" +print("Test passed") print("="*45) From af1b2ca3381b8630e2fc4da3332b9307391ff043 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 26 Jan 2019 14:55:54 -0800 Subject: [PATCH 11/41] updated first function with a try except error to allow for a tuple or string to be passed into it --- students/johnwachter/session03/slicing_lab.py | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/students/johnwachter/session03/slicing_lab.py b/students/johnwachter/session03/slicing_lab.py index b3ec213..455b708 100644 --- a/students/johnwachter/session03/slicing_lab.py +++ b/students/johnwachter/session03/slicing_lab.py @@ -2,28 +2,35 @@ #Change Log: (Who, When, What) #JWachter, 2019-01-26, Created File and finished exercise -def swap(string): - first = string[0] - last = string[-1] - mid = string[1:-1] - newstring = last + mid + first - return newstring - -swapped = swap("string") -print("Swap String") +def swap(sequence): + try: + first = sequence[0], + last = sequence[-1], + mid = sequence[1:-1] + newsequence = last + mid + first + return newsequence + except TypeError: + first = sequence[0] + last = sequence[-1] + mid = sequence[1:-1] + newsequence = last + mid + first + return newsequence +swappedsequence = (0,1,2,3,4) +swapped = swap(swappedsequence) +print("Swap Sequence") print(swapped) assert swap("flipped") == "dlippef" print("Test passed") print("="*45) def remove(tupl): - newtupl = tupl[0:-1:2] + newtupl = tupl[::2] return newtupl mytupl = (1,2,3,4,5,6,7,8,9) removeditems = remove(mytupl) print("Remove every other item") print(removeditems) -assert remove("123456789") == "1357" +assert remove("123456789") == "13579" asserttupltest = (1, 2, 3, 4) assert remove(asserttupltest) == (1, 3) print("Tests passed") @@ -44,11 +51,13 @@ def thirds(string): last = string[-thirds:] mid = string[thirds:-thirds] return last + first + mid -newthirds = thirds("111222333") +tuplethirds = (1,1,2,2,3,3) +newthirds = thirds(tuplethirds) print("last third, then first third, then the middle third in the new order") print(newthirds) assert thirds("123") == "312" -print("Test passed") +assert thirds(tuplethirds) == (3, 3, 1, 1, 2, 2) +print("Tests passed") print("="*45) def reverse(string): From 46d3846a37551b8a9574d056cc80a84e29ff0e0a Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 26 Jan 2019 15:29:21 -0800 Subject: [PATCH 12/41] completed series 1 --- students/johnwachter/session03/list_lab.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 students/johnwachter/session03/list_lab.py diff --git a/students/johnwachter/session03/list_lab.py b/students/johnwachter/session03/list_lab.py new file mode 100644 index 0000000..9922daa --- /dev/null +++ b/students/johnwachter/session03/list_lab.py @@ -0,0 +1,21 @@ +#Title: Lab list_lab.py +#Change Log: (Who, When, What) +#JWachter, 2019-01-26, created file to explore the list data structure + +#series 1 +#Series 1 +fruit_list = ["Apples", "Pears", "Oranges", "Peaches"] +print(fruit_list) +user_fruit = input("Enter a fruit: ") +fruit_list.append(user_fruit) +print(fruit_list) +user_index = int(input("Give me a number between 1 and {}: ".format(len(fruit_list)))) +fruittodisplay = int(user_index-1) +print("Your number was {} and the fruit is {}".format(user_index, fruit_list[fruittodisplay])) +fruit_list = [input("Enter another fruit: ")] + fruit_list +print(fruit_list) +fruit_list.insert(0, 'Cherry') +print(fruit_list) +for fruit in fruit_list: + if fruit[0] == 'P': + print("P fruits: ".format(fruit)) From 396bc8c9683668bf9c6748905ef20adaa2042c81 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 26 Jan 2019 18:54:25 -0800 Subject: [PATCH 13/41] completed series 2 --- students/johnwachter/session03/list_lab.py | 27 +++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/students/johnwachter/session03/list_lab.py b/students/johnwachter/session03/list_lab.py index 9922daa..7d5c6d9 100644 --- a/students/johnwachter/session03/list_lab.py +++ b/students/johnwachter/session03/list_lab.py @@ -2,7 +2,6 @@ #Change Log: (Who, When, What) #JWachter, 2019-01-26, created file to explore the list data structure -#series 1 #Series 1 fruit_list = ["Apples", "Pears", "Oranges", "Peaches"] print(fruit_list) @@ -17,5 +16,27 @@ fruit_list.insert(0, 'Cherry') print(fruit_list) for fruit in fruit_list: - if fruit[0] == 'P': - print("P fruits: ".format(fruit)) + if fruit.startswith('P'): + print(fruit) + +#series 2 +print("Series 2: {}".format(fruit_list)) +fruit_list.pop(-1) +print(fruit_list) +user_delete = input("Which fruit would you like to delete? ") +if user_delete in fruit_list: + fruit_list.remove(user_delete) +print(fruit_list) + +#series 3 +reversedfruitlist = fruit_list[::-1] +for fruit in reversedfruitlist: + yes_or_no = input("Do you like {}".format(fruit.lower())) + if yes_or_no == 'no': + fruit_list.remove(fruit) + while yes_or_no != 'yes' and yes_or_no != 'no': + print("Please enter yes or no: ") + yes_or_no = input("Do you like {}".format(fruit.lower())) + if yes_or_no == 'no': + fruit_list.remove(fruit) +print(fruit_list) From b47b94700d193cb5eb9cd79a17d3a74a215a6b15 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 26 Jan 2019 19:16:55 -0800 Subject: [PATCH 14/41] Completed series 4. Used for loop to iterate through original list and reverse the characters in each string in the list. Used .pop to remove the last item from the original list --- students/johnwachter/session03/list_lab.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/students/johnwachter/session03/list_lab.py b/students/johnwachter/session03/list_lab.py index 7d5c6d9..88a42f2 100644 --- a/students/johnwachter/session03/list_lab.py +++ b/students/johnwachter/session03/list_lab.py @@ -40,3 +40,12 @@ if yes_or_no == 'no': fruit_list.remove(fruit) print(fruit_list) + +#series4 +fruit_list_reversed = [] +for fruit in fruit_list: + reversefruit = fruit[::-1] + fruit_list_reversed.append(reversefruit) +fruit_list.pop(-1) +print("Original Fruit List with last removed {}".format(fruit_list)) +print("Copy of List, with items reversed {}".format(fruit_list_reversed)) From 5a993f05a85932179f82ffa6e07a04edbe1fa920 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Mon, 28 Jan 2019 17:34:28 -0800 Subject: [PATCH 15/41] completed --- students/johnwachter/session03/list_lab.py | 1 + 1 file changed, 1 insertion(+) diff --git a/students/johnwachter/session03/list_lab.py b/students/johnwachter/session03/list_lab.py index 88a42f2..b3d96c3 100644 --- a/students/johnwachter/session03/list_lab.py +++ b/students/johnwachter/session03/list_lab.py @@ -1,6 +1,7 @@ #Title: Lab list_lab.py #Change Log: (Who, When, What) #JWachter, 2019-01-26, created file to explore the list data structure +#JWachter, 2019-01-28, completed exercises and checkd my work #Series 1 fruit_list = ["Apples", "Pears", "Oranges", "Peaches"] From 64eda8b172e0011a2698d50967655d7f40455fa0 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Mon, 28 Jan 2019 19:16:10 -0800 Subject: [PATCH 16/41] Created file and finished exercises --- .../johnwachter/session03/strformat_lab.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 students/johnwachter/session03/strformat_lab.py diff --git a/students/johnwachter/session03/strformat_lab.py b/students/johnwachter/session03/strformat_lab.py new file mode 100644 index 0000000..030c8cb --- /dev/null +++ b/students/johnwachter/session03/strformat_lab.py @@ -0,0 +1,33 @@ +#Title: strformat_lab.py +#Change Log: (Who, When, What) +#JWachter, 1/28/2019, Created File + +#task1 +mytupl = (2, 123.4567, 10000, 12345.67) +print("file_00{0} : {1}, {2:.2e}, {3:.2e}".format(mytupl[0], round(mytupl[1], 2), mytupl[2], mytupl[3])) + +#task2 +# Using your results from Task One, repeat the exercise, but this time using an alternate type of format string (hint: think about alternative ways to use .format() (keywords anyone?), and also consider f-strings if you’ve not used them already). +print("The tuple contains {} items and the values are: {}, {}, {}, {}".format(len(mytupl),*mytupl)) + +#task3 +def arbitrarylengthtupl(): + tupl = (2, 3, 4, 5, 6 ,7) + tupllen = len(tupl) + print("Tuple contains {} items which are ".format(tupllen) + ("{}, "*tupllen).format(*tupl)) +arbitrarylengthtupl() + +#task4 +fiveelementtuple = (4, 30, 2017, 2, 27) +print("0{}, {}, {}, 0{}, {}".format(fiveelementtuple[3], fiveelementtuple[4], fiveelementtuple[2], fiveelementtuple[0], fiveelementtuple[1])) + +#task5 +fruitweightlist = ['oranges', 1.3, 'lemons', 1.1] +twentypercentincrease = 1.2 +print(f"The weight of an {fruitweightlist[0].rstrip('s').upper()} is {fruitweightlist[1]*twentypercentincrease} and the weight of a {fruitweightlist[2].rstrip('s').upper()} is {fruitweightlist[3]*twentypercentincrease}") + +#task6 +data = [["NAME", "AGE", "COST"], ["Greg", "Barnold", "Jarvey"], ['27', '89', '62'], ["$100", "$40,000", "$8,500"]] +col_width = max(len(word) for row in data for word in row) + 2 # padding +for row in data: + print("".join(word.ljust(col_width) for word in row)) From 9bb7dfd8d024d747869982ee674dd99994544d0d Mon Sep 17 00:00:00 2001 From: johnwachter Date: Mon, 28 Jan 2019 19:33:18 -0800 Subject: [PATCH 17/41] Built Donor database --- students/johnwachter/mailroom/mailroom.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/students/johnwachter/mailroom/mailroom.py b/students/johnwachter/mailroom/mailroom.py index 339ec27..2678d28 100644 --- a/students/johnwachter/mailroom/mailroom.py +++ b/students/johnwachter/mailroom/mailroom.py @@ -1,3 +1,10 @@ #Title: mailroom.py #Change Log: (Who, When, What) #JWachter, 1/19/2019, creating file to upload to github +#JWachter, 1/28/2019, built donor database + +donor_db = [("William Gates, III", [653772.32, 12.17]), + ("Jeff Bezos", [877.33]), + ("Paul Allen", [663.23, 43.87, 1.32]), + ("Mark Zuckerberg", [1663.23, 4300.87, 10432.0]), + ("Me Myself", [100])] From ff325e1edcf7a7811522a4bab18b0cb7bfe99b6c Mon Sep 17 00:00:00 2001 From: johnwachter Date: Mon, 28 Jan 2019 22:34:10 -0800 Subject: [PATCH 18/41] Changing donor database from a list of lists to a dictionary of key:value pairs, and the values are a list --- students/johnwachter/mailroom/mailroom.py | 77 +++++++++++++++++++++-- 1 file changed, 72 insertions(+), 5 deletions(-) diff --git a/students/johnwachter/mailroom/mailroom.py b/students/johnwachter/mailroom/mailroom.py index 2678d28..6bb3eb8 100644 --- a/students/johnwachter/mailroom/mailroom.py +++ b/students/johnwachter/mailroom/mailroom.py @@ -3,8 +3,75 @@ #JWachter, 1/19/2019, creating file to upload to github #JWachter, 1/28/2019, built donor database -donor_db = [("William Gates, III", [653772.32, 12.17]), - ("Jeff Bezos", [877.33]), - ("Paul Allen", [663.23, 43.87, 1.32]), - ("Mark Zuckerberg", [1663.23, 4300.87, 10432.0]), - ("Me Myself", [100])] +import sys + +donor_db = {"William Gates, III": [653772.32, 12.17], + "Jeff Bezos": [877.33], + "Paul Allen": [663.23, 43.87, 1.32], + "Mark Zuckerberg": [1663.23, 4300.87, 10432.0], + "Me Myself": [100]} +user_prompt = "\n".join(("Welcome to your Donor Database", "Please choose an option: ", "1 - Send a Thank You", "2 - Create a Report", "3 - Quit\n")) + +def sendthankyou(): + user_input = input( + "Let's send some Thank You letters.\nType 'list' to see a list of donors, or\ninput the donors full name: ") + for record in donor_db: + for name in record: + if user_input in name: + amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) + amtdonated + user_input_index = int(name.index(user_input)) + print("###{}".format(user_input_index)) + donor_db[4].insert(user_input_index, amtdonated) + print(donor_db) + elif user_input == 'list': + print(record[0]) + elif user_input not in name: + print("k") + +# def sendthankyou(): +# user_input = input( +# "Let's send some Thank You letters.\nType 'list' to see a list of donors, or\ninput the donors full name: ") +# for record in donor_db: +# for name in record: +# # print(name) +# # if 'Me Myself' in record: +# # print("true") +# # else: print("false") +# if user_input in name: +# #print("true") +# amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) +# amtdonated +# user_input_index = int(name.index(user_input)) +# print("###{}".format(user_input_index)) +# donor_db[4].insert(user_input_index, amtdonated) +# print(donor_db) +# elif user_input == 'list': +# print(record[0]) +# elif user_input not in name: +# print("k") + +def createreport(): + print("Great, let's create a report") + for record in donor_db: + for name in record: + print(name) + +def quitprogram(): + print("Goodbye") + sys.exit() + +def main(): + while True: + response = input(user_prompt) + if response == "1": + sendthankyou() + elif response == "2": + createreport() + elif response == "3": + quitprogram() + else: + print("Not a valid option!") + +if __name__ == "__main__": + main() From 84c5f7dd00d22676e54def6232b76595e530d710 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Mon, 28 Jan 2019 22:47:27 -0800 Subject: [PATCH 19/41] importing collections so I can have a ordered dictionary. I need an ordered dictionary so that I can find the index of the donor the user enters and insert the gift amount --- students/johnwachter/mailroom/mailroom.py | 35 +++++++++++------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/students/johnwachter/mailroom/mailroom.py b/students/johnwachter/mailroom/mailroom.py index 6bb3eb8..c1ff4e9 100644 --- a/students/johnwachter/mailroom/mailroom.py +++ b/students/johnwachter/mailroom/mailroom.py @@ -4,30 +4,29 @@ #JWachter, 1/28/2019, built donor database import sys +import collections -donor_db = {"William Gates, III": [653772.32, 12.17], - "Jeff Bezos": [877.33], - "Paul Allen": [663.23, 43.87, 1.32], - "Mark Zuckerberg": [1663.23, 4300.87, 10432.0], - "Me Myself": [100]} +donor_db = collections.OrderedDict(((("William Gates, III", [653772.32, 12.17]), + ("Jeff Bezos", [877.33]), + ("Paul Allen", [663.23, 43.87, 1.32]), + ("Mark Zuckerberg", [1663.23, 4300.87, 10432.0]), + ("Me Myself", [100])))) user_prompt = "\n".join(("Welcome to your Donor Database", "Please choose an option: ", "1 - Send a Thank You", "2 - Create a Report", "3 - Quit\n")) def sendthankyou(): user_input = input( "Let's send some Thank You letters.\nType 'list' to see a list of donors, or\ninput the donors full name: ") - for record in donor_db: - for name in record: - if user_input in name: - amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) - amtdonated - user_input_index = int(name.index(user_input)) - print("###{}".format(user_input_index)) - donor_db[4].insert(user_input_index, amtdonated) - print(donor_db) - elif user_input == 'list': - print(record[0]) - elif user_input not in name: - print("k") + if user_input in donor_db: + amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) + amtdonated + user_input_index = donor_db.keys().index(userinput) + print("###{}".format(user_input_index)) + donor_db[4].insert(user_input_index, amtdonated) + print(donor_db) + elif user_input == 'list': + print(record[0]) + elif user_input not in name: + print("k") # def sendthankyou(): # user_input = input( From 38eabfa4ace8050e6fd4370868e86505433aee84 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Mon, 28 Jan 2019 23:07:31 -0800 Subject: [PATCH 20/41] Realized ordered dictionary is not necessary. no longer importing, and changed database back to a regular dictionary --- students/johnwachter/mailroom/mailroom.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/students/johnwachter/mailroom/mailroom.py b/students/johnwachter/mailroom/mailroom.py index c1ff4e9..37b3ebb 100644 --- a/students/johnwachter/mailroom/mailroom.py +++ b/students/johnwachter/mailroom/mailroom.py @@ -2,15 +2,16 @@ #Change Log: (Who, When, What) #JWachter, 1/19/2019, creating file to upload to github #JWachter, 1/28/2019, built donor database +#JWachter, 2019-01-28, imported ordered dictionary to update info in dictionary +#JWachter, 2019-01-28, realized I don't need an ordered dictionary, no longer importing import sys -import collections -donor_db = collections.OrderedDict(((("William Gates, III", [653772.32, 12.17]), - ("Jeff Bezos", [877.33]), - ("Paul Allen", [663.23, 43.87, 1.32]), - ("Mark Zuckerberg", [1663.23, 4300.87, 10432.0]), - ("Me Myself", [100])))) +donor_db = {"William Gates, III" : [653772.32, 12.17], + "Jeff Bezos": [877.33], + "Paul Allen": [663.23, 43.87, 1.32], + "Mark Zuckerberg": [1663.23, 4300.87, 10432.0], + "Me Myself": [100]} user_prompt = "\n".join(("Welcome to your Donor Database", "Please choose an option: ", "1 - Send a Thank You", "2 - Create a Report", "3 - Quit\n")) def sendthankyou(): @@ -19,9 +20,7 @@ def sendthankyou(): if user_input in donor_db: amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) amtdonated - user_input_index = donor_db.keys().index(userinput) - print("###{}".format(user_input_index)) - donor_db[4].insert(user_input_index, amtdonated) + donor_db[user_input].append(amtdonated) print(donor_db) elif user_input == 'list': print(record[0]) From 5e23522cd9def4b585724081d18dd29df7a5b968 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Tue, 29 Jan 2019 18:16:20 -0800 Subject: [PATCH 21/41] Added while loop to repeat questions in the 'sendthankyou' function. This way the user can continue adding new donors and new gifts without automatically returning to the main menu --- students/johnwachter/session03/mailroom_part1 | 1 + students/johnwachter/session03/slicing_lab | 0 2 files changed, 1 insertion(+) create mode 100644 students/johnwachter/session03/mailroom_part1 create mode 100644 students/johnwachter/session03/slicing_lab diff --git a/students/johnwachter/session03/mailroom_part1 b/students/johnwachter/session03/mailroom_part1 new file mode 100644 index 0000000..c2fb4f3 --- /dev/null +++ b/students/johnwachter/session03/mailroom_part1 @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/students/johnwachter/session03/slicing_lab b/students/johnwachter/session03/slicing_lab new file mode 100644 index 0000000..e69de29 From f6f186242f18e4062faca93ad1a1a046b4b855d3 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Tue, 29 Jan 2019 18:23:35 -0800 Subject: [PATCH 22/41] want to make sure most up to date copy is on github --- students/johnwachter/mailroom/mailroom.py | 65 ++++++++++------------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/students/johnwachter/mailroom/mailroom.py b/students/johnwachter/mailroom/mailroom.py index 37b3ebb..8807925 100644 --- a/students/johnwachter/mailroom/mailroom.py +++ b/students/johnwachter/mailroom/mailroom.py @@ -1,9 +1,10 @@ #Title: mailroom.py #Change Log: (Who, When, What) -#JWachter, 1/19/2019, creating file to upload to github -#JWachter, 1/28/2019, built donor database +#JWachter, 2019-01-28, Created File +#JWachter, 2019-01-28, built donor database #JWachter, 2019-01-28, imported ordered dictionary to update info in dictionary #JWachter, 2019-01-28, realized I don't need an ordered dictionary, no longer importing +#JWachter. 2019-01-29, adding while loop to get user input and not return to the main menu until specified import sys @@ -15,45 +16,33 @@ user_prompt = "\n".join(("Welcome to your Donor Database", "Please choose an option: ", "1 - Send a Thank You", "2 - Create a Report", "3 - Quit\n")) def sendthankyou(): - user_input = input( - "Let's send some Thank You letters.\nType 'list' to see a list of donors, or\ninput the donors full name: ") - if user_input in donor_db: - amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) - amtdonated - donor_db[user_input].append(amtdonated) - print(donor_db) - elif user_input == 'list': - print(record[0]) - elif user_input not in name: - print("k") + user_input = "" + while user_input != "Main Menu": + user_input = input("Let's send some Thank You letters.\nType 'list' to see a list of donors, or input the donors full name to add a gift and send a Thank You letter. To return to the main menu, type 'Main Menu': ") + if user_input in donor_db: + amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) + donor_db[user_input].append(amtdonated) + print("+"*45 + "\nNice! Thanks for the ${}, {}!\n\nSincerely, me\n".format(amtdonated, user_input) + "+"*45) + elif user_input == 'list': + for donor in donor_db: + print(donor + "\n") + elif user_input not in donor_db and user_input != 'Main Menu': + donor_db[user_input] = [] + print("Great, {} has been added to the donor database.".format(user_input)) + amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) + donor_db[user_input].append(amtdonated) -# def sendthankyou(): -# user_input = input( -# "Let's send some Thank You letters.\nType 'list' to see a list of donors, or\ninput the donors full name: ") -# for record in donor_db: -# for name in record: -# # print(name) -# # if 'Me Myself' in record: -# # print("true") -# # else: print("false") -# if user_input in name: -# #print("true") -# amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) -# amtdonated -# user_input_index = int(name.index(user_input)) -# print("###{}".format(user_input_index)) -# donor_db[4].insert(user_input_index, amtdonated) -# print(donor_db) -# elif user_input == 'list': -# print(record[0]) -# elif user_input not in name: -# print("k") def createreport(): - print("Great, let's create a report") - for record in donor_db: - for name in record: - print(name) + print(" Here is your report\n" + "="*45) + print("Donor Name | Total Given | Num Gifts | Average Gift") + print("--------------------------------------------------------") + l = max(len(donor) for donor in donor_db) + for donor in donor_db: + avg = sum(donor_db[donor])/len(donor_db[donor]) + print("{:20} |".format(donor), "${0:10,.2f}|".format(sum(donor_db[donor])), "{:>4} {:<4}|".format(len(donor_db[donor]),"gifts"), "${0:<10,.2f}".format(avg)) + main() + print("+++++++++++++++++++++") def quitprogram(): print("Goodbye") From f384ea3417978a15e4f046ee8f07d6c1029a1bbb Mon Sep 17 00:00:00 2001 From: johnwachter Date: Thu, 31 Jan 2019 22:19:39 -0800 Subject: [PATCH 23/41] Forced lists into sets and checked if sets were subsets, which is working --- students/johnwachter/dict_set_lab.py | 47 ++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 students/johnwachter/dict_set_lab.py diff --git a/students/johnwachter/dict_set_lab.py b/students/johnwachter/dict_set_lab.py new file mode 100644 index 0000000..6506ec4 --- /dev/null +++ b/students/johnwachter/dict_set_lab.py @@ -0,0 +1,47 @@ +#Dictionaires1 +mydict = {'Name': 'Chris', 'City': 'Seattle', 'Cake':'Chocolate'} +print(mydict) +del mydict['Cake'] +print(mydict) +mydict['Fruit'] = 'Mango' +print(mydict) +print(mydict.keys()) +print(mydict.values()) +print(mydict.get('Cake', 'Cake not in dictionary')) +if 'Mango' in mydict.values(): + print('Mango is in the dictionary') +else: print('Mango not in dictionary') + + + +s2 = range(0,21) +s3 = range(0,21) +s4 = range(0,21) + +holds2 = list(s2) +holds3 = list(s3) +holds4 = list(s4) + +l2 = [] +l3 = [] +l4 = [] + +for i in holds2: + if i%2 ==0: + l2.append(i) +for i in holds3: + if i%3 == 0: + l3.append(i) +for i in holds4: + if i%4 == 0: + l4.append(i) + +s2 = set(l2) +s3 = set(l3) +s4 = set(l4) +print(s2, s3, s4) +print(s3 < s2) +print(s4 Date: Thu, 31 Jan 2019 22:28:32 -0800 Subject: [PATCH 24/41] Printed union and intersection of sets. Can't figure out what I'm supposed to do for Dictionary Part 2 --- students/johnwachter/dict_set_lab.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/students/johnwachter/dict_set_lab.py b/students/johnwachter/dict_set_lab.py index 6506ec4..c1d9feb 100644 --- a/students/johnwachter/dict_set_lab.py +++ b/students/johnwachter/dict_set_lab.py @@ -12,8 +12,9 @@ print('Mango is in the dictionary') else: print('Mango not in dictionary') +#Dictionaries2 - What??? - +#Sets1 s2 = range(0,21) s3 = range(0,21) s4 = range(0,21) @@ -43,5 +44,17 @@ print(s3 < s2) print(s4 Date: Sat, 2 Feb 2019 14:02:04 -0800 Subject: [PATCH 25/41] Dictionaried up my mailroom --- students/johnwachter/mailroom/mailroom2.py | 70 ++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 students/johnwachter/mailroom/mailroom2.py diff --git a/students/johnwachter/mailroom/mailroom2.py b/students/johnwachter/mailroom/mailroom2.py new file mode 100644 index 0000000..59f98a1 --- /dev/null +++ b/students/johnwachter/mailroom/mailroom2.py @@ -0,0 +1,70 @@ +#Title: MailroomPart2.py +#Change Log: (Who, When, What) +#JWachter, 2019-01-31, Created File +#JWachter. 2019-01-31, Using a dictionary as a case switch instead of If Elif statements + +import sys + +donor_db = {"William Gates, III": [653772.32, 12.17], + "Jeff Bezos": [877.33], + "Paul Allen": [663.23, 43.87, 1.32], + "Mark Zuckerberg": [1663.23, 4300.87, 10432.0], + "Me Myself": [100]} +user_prompt = "\n".join(("Welcome to your Donor Database", "Please choose an option: ", "1 - Create One 'Thank You' Letter", "2 - Create a Report", "3 - Create Thank You letters for all donors", "4 - Quit\n")) + +def sendthankyou(): + user_input = "" + while user_input != "Main Menu": + user_input = input("Let's send some Thank You letters.\nType 'list' to see a list of donors, or input the donors full name to add a gift and send a Thank You letter. To return to the main menu, type 'Main Menu': ") + if user_input in donor_db: + amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) + donor_db[user_input].append(amtdonated) + thankyouletterdict = {"Name": user_input, "Amount": amtdonated} + print("+"*45 + "\nNice!\n Thanks, {Name} for the ${Amount}!\n\nSincerely, me\n".format(**thankyouletterdict) + "+"*45) + elif user_input == 'list': + for donor in donor_db: + print(donor + "\n") + elif user_input not in donor_db and user_input != 'Main Menu': + donor_db[user_input] = [] + print("Great, {} has been added to the donor database.".format(user_input)) + amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) + donor_db[user_input].append(amtdonated) + thankyouletterdict = {"Name": user_input, "Amount": amtdonated} + print("+" * 45 + "\nNice! Thanks, {Name} for the ${Amount}!\n\nSincerely, me\n".format( + **thankyouletterdict) + "+" * 45) + +def createreport(): + print(" Here is your report\n" + "="*45) + print("Donor Name | Total Given | Num Gifts | Average Gift") + print("--------------------------------------------------------") + l = max(len(donor) for donor in donor_db) + for donor in donor_db: + avg = sum(donor_db[donor])/len(donor_db[donor]) + print("{:20} |".format(donor), "${0:10,.2f}|".format(sum(donor_db[donor])), "{:>4} {:<4}|".format(len(donor_db[donor]),"gifts"), "${0:<10,.2f}".format(avg)) + main() + print("+++++++++++++++++++++") + +def createthankyouletters(): + for donor in donor_db: + with open('/Users/John/Python210-W19/students/johnwachter/mailroom/{}_letter.txt'.format(donor), 'w') as donorletter: + donorletter.write("+"*45 + "\nNice!\n\nThanks, {} for the ${}!\n\nSincerely, me\n".format(donor, donor_db[donor][-1]) + "+"*45) + +def quitprogram(): + print("Goodbye") + sys.exit() + +def responsedict(choice): + data = {'1': sendthankyou, '2': createreport, '3': createthankyouletters, '4': quitprogram} + return data.get(choice)() + main() + +def main(): + while True: + response = input(user_prompt) + try: + responsedict(response) + except TypeError as te: + print('Please enter 1 2 or 3', type(te)) + +if __name__ == "__main__": + main() From ab0a34f1d39782de3d97eb6a85ea1c0ce918e244 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 2 Feb 2019 14:52:56 -0800 Subject: [PATCH 26/41] adding donor history to the generated letters --- students/johnwachter/mailroom/mailroom2.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/students/johnwachter/mailroom/mailroom2.py b/students/johnwachter/mailroom/mailroom2.py index 59f98a1..9c94abf 100644 --- a/students/johnwachter/mailroom/mailroom2.py +++ b/students/johnwachter/mailroom/mailroom2.py @@ -44,10 +44,19 @@ def createreport(): main() print("+++++++++++++++++++++") +# def donorcategory(): +# for donor in donor_db: +# if int(sum(donor_db[donor])) < 10000: +# return 'measly' +# else: +# return 'generous' + def createthankyouletters(): for donor in donor_db: with open('/Users/John/Python210-W19/students/johnwachter/mailroom/{}_letter.txt'.format(donor), 'w') as donorletter: - donorletter.write("+"*45 + "\nNice!\n\nThanks, {} for the ${}!\n\nSincerely, me\n".format(donor, donor_db[donor][-1]) + "+"*45) + donorletter.write("+"*45 + "\nNice!\n\nThanks, {} for the ${}! You have given ${} since you started donating.\n\nSincerely, me\n".format(donor, donor_db[donor][-1], sum(donor_db[donor])) + "+"*45) + print("Letters generated.\n") + def quitprogram(): print("Goodbye") From 3e9e137a32adaa9c9da6ee53fa33a677e9dd01a2 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sun, 3 Feb 2019 17:39:30 -0800 Subject: [PATCH 27/41] built function to create trigrams from a list --- students/johnwachter/session04/trigrams.py | 49 ++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 students/johnwachter/session04/trigrams.py diff --git a/students/johnwachter/session04/trigrams.py b/students/johnwachter/session04/trigrams.py new file mode 100644 index 0000000..83d22a8 --- /dev/null +++ b/students/johnwachter/session04/trigrams.py @@ -0,0 +1,49 @@ +words = "I wish I may I wish I might".split() +def buildtrigrams(words): + trigrams = {} + for i in range(len(words) - 2): + pair = tuple(words[i:i + 2]) + followerlist = [words[i + 2]] + follower = words[i + 2] + if pair in trigrams: + trigrams[pair].append(follower) + elif pair not in trigrams: + trigrams.setdefault(pair, followerlist) + return trigrams + +if __name__ == "__main__": + trigrams = buildtrigrams(words) + print(buildtrigrams(words)) + # print("keys are {}".format(trigrams.keys())) + # print("values are {}".format(trigrams.values())) + + + + +#Take1 +# words = "I wish I may I wish I might I wish I may I wish I might".split() +# def buildtrigrams(words): +# trigrams = {} +# for i in range(len(words) - 2): +# pair = tuple(words[i:i + 2]) +# follower = [words[i + 2]] +# print(type(follower)) +# trigrams.setdefault(pair, follower) +# return trigrams +# +# if __name__ == "__main__": +# trigrams = buildtrigrams(words) +# print(buildtrigrams(words)) +# # print("keys are {}".format(trigrams.keys())) +# # print("values are {}".format(trigrams.values())) + +#Take2 +# words = "I wish I may I wish I might".split() +# def buildtrigrams(words): +# trigrams = {} +# for i in range(len(words) - 2): +# pair = tuple(words[i:i + 2]) +# follower = [words[i + 2]] +# trigrams.setdefault(pair, follower) +# trigrams[pair].append(follower) +# return trigrams From 0b2abf45d5dfb8b0c28bee1163a21c34b8794c1c Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sun, 3 Feb 2019 18:41:41 -0800 Subject: [PATCH 28/41] mixed words iterating through the dict, appending to a new list, and choosing items at random from the list --- students/johnwachter/session04/trigrams.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/students/johnwachter/session04/trigrams.py b/students/johnwachter/session04/trigrams.py index 83d22a8..3341569 100644 --- a/students/johnwachter/session04/trigrams.py +++ b/students/johnwachter/session04/trigrams.py @@ -1,4 +1,6 @@ -words = "I wish I may I wish I might".split() +import random + +words = "This random third of text data is meaningless".split() def buildtrigrams(words): trigrams = {} for i in range(len(words) - 2): @@ -11,11 +13,18 @@ def buildtrigrams(words): trigrams.setdefault(pair, followerlist) return trigrams +def mixwords(trilist): + completebook = [] + for item in trilist: + for i in item: + completebook.append(trigrams[item]) + for item in completebook: + print(" ".join(random.choice(completebook)), end=" ") + if __name__ == "__main__": trigrams = buildtrigrams(words) - print(buildtrigrams(words)) - # print("keys are {}".format(trigrams.keys())) - # print("values are {}".format(trigrams.values())) + trilist = list(buildtrigrams(words)) + mixwords(trilist) From 7f5fe9b0e1f03145e491545925a6b4fcd799d2d8 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Mon, 11 Feb 2019 11:52:50 -0800 Subject: [PATCH 29/41] two more pushups --- .../session04/pythonpushupsweek4.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 students/johnwachter/session04/pythonpushupsweek4.py diff --git a/students/johnwachter/session04/pythonpushupsweek4.py b/students/johnwachter/session04/pythonpushupsweek4.py new file mode 100644 index 0000000..d4a8ccc --- /dev/null +++ b/students/johnwachter/session04/pythonpushupsweek4.py @@ -0,0 +1,20 @@ +#Python Pushups - warmup 2 'array_font9' +def array_front9(nums): + checklist = nums[0:4] + if 9 in checklist: + return True + return False +print(array_front9([1, 9, 3, 4, 9])) + +def tempconverter(temp): + if temp[-1] == 'C': + celtemp = float(temp[:-1]) + tempinfar = ((celtemp)*(9/5) + 32) + return ("{} Farenheit".format(tempinfar)) + elif temp[-1] == 'F': + fartemp = float(temp[:-1]) + tempincel = (fartemp - 32)*(5/9) + return ("{} Celcius".format(tempincel)) + +tempinput = input("Enter a temperature, followed by 'F' or 'C'") +print(tempconverter(tempinput)) From 8294d0d613a60eb7fb153e965679f4f4d92ceb4f Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 16 Feb 2019 08:52:07 -0800 Subject: [PATCH 30/41] First Commit First Commit --- students/johnwachter/mailroom/mailroom3.py | 85 ++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 students/johnwachter/mailroom/mailroom3.py diff --git a/students/johnwachter/mailroom/mailroom3.py b/students/johnwachter/mailroom/mailroom3.py new file mode 100644 index 0000000..7d8209e --- /dev/null +++ b/students/johnwachter/mailroom/mailroom3.py @@ -0,0 +1,85 @@ +#tle: MailroomPart3.py +#Change Log: (Who, When, What) +#JWachter, 2019-02-10, Created File +#JWachter, 2019-02-10, put in some error handling +#JWachter, 2019-02-10, looked to use list comprehension, didn't find a good spot + + + +import sys + +donor_db = {"William Gates, III": [653772.32, 12.17], + "Jeff Bezos": [877.33], + "Paul Allen": [663.23, 43.87, 1.32], + "Mark Zuckerberg": [1663.23, 4300.87, 10432.0], + "Me Myself": [100]} +user_prompt = "\n".join(("Welcome to your Donor Database", "Please choose an option: ", "1 - Create One 'Thank You' Letter", "2 - Create a Report", "3 - Create Thank You letters for all donors", "4 - Quit\n")) + +def sendthankyou(): + user_input = "" + while user_input != "Main Menu": + try: + user_input = input("Let's send some Thank You letters.\nType 'list' to see a list of donors, or input the donors full name to add a gift and send a Thank You letter. To return to the main menu, type 'Main Menu': ") + if user_input in donor_db: + amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) + donor_db[user_input].append(amtdonated) + thankyouletterdict = {"Name": user_input, "Amount": amtdonated} + print("+"*45 + "\nNice!\n Thanks, {Name} for the ${Amount}!\n\nSincerely, me\n".format(**thankyouletterdict) + "+"*45) + elif user_input == 'list': + for donor in donor_db: + print(donor + "\n") + elif user_input not in donor_db and user_input != 'Main Menu': + donor_db[user_input] = [] + print("Great, {} has been added to the donor database.".format(user_input)) + amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) + donor_db[user_input].append(amtdonated) + thankyouletterdict = {"Name": user_input, "Amount": amtdonated} + print("+" * 45 + "\nNice! Thanks, {Name} for the ${Amount}!\n\nSincerely, me\n".format( + **thankyouletterdict) + "+" * 45) + except ValueError as ve: + print('please enter a valid number', type(ve)) +def createreport(): + print(" Here is your report\n" + "="*65) + print("Donor Name | Total Given | Num Gifts | Average Gift") + print("---------------------------------------------------------------") + for donor in donor_db: + try: + avg = sum(donor_db[donor])/len(donor_db[donor]) + print("{:20} |".format(donor), "${0:10,.2f}|".format(sum(donor_db[donor])), "{:>4} {:<4}|".format(len(donor_db[donor]),"gifts"), "${0:<10,.2f}".format(avg)) + except ZeroDivisionError: + print("{} has not given any gifts.".format(donor)) + main() + print("\n") +def donorcategory(): + for donor in donor_db: + if int(sum(donor_db[donor])) < 10000: + return 'measly' + else: + return 'generous' + +def createthankyouletters(): + for donor in donor_db: + with open('/Users/John/Python210-W19/students/johnwachter/mailroom/{}_letter.txt'.format(donor), 'w') as donorletter: + donorletter.write("+"*45 + "\nNice!\n\nThanks, {} for the ${}! You have given ${} since you started donating.\n\nSincerely, me\n".format(donor, donor_db[donor][-1], sum(donor_db[donor])) + "+"*45) + print("Letters generated.\n") + + +def quitprogram(): + print("Goodbye") + sys.exit() + +def responsedict(choice): + data = {'1': sendthankyou, '2': createreport, '3': createthankyouletters, '4': quitprogram} + return data.get(choice)() + main() + +def main(): + while True: + response = input(user_prompt) + try: + responsedict(response) + except TypeError as te: + print('Please enter 1 2 or 3', type(te)) + +if __name__ == "__main__": + main() From f46f77b6e06448aaf9e937c4f07584a5f4b61733 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 16 Feb 2019 10:28:34 -0800 Subject: [PATCH 31/41] changing report function --- students/johnwachter/mailroom/mailroom4.py | 98 ++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 students/johnwachter/mailroom/mailroom4.py diff --git a/students/johnwachter/mailroom/mailroom4.py b/students/johnwachter/mailroom/mailroom4.py new file mode 100644 index 0000000..9c9da8c --- /dev/null +++ b/students/johnwachter/mailroom/mailroom4.py @@ -0,0 +1,98 @@ + + +D +git commit mailroom4.py -m "changing report function" + + +ž + + 2019-02-16, Created File +#JWachter, 2019-02-10, put in some error handling +#JWachter, 2019-02-10, looked to use list comprehension, didn't find a good spot + + +import sys + +donor_db = {"William Gates, III": [653772.32, 12.17], + "Jeff Bezos": [877.33], + "Paul Allen": [663.23, 43.87, 1.32], + "Mark Zuckerberg": [1663.23, 4300.87, 10432.0], + "Me Myself": [100]} +user_prompt = "\n".join(("Welcome to your Donor Database", "Please choose an option: ", "1 - Create One 'Thank You' Letter", "2 - Create a Report", "3 - Create Thank You letters for all donors", "4 - Quit\n")) + + +def sendthankyou(): + user_input = "" + while user_input != "Main Menu": + try: + user_input = input("Let's send some Thank You letters.\nType 'list' to see a list of donors, or input the donors full name to add a gift and send a Thank You letter. To return to the main menu, type 'Main Menu': ") + if user_input in donor_db: + amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) + donor_db[user_input].append(amtdonated) + thankyouletterdict = {"Name": user_input, "Amount": amtdonated} + print("+"*45 + "\nNice!\n Thanks, {Name} for the ${Amount}!\n\nSincerely, me\n".format(**thankyouletterdict) + "+"*45) + elif user_input == 'list': + for donor in donor_db: + print(donor + "\n") + elif user_input not in donor_db and user_input != 'Main Menu': + donor_db[user_input] = [] + print("Great, {} has been added to the donor database.".format(user_input)) + amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) + donor_db[user_input].append(amtdonated) + thankyouletterdict = {"Name": user_input, "Amount": amtdonated} + print("+" * 45 + "\nNice! Thanks, {Name} for the ${Amount}!\n\nSincerely, me\n".format( + **thankyouletterdict) + "+" * 45) + except ValueError as ve: + print('please enter a valid number', type(ve)) +# def createreport(): +# print(" Here is your report\n" + "="*65) +# print("Donor Name | Total Given | Num Gifts | Average Gift") +# print("---------------------------------------------------------------") +# for donor in donor_db: +# try: +# avg = sum(donor_db[donor])/len(donor_db[donor]) +# print("{:20} |".format(donor), "${0:10,.2f}|".format(sum(donor_db[donor])), "{:>4} {:<4}|".format(len(donor_db[donor]),"gifts"), "${0:<10,.2f}".format(avg)) +# except ZeroDivisionError: +# print("{} has not given any gifts.".format(donor)) +# main() +# print("\n") + +def createreport2(): + reportstring = str(" Here is your report\n" + "="*65 + "\n" + "Donor Name | Total Given | Num Gifts | Average Gift\n" + + "---------------------------------------------------------------" + "\n") + for donor in donor_db: + avg = sum(donor_db[donor])/len(donor_db[donor]) + reportstring += "{:20} | ${:10,.2f}| {:>4} {:<4}| ${:<10,.2f} \n".format(donor, sum(donor_db[donor]), len(donor_db[donor]), "gifts", avg) + return reportstring + +def displayreport(report = createreport2()): + print(report) + print("\n") + + +def createthankyouletters(): + for donor in donor_db: + with open('/Users/John/Python210-W19/students/johnwachter/mailroom/{}_letter.txt'.format(donor), 'w') as donorletter: + donorletter.write("+"*45 + "\nNice!\n\nThanks, {} for the ${}! You have given ${} since you started donating.\n\nSincerely, me\n".format(donor, donor_db[donor][-1], sum(donor_db[donor])) + "+"*45) + print("Letters generated.\n") + + +def quitprogram(): + print("Goodbye") + sys.exit() + +def responsedict(choice): + data = {'1': sendthankyou, '2': displayreport(), '3': createthankyouletters, '4': quitprogram} + return data.get(choice)() + main() + +def main(): + while True: + response = input(user_prompt) + try: + responsedict(response) + except TypeError as te: + print('Please enter 1 2 or 3', type(te)) + +if __name__ == "__main__": + main() From 04cd604beeea71cdc9667b7321621257f8af8323 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 16 Feb 2019 13:19:30 -0800 Subject: [PATCH 32/41] split the thank you letter text and the file creation functions into two functions --- students/johnwachter/mailroom/mailroom4.py | 82 ++++++++++------------ 1 file changed, 37 insertions(+), 45 deletions(-) diff --git a/students/johnwachter/mailroom/mailroom4.py b/students/johnwachter/mailroom/mailroom4.py index 9c9da8c..e59e0c8 100644 --- a/students/johnwachter/mailroom/mailroom4.py +++ b/students/johnwachter/mailroom/mailroom4.py @@ -1,13 +1,7 @@ - - -D -git commit mailroom4.py -m "changing report function" - - -ž - - 2019-02-16, Created File -#JWachter, 2019-02-10, put in some error handling +#Title: MailroomPart4.py +#Change Log: (Who, When, What) +#JWachter, 2019-02-16, Created File +#JWachter, 2019-02-16, Updated create report function to split data processing and data presentation. Now have 2 funcs #JWachter, 2019-02-10, looked to use list comprehension, didn't find a good spot @@ -20,60 +14,55 @@ "Me Myself": [100]} user_prompt = "\n".join(("Welcome to your Donor Database", "Please choose an option: ", "1 - Create One 'Thank You' Letter", "2 - Create a Report", "3 - Create Thank You letters for all donors", "4 - Quit\n")) - -def sendthankyou(): +def sendthankyou(database = donor_db): user_input = "" + donorlist = [] while user_input != "Main Menu": try: user_input = input("Let's send some Thank You letters.\nType 'list' to see a list of donors, or input the donors full name to add a gift and send a Thank You letter. To return to the main menu, type 'Main Menu': ") if user_input in donor_db: - amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) - donor_db[user_input].append(amtdonated) + amtdonated = int(input("Please enter the amount donated: ")) + database[user_input].append(amtdonated) thankyouletterdict = {"Name": user_input, "Amount": amtdonated} print("+"*45 + "\nNice!\n Thanks, {Name} for the ${Amount}!\n\nSincerely, me\n".format(**thankyouletterdict) + "+"*45) - elif user_input == 'list': - for donor in donor_db: + elif user_input == "list": + for donor in database: + donorlist.append(donor) print(donor + "\n") - elif user_input not in donor_db and user_input != 'Main Menu': - donor_db[user_input] = [] + elif user_input not in database and user_input != 'Main Menu': + database[user_input] = [] print("Great, {} has been added to the donor database.".format(user_input)) amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) - donor_db[user_input].append(amtdonated) + database[user_input].append(amtdonated) thankyouletterdict = {"Name": user_input, "Amount": amtdonated} - print("+" * 45 + "\nNice! Thanks, {Name} for the ${Amount}!\n\nSincerely, me\n".format( - **thankyouletterdict) + "+" * 45) + print("+" * 45 + "\nNice! Thanks, {Name} for the ${Amount}!\n\nSincerely, me\n".format(**thankyouletterdict) + "+" * 45) except ValueError as ve: print('please enter a valid number', type(ve)) -# def createreport(): -# print(" Here is your report\n" + "="*65) -# print("Donor Name | Total Given | Num Gifts | Average Gift") -# print("---------------------------------------------------------------") -# for donor in donor_db: -# try: -# avg = sum(donor_db[donor])/len(donor_db[donor]) -# print("{:20} |".format(donor), "${0:10,.2f}|".format(sum(donor_db[donor])), "{:>4} {:<4}|".format(len(donor_db[donor]),"gifts"), "${0:<10,.2f}".format(avg)) -# except ZeroDivisionError: -# print("{} has not given any gifts.".format(donor)) -# main() -# print("\n") -def createreport2(): - reportstring = str(" Here is your report\n" + "="*65 + "\n" + "Donor Name | Total Given | Num Gifts | Average Gift\n" + - "---------------------------------------------------------------" + "\n") - for donor in donor_db: - avg = sum(donor_db[donor])/len(donor_db[donor]) - reportstring += "{:20} | ${:10,.2f}| {:>4} {:<4}| ${:<10,.2f} \n".format(donor, sum(donor_db[donor]), len(donor_db[donor]), "gifts", avg) +def createreport(database = donor_db): + try: + reportstring = str(" Here is your report\n" + "="*65 + "\n" + "Donor Name | Total Given | Num Gifts | Average Gift\n" + + "---------------------------------------------------------------" + "\n") + for donor in database: + avg = sum(database[donor])/len(database[donor]) + reportstring += "{:20} | ${:10,.2f}| {:>4} {:<4}| ${:<10,.2f} \n".format(donor, sum(database[donor]), len(database[donor]), "gifts", avg) + except ZeroDivisionError as zde: + print("{} has not given any gifts.".format(donor)) return reportstring -def displayreport(report = createreport2()): - print(report) +def displayreport(): + print(createreport(donor_db)) print("\n") +def tylettertxt(): + for donor in donor_db: + txt = "+"*45 + "\nNice!\n\nThanks, {} for the ${}! You have given ${} since you started donating.\n\nSincerely, me\n".format(donor, donor_db[donor][-1], sum(donor_db[donor])) + "+"*45 + return txt -def createthankyouletters(): +def createthankyouletters(txt = tylettertxt()): for donor in donor_db: with open('/Users/John/Python210-W19/students/johnwachter/mailroom/{}_letter.txt'.format(donor), 'w') as donorletter: - donorletter.write("+"*45 + "\nNice!\n\nThanks, {} for the ${}! You have given ${} since you started donating.\n\nSincerely, me\n".format(donor, donor_db[donor][-1], sum(donor_db[donor])) + "+"*45) + donorletter.write(txt) print("Letters generated.\n") @@ -82,8 +71,11 @@ def quitprogram(): sys.exit() def responsedict(choice): - data = {'1': sendthankyou, '2': displayreport(), '3': createthankyouletters, '4': quitprogram} - return data.get(choice)() + casedict = {'1': sendthankyou, '2': displayreport, '3': createthankyouletters, '4': quitprogram} + if casedict.get(choice) == "1": + return casedict.get(choice) + else: + return casedict.get(choice)() main() def main(): From a4cd2fc794184e363602ab557abe99236638239b Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 16 Feb 2019 19:32:35 -0800 Subject: [PATCH 33/41] created two helper functions and put them inside the sendthankyou function to make that function do only one thing as opposed to 3 --- students/johnwachter/mailroom/mailroom4.py | 64 +++++++++++++--------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/students/johnwachter/mailroom/mailroom4.py b/students/johnwachter/mailroom/mailroom4.py index e59e0c8..b3038ee 100644 --- a/students/johnwachter/mailroom/mailroom4.py +++ b/students/johnwachter/mailroom/mailroom4.py @@ -2,7 +2,7 @@ #Change Log: (Who, When, What) #JWachter, 2019-02-16, Created File #JWachter, 2019-02-16, Updated create report function to split data processing and data presentation. Now have 2 funcs -#JWachter, 2019-02-10, looked to use list comprehension, didn't find a good spot +#JWachter, 2019-02-16, Added two new helper functions to print an email and add donor info to the database, pulling them out of the send thank you function import sys @@ -14,31 +14,38 @@ "Me Myself": [100]} user_prompt = "\n".join(("Welcome to your Donor Database", "Please choose an option: ", "1 - Create One 'Thank You' Letter", "2 - Create a Report", "3 - Create Thank You letters for all donors", "4 - Quit\n")) -def sendthankyou(database = donor_db): +def sendthankyou(database=donor_db): user_input = "" donorlist = [] - while user_input != "Main Menu": - try: - user_input = input("Let's send some Thank You letters.\nType 'list' to see a list of donors, or input the donors full name to add a gift and send a Thank You letter. To return to the main menu, type 'Main Menu': ") - if user_input in donor_db: - amtdonated = int(input("Please enter the amount donated: ")) - database[user_input].append(amtdonated) - thankyouletterdict = {"Name": user_input, "Amount": amtdonated} - print("+"*45 + "\nNice!\n Thanks, {Name} for the ${Amount}!\n\nSincerely, me\n".format(**thankyouletterdict) + "+"*45) - elif user_input == "list": - for donor in database: - donorlist.append(donor) - print(donor + "\n") - elif user_input not in database and user_input != 'Main Menu': - database[user_input] = [] - print("Great, {} has been added to the donor database.".format(user_input)) - amtdonated = int(input("Please enter the amount donated by {}: ".format(user_input))) - database[user_input].append(amtdonated) - thankyouletterdict = {"Name": user_input, "Amount": amtdonated} - print("+" * 45 + "\nNice! Thanks, {Name} for the ${Amount}!\n\nSincerely, me\n".format(**thankyouletterdict) + "+" * 45) - except ValueError as ve: - print('please enter a valid number', type(ve)) + while user_input.lower() != "Main Menu": + user_input = input( + "Let's send some Thank You letters.\nType 'list' to see a list of donors, or input the donors full name to add a gift and send a Thank You letter. To return to the main menu, type 'Main Menu': ") + if user_input == "list": + for donor in database: + donorlist.append(donor) + print(donor + "\n") + elif user_input != "Main Menu": + amtdonated = int(input("Please enter the amount donated: ")) + adddonation(user_input, amtdonated, database) + print(tyemail(user_input, amtdonated)) + else: + main() + +def adddonation(userinput, donationamount, database=donor_db): + try: + if userinput in database: + database[userinput].append(donationamount) + else: + database[userinput] = [donationamount] + except ValueError as ve: + print('Please enter a valid number', type(ve)) + return database +def tyemail(user_input, amtdonated): + thankyouletterdict = {"Name": user_input, "Amount": amtdonated} + print("+" * 45 + "\nNice!\n Thanks, {Name} for the ${Amount}!\n\nSincerely, me\n".format( + **thankyouletterdict) + "+" * 45) + def createreport(database = donor_db): try: reportstring = str(" Here is your report\n" + "="*65 + "\n" + "Donor Name | Total Given | Num Gifts | Average Gift\n" + @@ -55,14 +62,17 @@ def displayreport(): print("\n") def tylettertxt(): + listtxt = {} for donor in donor_db: - txt = "+"*45 + "\nNice!\n\nThanks, {} for the ${}! You have given ${} since you started donating.\n\nSincerely, me\n".format(donor, donor_db[donor][-1], sum(donor_db[donor])) + "+"*45 - return txt + #txt = "+"*45 + "\nNice!\n\nThanks, {} for the ${}! You have given ${} since you started donating.\n\nSincerely, me\n".format(donor, donor_db[donor][-1], sum(donor_db[donor])) + "+"*45 + listtxt.update({donor: "+"*45 + "\nNice!\n\nThanks, {} for the ${}! You have given ${} since you started donating.\n\nSincerely, me\n".format(donor, donor_db[donor][-1], sum(donor_db[donor])) + "+"*45}) + print(listtxt) + return listtxt def createthankyouletters(txt = tylettertxt()): for donor in donor_db: with open('/Users/John/Python210-W19/students/johnwachter/mailroom/{}_letter.txt'.format(donor), 'w') as donorletter: - donorletter.write(txt) + donorletter.write(txt) print("Letters generated.\n") @@ -74,6 +84,8 @@ def responsedict(choice): casedict = {'1': sendthankyou, '2': displayreport, '3': createthankyouletters, '4': quitprogram} if casedict.get(choice) == "1": return casedict.get(choice) + elif casedict.get(choice) == "3": + return casedict.get(choice(tylettertxt())) else: return casedict.get(choice)() main() From 5ea7a06dc74e72568103639712cdf49e0dd13e75 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 16 Feb 2019 21:18:43 -0800 Subject: [PATCH 34/41] created another helper function to create the list of donors, and now call this function inside of the sendthankyou function --- students/johnwachter/mailroom/mailroom4.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/students/johnwachter/mailroom/mailroom4.py b/students/johnwachter/mailroom/mailroom4.py index b3038ee..a70a8fb 100644 --- a/students/johnwachter/mailroom/mailroom4.py +++ b/students/johnwachter/mailroom/mailroom4.py @@ -4,7 +4,6 @@ #JWachter, 2019-02-16, Updated create report function to split data processing and data presentation. Now have 2 funcs #JWachter, 2019-02-16, Added two new helper functions to print an email and add donor info to the database, pulling them out of the send thank you function - import sys donor_db = {"William Gates, III": [653772.32, 12.17], @@ -16,14 +15,11 @@ def sendthankyou(database=donor_db): user_input = "" - donorlist = [] while user_input.lower() != "Main Menu": user_input = input( "Let's send some Thank You letters.\nType 'list' to see a list of donors, or input the donors full name to add a gift and send a Thank You letter. To return to the main menu, type 'Main Menu': ") if user_input == "list": - for donor in database: - donorlist.append(donor) - print(donor + "\n") + print("\n", donorlist(), "\n") elif user_input != "Main Menu": amtdonated = int(input("Please enter the amount donated: ")) adddonation(user_input, amtdonated, database) @@ -31,6 +27,12 @@ def sendthankyou(database=donor_db): else: main() +def donorlist(): + donorlist = [] + for donor in donor_db: + donorlist.append(donor) + return donorlist + def adddonation(userinput, donationamount, database=donor_db): try: if userinput in database: @@ -45,7 +47,7 @@ def tyemail(user_input, amtdonated): thankyouletterdict = {"Name": user_input, "Amount": amtdonated} print("+" * 45 + "\nNice!\n Thanks, {Name} for the ${Amount}!\n\nSincerely, me\n".format( **thankyouletterdict) + "+" * 45) - + def createreport(database = donor_db): try: reportstring = str(" Here is your report\n" + "="*65 + "\n" + "Donor Name | Total Given | Num Gifts | Average Gift\n" + @@ -64,15 +66,13 @@ def displayreport(): def tylettertxt(): listtxt = {} for donor in donor_db: - #txt = "+"*45 + "\nNice!\n\nThanks, {} for the ${}! You have given ${} since you started donating.\n\nSincerely, me\n".format(donor, donor_db[donor][-1], sum(donor_db[donor])) + "+"*45 listtxt.update({donor: "+"*45 + "\nNice!\n\nThanks, {} for the ${}! You have given ${} since you started donating.\n\nSincerely, me\n".format(donor, donor_db[donor][-1], sum(donor_db[donor])) + "+"*45}) - print(listtxt) return listtxt def createthankyouletters(txt = tylettertxt()): for donor in donor_db: with open('/Users/John/Python210-W19/students/johnwachter/mailroom/{}_letter.txt'.format(donor), 'w') as donorletter: - donorletter.write(txt) + donorletter.write(txt) print("Letters generated.\n") From c303230eb31cc5c1e4a472ef306a7e2aa4772deb Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 16 Feb 2019 21:19:47 -0800 Subject: [PATCH 35/41] added test to check if the function creates the files it is supposed to --- .../johnwachter/mailroom/test_mailroom4.py | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 students/johnwachter/mailroom/test_mailroom4.py diff --git a/students/johnwachter/mailroom/test_mailroom4.py b/students/johnwachter/mailroom/test_mailroom4.py new file mode 100644 index 0000000..4fbd0dd --- /dev/null +++ b/students/johnwachter/mailroom/test_mailroom4.py @@ -0,0 +1,36 @@ +from os import path +from mailroom4 import createreport +from mailroom4 import displayreport +from mailroom4 import tylettertxt + +newdb= {"Me":[2,2]} + +fullpath1 = r"C:\\Users\\John\\Python210-W19\\students\\johnwachter\\mailroom\\Me Myself_letter.txt" +fullpath2 = r"C:\\Users\\John\\Python210-W19\\students\\johnwachter\\mailroom\\Jeff Bezos_letter.txt" +fullpath3 = r"C:\\Users\\John\\Python210-W19\\students\\johnwachter\\mailroom\\Mark Zuckerberg_letter.txt" +fullpath4 = r"C:\\Users\\John\\Python210-W19\\students\\johnwachter\\mailroom\\Paul Allen_letter.txt" +fullpath5 = r"C:\\Users\\John\\Python210-W19\\students\\johnwachter\\mailroom\\William Gates, III_letter.txt" + +def test_1(): + assert createreport(newdb) == 2 + print("test_1 passed") + + +def test_2(): + assert path.exists(fullpath1) + print("The file ending with {} does exist | Pass".format(fullpath1[-20:])) + assert path.exists(fullpath2) + print("The file ending with {} does exist | Pass".format(fullpath2[-20:])) + assert path.exists(fullpath3) + print("The file ending with {} does exist | Pass".format(fullpath3[-20:])) + assert path.exists(fullpath4) + print("The file ending with {} does exist | Pass".format(fullpath4[-20:])) + assert path.exists(fullpath5) + print("The file ending with {} does exist | Pass".format(fullpath5[-20:])) + +test_2() + + + + + From ecc831d2f32bcbfb4405cddb818789a4dbb58090 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 16 Feb 2019 21:26:02 -0800 Subject: [PATCH 36/41] added test to check if the adddonation function properly adds a new donor and amount to a database --- students/johnwachter/mailroom/test_mailroom4.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/students/johnwachter/mailroom/test_mailroom4.py b/students/johnwachter/mailroom/test_mailroom4.py index 4fbd0dd..a88cbce 100644 --- a/students/johnwachter/mailroom/test_mailroom4.py +++ b/students/johnwachter/mailroom/test_mailroom4.py @@ -2,8 +2,9 @@ from mailroom4 import createreport from mailroom4 import displayreport from mailroom4 import tylettertxt +from mailroom4 import adddonation -newdb= {"Me":[2,2]} +testdb = {} fullpath1 = r"C:\\Users\\John\\Python210-W19\\students\\johnwachter\\mailroom\\Me Myself_letter.txt" fullpath2 = r"C:\\Users\\John\\Python210-W19\\students\\johnwachter\\mailroom\\Jeff Bezos_letter.txt" @@ -12,11 +13,6 @@ fullpath5 = r"C:\\Users\\John\\Python210-W19\\students\\johnwachter\\mailroom\\William Gates, III_letter.txt" def test_1(): - assert createreport(newdb) == 2 - print("test_1 passed") - - -def test_2(): assert path.exists(fullpath1) print("The file ending with {} does exist | Pass".format(fullpath1[-20:])) assert path.exists(fullpath2) @@ -28,6 +24,11 @@ def test_2(): assert path.exists(fullpath5) print("The file ending with {} does exist | Pass".format(fullpath5[-20:])) +def test_2(): + assert adddonation("Me Myself", "900", database = testdb) == {"Me Myself":['900']} + print("passed") + +test_1() test_2() From a4e419c03a4e90bcb188e28057e6a8edb9d53e58 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sat, 16 Feb 2019 22:31:49 -0800 Subject: [PATCH 37/41] adding multiple tests to check the donorlist function which should return just a list of the keys in the donor database dictionary --- .../johnwachter/mailroom/test_mailroom4.py | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/students/johnwachter/mailroom/test_mailroom4.py b/students/johnwachter/mailroom/test_mailroom4.py index a88cbce..eef50c1 100644 --- a/students/johnwachter/mailroom/test_mailroom4.py +++ b/students/johnwachter/mailroom/test_mailroom4.py @@ -3,8 +3,12 @@ from mailroom4 import displayreport from mailroom4 import tylettertxt from mailroom4 import adddonation +from mailroom4 import donorlist -testdb = {} +test2db = {} +test3db = {} +test4db = {'testdonor': 1} +test5db = {'testdonor': 1, 'testdonor2': 2} fullpath1 = r"C:\\Users\\John\\Python210-W19\\students\\johnwachter\\mailroom\\Me Myself_letter.txt" fullpath2 = r"C:\\Users\\John\\Python210-W19\\students\\johnwachter\\mailroom\\Jeff Bezos_letter.txt" @@ -13,6 +17,7 @@ fullpath5 = r"C:\\Users\\John\\Python210-W19\\students\\johnwachter\\mailroom\\William Gates, III_letter.txt" def test_1(): + """Tests if the files that the function is supposed to create actually exist""" assert path.exists(fullpath1) print("The file ending with {} does exist | Pass".format(fullpath1[-20:])) assert path.exists(fullpath2) @@ -25,13 +30,29 @@ def test_1(): print("The file ending with {} does exist | Pass".format(fullpath5[-20:])) def test_2(): - assert adddonation("Me Myself", "900", database = testdb) == {"Me Myself":['900']} - print("passed") - + """Tests if the function that adds donors and amounts to the database works""" + assert adddonation("Me Myself", "900", database = test2db) == {"Me Myself":['900']} + print("Test_2 passed") + +def test_3(): + """Assert not is used to check if the database is empty""" + assert not donorlist(test3db) + print("Test_3 passed") + +def test_4(): + """Checks if the donorlist function will return a list of donors that is passed to it""" + assert donorlist(test4db) == ['testdonor'] + print("Test_4 passed") + +def test_5(): + assert donorlist(test5db) == ['testdonor', 'testdonor2'] + print("Test_5 passed") + test_1() test_2() - - +test_3() +test_4() +test_5() From ac073ab27e49106d42a1cd1bb83c205943403043 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sun, 3 Mar 2019 13:14:39 -0800 Subject: [PATCH 38/41] 4 more pushup exercises --- .../session06/pythonpushupsweek6.py | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 students/johnwachter/session06/pythonpushupsweek6.py diff --git a/students/johnwachter/session06/pythonpushupsweek6.py b/students/johnwachter/session06/pythonpushupsweek6.py new file mode 100644 index 0000000..1aa59f5 --- /dev/null +++ b/students/johnwachter/session06/pythonpushupsweek6.py @@ -0,0 +1,53 @@ +#Given a string and a non-negative int n, we'll say that the front of the string is the first 3 chars, or whatever is there if the string is less than length 3. Return n copies of the front; +def front_times(str, n): + if n >0: + return str[0:3]*n + else: + return False + +#Given a string, return a new string made of every other char starting with the first, so "Hello" yields "Hlo". +def string_bits(str): + return str[0::2] + +#Given a non-empty string like "Code" return a string like "CCoCodCode". +def string_splosion(str): + if str: + counter = 0 + string = "" + while counter <= len(str): + string += str[0:counter] + counter +=1 + return string + +#Given a string, return the count of the number of times that a substring length 2 appears in the string and also as the last 2 chars of the string, so "hixxxhi" yields 1 (we won't count the end substring). +def last2(stri): + if len(stri) < 2: + return 0 + else: + counter = 0 + try: + target = stri[-2:] + for i in range(len(stri) -2): + sub = stri[i:i + 2] + if sub == target: + counter += 1 + except TypeError as te: + return ("error is {}".format(te)) + return counter + + +print(front_times('Chocolate', 2)) +front_times('Chocolate', 3) +front_times('Abc', 3) + +string_bits('Hello') +string_bits('Hi') +string_bits('Heeololeo') + +string_splosion('Code') +string_splosion('abc') +string_splosion('ab') + +last2('hixxhi') +last2('xaxxaxaxx') +last2('axxxaaxx') From baf4dcc50cd7eed3e928f50d4d1a88fa8c8bfa2c Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sun, 10 Mar 2019 13:10:51 -0700 Subject: [PATCH 39/41] data model is working, so committing to github as a backup --- .../johnwachter/Final_Project/DataModel.py | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 students/johnwachter/Final_Project/DataModel.py diff --git a/students/johnwachter/Final_Project/DataModel.py b/students/johnwachter/Final_Project/DataModel.py new file mode 100644 index 0000000..1b292a9 --- /dev/null +++ b/students/johnwachter/Final_Project/DataModel.py @@ -0,0 +1,126 @@ +from datetime import datetime +import re as rex + +class Product(object): + def __init__(self, product_id: int, product_name: str): + self.__product_id = product_id + self.__product_name = product_name + def __str__(self): + return("ProductID: {}, ProductName: {}".format(self.__product_id, self.__product_name)) + def __repr__(self): + return "{i}:[{brk1}{pi}{p}, {c}:{cv}{brk2}]".format(brk1='{', i="Product", + pi="'ProductID':", + p=self.__product_id, + c="'ProductName'", + cv=self.__product_name, brk2='}') + def __dict__(self): + return {"ProductID": self.__product_id, "ProductName": self.__product_name} + @property + def product_id(self): + return self.__product_id + def set_product_id(self, product_id): + if type(product_id) is not int: + raise TypeError("Requires integer!") + if product_id <= 0: + raise ValueError("Requires value greater than zero!") + else: + self.__product_id = product_id + @property + def product_name(self): + return self.__product_name + def set_product_name(self, product_name): + self.__product_name = str(product_name).strip() + +class InventoryCount(object): + def __init__(self, product: Product, count: int): + self.__product = product + self.__count = count + def __str__(self): + return ("Product: ({}), Number of products: {}".format(self.__product, self.__count)) + def __repr__(self): + return "{i}:[{p}, {c}:{cv}]".format(i="InventoryCount", + p=self.product.__repr__(), + c="count", + cv=self.count) + def __dict__(self): + return {"Product": self.__product, "Count": self.__count} + @property + def product(self): + return self.__product + def set_product(self, product): + if type(product) is not Product: raise TypeError("Requires Product Object!") + else: + self.__product = product + @property + def count(self): + return self.__count + def set_count(self, count): + if count < 0: + raise ValueError("Negative counts are not possible") + self.__count = count + +class Inventory(object): + def __init__(self, inventory_id: int, inventory_date: datetime.date, inventory_counts: InventoryCount = [None]): + self.__inventory_id = inventory_id + self.__inventory_date = inventory_date + self.__inventory_counts = inventory_counts + def __str__(self): + return("InventoryID: {}, InventoryDate: {}, InventoryCount: {}".format(self.__inventory_id, self.__inventory_date, self.__inventory_counts)) + def __repr__(self): + return "{d}, {i}:[{p}, {c}:{cv}]".format(d=self.__inventory_date, + i="InventoryID", + p=self.__inventory_id.__repr__(), + c="count", + cv=self.__inventory_counts.__repr__()) + def __dict__(self): + return {"InventoryID": self.__inventory_id, "InventoryDate": self.__InventoryDate, "InventoryCount": self.__inventory_counts} + @property + def inventory_id(self): + return self.__inventory_id + def set_inventory_id(self, inventory_id): + if inventory_id < 0: + raise TypeError("Can't have a negative InventoryID!") + else: + self.__inventory_id = inventory_id + @property + def inventory_date(self): + return self.__inventory_date + def set_inventory_date(self, inventory_date): + try: + if rex.match("\d\d\d\d-\d\d-\d\d", str(inventory_date)) is None: + raise TypeError("Not a Date! Use the following format: YYYY-MM-DD") + else: + self.__inventory_date = inventory_date + except Exception as e: + raise e + @property + def inventory_counts(self): + return self.__inventory_counts + def set_inventory_counts(self, inventory_counts): + if inventory_counts is not None and type(inventory_counts) is InventoryCount: + self.inventory_counts = inventory_counts + +if __name__ == '__main__': + p1 = Product(100, "ProdA") + p2 = Product(200, "ProdB") + #print("P1 str function produces:\n{}".format(p1)) + #print(p2.product_id) + #print(repr(p1)) + p2.set_product_id(1) + #print(p2.product_id) + ic1 = InventoryCount(p1, 15) + ic2 = InventoryCount(p2, 45) + #print(repr(ic1)) + #print("ic1 str function produces:\n{}".format(ic1)) + invJan0119 = Inventory(1, '2019-01-01', [ic1,ic2]) + invFeb0119 = Inventory(2, '2020-01-01', [ic1]) + print("repr func produces: {}".format(repr(invFeb0119))) + print("Str func produces: {}".format(invFeb0119)) + print("repr func produces: {}".format(repr(invJan0119))) + print("Str func produces: {}".format(invJan0119)) + #for ic in invJan0119.inventory_counts: + #print(invJan0119.inventory_date , ic.product.product_name, ' = ', ic.count) + invJan0119.set_inventory_date('2019-09-01') + #print(invJan0119.inventory_date) + print(dict()) + From 86aa9562b694c6d2b8e749c6cbfa5e8302a31f5f Mon Sep 17 00:00:00 2001 From: johnwachter Date: Sun, 10 Mar 2019 13:11:10 -0700 Subject: [PATCH 40/41] data processor is working so adding to github as a backup --- .../Final_Project/DataProcessor.py | 294 ++++++++++++++++++ 1 file changed, 294 insertions(+) create mode 100644 students/johnwachter/Final_Project/DataProcessor.py diff --git a/students/johnwachter/Final_Project/DataProcessor.py b/students/johnwachter/Final_Project/DataProcessor.py new file mode 100644 index 0000000..2d9a2c8 --- /dev/null +++ b/students/johnwachter/Final_Project/DataProcessor.py @@ -0,0 +1,294 @@ +import sqlite3 +from sqlite3 import Error as sqlErr +import re as rex + +def create_connection(db_file: str ="C:\sqlite\sqlite\Python210FinalDB.db"): + """ Create or connect to a SQLite database """ + try: + con = sqlite3.connect(db_file) + except sqlErr as se: + raise Exception('SQL Error in create_connection(): ' + se.__str__()) + except Exception as e: + raise Exception('General Error in create_connection(): ' + e.__str__()) + return con + +# SQL Validators +def check_for_extra_semicolon(sql_str): + """Checks for an extra semicolon""" + # print(len("Select;Delete From T1; ID, Name FROM T1;".split(';')) > 2) + try: + if len(sql_str.split(';')) > 2: + raise sqlErr("Extra Semi-Colon Detected!") + except Exception as e: + raise e + + +def check_for_or(sql_str): + """Checks for an injected OR in tampered WHERE Clause""" + # print(rex.search("WHERE", "SELECT * FROM T1 WHERE", rex.IGNORECASE)) + # print(rex.search("or","FROM T1 WHERE ID = 1 or 1 = 1".split('WHERE')[1], rex.IGNORECASE)) + try: + if rex.search("WHERE", sql_str, rex.IGNORECASE): #If it has a Where clause + if rex.search(' or ', sql_str.split('WHERE')[1], rex.IGNORECASE) is not None: # check injected OR + raise sqlErr("OR Detected!") + except Exception as e: + raise e + +def check_for_date(date_str): #Inventories table check + try: + if rex.match("\d\d\d\d-\d\d-\d\d", str(date_str)) is None: # Returns None if not matched + raise sqlErr("Not a Date!") + except Exception as e: + raise e + +# def execute_sql_code(db_con: object = None, sql_code: str = ''): +# """ Execute SQL code on a open connection """ +# try: +# if db_con is not None and sql_code != '': +# # Validate +# check_for_extra_semicolon(sql_code); +# check_for_or(sql_code); +# # Connect and Run +# with db_con: +# csr = db_con.cursor() +# csr.execute(sql_code) +# else: +# raise Exception('SQL Code or Connection is missing!') +# except sqlite3.OperationalError as oe: +# raise Exception('Table already exists(): ' + oe.__str__()) +# except sqlErr as se: +# raise Exception('SQL Error in execute_sql_code(): ' + se.__str__() + 'That ID already exists, and ID is a primary key') +# except Exception as e: +# raise Exception('General Error in execute_sql_code(): ' + e.__str__()) +# return csr + + +class DBProcessor(object): + def __init__(self, db_name: str = "C:\sqlite\sqlite\Python210FinalDB.db"): + self.__db_name = db_name + self.__db_con = self.create_connection(self.db_name) + + @property + def db_name(self): # Get DB Name + return self.__db_name + + @property + def db_con(self): # Get Live Connection + return self.__db_con + + # SQL Validators + @staticmethod + def check_for_extra_semicolon(sql_str): + """Checks for an extra semicolon""" + # print(len("Select;Delete From T1; ID, Name FROM T1;".split(';')) > 2) + try: + if len(sql_str.split(';')) > 2: + raise sqlErr("Extra Semi-Colon Detected!") + except Exception as e: + raise e + + @staticmethod + def check_for_or(sql_str): + """Checks for an injected OR in tampered WHERE Clause""" + # print(rex.search("WHERE", "SELECT * FROM T1 WHERE", rex.IGNORECASE)) + # print(rex.search("or","FROM T1 WHERE ID = 1 or 1 = 1".split('WHERE')[1], rex.IGNORECASE)) + try: + if rex.search("WHERE", sql_str, rex.IGNORECASE): # If it has a Where clause + if rex.search(' or ', sql_str.split('WHERE')[1], rex.IGNORECASE) is not None: # injected OR? + raise sqlErr("OR Detected!") + except Exception as e: + raise e + + @staticmethod + def check_for_date(date_str): # Inventories table check + """Checks for an valid date string""" + try: + if rex.match("\d\d\d\d-\d\d-\d\d", str(date_str)) is None: + raise sqlErr("Not a Date!") + except Exception as e: + raise e + + @staticmethod + def check_for_product_name(product_name): # Product table check + """Checks to make sure the product name is a string""" + try: + if type(product_name) is not str: + raise sqlErr("Not a valid product name!") + except Exception as e: + raise e + + @staticmethod + def inventory_counts_check(inventory_counts): + """Checks something in the inventory counts""" + pass + + def create_connection(self, db_file: str="C:\sqlite\sqlite\Python210FinalDB.db"): + """ Create or connect to a SQLite database """ + try: + con = sqlite3.connect(db_file) + except sqlErr as se: + raise Exception('SQL Error in create_connection(): ' + se.__str__()) + except Exception as e: + raise Exception('General Error in create_connection(): ' + e.__str__()) + return con + + def execute_sql_code(self, db_con: object = None, sql_code: str = ''): + """ Execute SQL code on a open connection """ + db_con = self.db_con + try: + if db_con is not None and sql_code != '': + # Validate + self.check_for_extra_semicolon(sql_code); + self.check_for_or(sql_code); + # Connect and Run + with db_con: + csr = db_con.cursor() + csr.execute(sql_code) + else: + raise Exception('SQL Code or Connection is missing!') + except sqlErr as se: + raise Exception('SQL Error in execute_sql_code(): ' + se.__str__()) + except Exception as e: + raise Exception('General Error in execute_sql_code(): ' + e.__str__()) + return csr + + def build_ins_code(self): + # Validate Input + sql = str.format("INSERT Not Implemented Yet") + return sql + + def build_upd_code(self): + # Validate Input + sql = str.format("UPDATE Not Implemented Yet") + return sql + + def build_del_code(self): + # Validate Input + # Validate Input + sql = str.format("DELETE Not Implemented Yet") + return sql + + def build_sel_code(self): + # Validate Input + sql = str.format("SELECT Not Implemented Yet") + return sql + + +class InventoryProcessor(DBProcessor): + def build_ins_code(self, inventory_id: int, inventory_date: str): + DBProcessor.check_for_date(inventory_date) + sql = str.format("INSERT OR IGNORE INTO Inventories (InventoryID, InventoryDate) " + "VALUES ({id},'{date}');", id=inventory_id, date=inventory_date) + return sql + + def build_upd_code(self, inventory_id: int, inventory_date: str): + DBProcessor.check_for_date(inventory_date) + sql = str.format("UPDATE Inventories SET InventoryDate = '{date}' " + "WHERE InventoryID = {id};", id=inventory_id, date=inventory_date) + return sql + + def build_del_code(self, inventory_id: int): + sql = str.format("DELETE FROM Inventories " + "WHERE InventoryID = {id};", id=inventory_id) + return sql + + def build_sel_code(self, inventory_id: int = None): + if inventory_id is not None: + w = ' WHERE InventoryID = ' + str(inventory_id) + else: + w = '' + sql = str.format("SELECT InventoryID, InventoryDate " + "FROM Inventories{WHERE};", WHERE=w) + return sql + +class ProductsProcessor(DBProcessor): + def build_ins_code(self, product_id: int, product_name: str): + DBProcessor.check_for_product_name(product_name) + sql = str.format("INSERT OR IGNORE INTO Products (ProductID, ProductName) " + "VALUES ({id},'{name}');", id=product_id, name=product_name) + return sql + + def build_upd_code(self, product_id: int, product_name: str): + DBProcessor.check_for_product_name(product_name) + sql = str.format("UPDATE Products SET ProductName = '{name}' " + "WHERE ProductID = {id};", id=product_id, name=product_name) + return sql + + def build_del_code(self, product_id: int): + sql = str.format("DELETE FROM Products WHERE ProductID = {id};", id=product_id) + return sql + + def build_sel_code(self, product_id: int = None): + if product_id is not None: + w = ' WHERE ProductID = ' + str(product_id) + else: + w = '' + sql = str.format("SELECT ProductID, ProductName " + "FROM Products{WHERE};", WHERE=w) + return sql + +class InventoryCountsProcessor(DBProcessor): + def build_ins_code(self, inventory_id: int, product_id: int, inventory_count: int): + DBProcessor.inventory_counts_check(inventory_count) + sql = str.format("INSERT OR IGNORE INTO InventoryCounts (InventoryID, ProductID, Count) " + "VALUES ({invid}, {prodid}, '{count}');", invid=inventory_id, prodid=product_id, count=inventory_count) + return sql + + def build_upd_code(self, inventory_id: int, product_id: int, inventory_count): + DBProcessor.inventory_counts_check(inventory_count) + sql = str.format("UPDATE InventoryCounts SET Count = '{count}' " + "WHERE ProductID = {prodid} AND InventoryID = {invid};", count=inventory_count, prodid=product_id, invid=inventory_id) + return sql + + def build_del_code(self, inventory_id: int, product_id: int): + sql = str.format("DELETE FROM InventoryCounts WHERE ProductID = {prodid} AND InventoryID = {invid};", prodid=product_id, invid=inventory_id) + return sql + + def build_sel_code(self, inventory_id: int = None): + if inventory_id is not None: + w = ' WHERE InventoryID = ' + str(inventory_id) + else: + w = '' + sql = str.format("SELECT InventoryID, ProductID, Count " + "FROM InventoryCounts{WHERE};", WHERE=w) + return sql + +class create_tables(): + def create_inventories_tbl(self): + sql = str.format("CREATE TABLE if not exists Inventories (InventoryID int Primary Key, InventoryDate date);") + return sql + + def create_products_tbl(self): + sql = str.format("CREATE TABLE if not exists Products (ProductID int Primary Key, ProductName varchar(100));") + return sql + + def create_inventorycounts_tbl(self): + sql = str.format("CREATE TABLE if not exists InventoryCounts (InventoryID int, ProductID int, Count int, Primary Key (InventoryID,ProductID));") + return sql + +if __name__ == '__main__': + + #Create Tables for Testing + DBProcessor().execute_sql_code(db_con=create_connection(), sql_code=create_tables().create_products_tbl()) + DBProcessor().execute_sql_code(db_con=create_connection(), sql_code=create_tables().create_inventories_tbl()) + DBProcessor().execute_sql_code(db_con=create_connection(), sql_code=create_tables().create_inventorycounts_tbl()) + + #Insert Data + DBProcessor().execute_sql_code(db_con=create_connection(), sql_code=ProductsProcessor().build_ins_code(8888,'MMouse')) + DBProcessor().execute_sql_code(db_con=create_connection(), sql_code=InventoryProcessor().build_ins_code(8888,'2019-01-01')) + DBProcessor().execute_sql_code(db_con=create_connection(), sql_code=InventoryCountsProcessor().build_ins_code(99, 5, 2)) + + #Select Data - all run without errors, but I can only return the cursor object, not the data + DBProcessor().execute_sql_code(db_con=create_connection(), sql_code=InventoryProcessor().build_sel_code()) + DBProcessor().execute_sql_code(db_con=create_connection(), sql_code=InventoryCountsProcessor().build_sel_code()) + DBProcessor().execute_sql_code(db_con=create_connection(), sql_code=ProductsProcessor().build_sel_code(5)) + + #Update Data + DBProcessor().execute_sql_code(db_con=create_connection(), sql_code=InventoryProcessor().build_upd_code(5,'2000-09-09')) + DBProcessor().execute_sql_code(db_con=create_connection(), sql_code=ProductsProcessor().build_upd_code(5,'thing')) + DBProcessor().execute_sql_code(db_con=create_connection(), sql_code=InventoryCountsProcessor().build_upd_code(100,100,90000)) + + #Delete Data + DBProcessor().execute_sql_code(db_con=create_connection(), sql_code=InventoryProcessor().build_del_code(5)) + DBProcessor().execute_sql_code(db_con=create_connection(), sql_code=ProductsProcessor().build_del_code(5)) + DBProcessor().execute_sql_code(db_con=create_connection(), sql_code=InventoryCountsProcessor().build_del_code(2,101)) From cdc6e24a820897cc1b6cef175d1e3bf06928aec7 Mon Sep 17 00:00:00 2001 From: johnwachter Date: Thu, 6 Aug 2020 20:25:08 -0700 Subject: [PATCH 41/41] committing session 5 --- .../johnwachter/session04/dict_set_lab.py | 60 +++++++++++++++++++ .../johnwachter/session05/except_exercise.py | 55 +++++++++++++++++ students/johnwachter/session05/except_test.py | 41 +++++++++++++ .../session05/pythonpushupsweek5.py | 16 +++++ 4 files changed, 172 insertions(+) create mode 100644 students/johnwachter/session04/dict_set_lab.py create mode 100644 students/johnwachter/session05/except_exercise.py create mode 100644 students/johnwachter/session05/except_test.py create mode 100644 students/johnwachter/session05/pythonpushupsweek5.py diff --git a/students/johnwachter/session04/dict_set_lab.py b/students/johnwachter/session04/dict_set_lab.py new file mode 100644 index 0000000..c1d9feb --- /dev/null +++ b/students/johnwachter/session04/dict_set_lab.py @@ -0,0 +1,60 @@ +#Dictionaires1 +mydict = {'Name': 'Chris', 'City': 'Seattle', 'Cake':'Chocolate'} +print(mydict) +del mydict['Cake'] +print(mydict) +mydict['Fruit'] = 'Mango' +print(mydict) +print(mydict.keys()) +print(mydict.values()) +print(mydict.get('Cake', 'Cake not in dictionary')) +if 'Mango' in mydict.values(): + print('Mango is in the dictionary') +else: print('Mango not in dictionary') + +#Dictionaries2 - What??? + +#Sets1 +s2 = range(0,21) +s3 = range(0,21) +s4 = range(0,21) + +holds2 = list(s2) +holds3 = list(s3) +holds4 = list(s4) + +l2 = [] +l3 = [] +l4 = [] + +for i in holds2: + if i%2 ==0: + l2.append(i) +for i in holds3: + if i%3 == 0: + l3.append(i) +for i in holds4: + if i%4 == 0: + l4.append(i) + +s2 = set(l2) +s3 = set(l3) +s4 = set(l4) +print(s2, s3, s4) +print(s3 < s2) +print(s4