From c186b691eb4d93008664b37244eab6a7bc38ebb6 Mon Sep 17 00:00:00 2001 From: kevcav91 Date: Sun, 10 Feb 2019 13:30:25 -0800 Subject: [PATCH 1/4] week 5 homeworks --- .../session4/.idea/workspace.xml | 114 ++---- .../session5/.idea/encodings.xml | 4 + .../KevinCavanaugh/session5/.idea/misc.xml | 4 + .../KevinCavanaugh/session5/.idea/modules.xml | 8 + .../session5/.idea/session5.iml | 13 + .../KevinCavanaugh/session5/.idea/vcs.xml | 6 + .../session5/.idea/workspace.xml | 340 ++++++++++++++++++ .../KevinCavanaugh/session5/class_notes.py | 0 .../session5/compreshion_lab.py | 44 +++ .../session5/except_exercise.py | 55 +++ .../KevinCavanaugh/session5/except_test.py | 41 +++ students/KevinCavanaugh/session5/lab 5-1.py | 33 ++ .../KevinCavanaugh/session5/mailroom_3.py | 125 +++++++ .../new/thank_you_Kevin Cavanaugh.txt | 8 + .../session5/new/thank_you_Kim Pinkie.txt | 8 + .../session5/new/thank_you_Piper Long.txt | 8 + .../session5/new/thank_you_Randy Brown.txt | 8 + .../session5/new/thank_you_Victor Murphy.txt | 8 + .../session5/new/thank_you_dan.txt | 8 + .../thank_you_Kevin Cavanaugh.txt | 8 + .../thank_you_Kim Pinkie.txt | 8 + .../thank_you_Piper Long.txt | 8 + .../thank_you_Randy Brown.txt | 8 + .../thank_you_Victor Murphy.txt | 8 + 24 files changed, 789 insertions(+), 86 deletions(-) create mode 100644 students/KevinCavanaugh/session5/.idea/encodings.xml create mode 100644 students/KevinCavanaugh/session5/.idea/misc.xml create mode 100644 students/KevinCavanaugh/session5/.idea/modules.xml create mode 100644 students/KevinCavanaugh/session5/.idea/session5.iml create mode 100644 students/KevinCavanaugh/session5/.idea/vcs.xml create mode 100644 students/KevinCavanaugh/session5/.idea/workspace.xml create mode 100644 students/KevinCavanaugh/session5/class_notes.py create mode 100644 students/KevinCavanaugh/session5/compreshion_lab.py create mode 100644 students/KevinCavanaugh/session5/except_exercise.py create mode 100644 students/KevinCavanaugh/session5/except_test.py create mode 100644 students/KevinCavanaugh/session5/lab 5-1.py create mode 100644 students/KevinCavanaugh/session5/mailroom_3.py create mode 100644 students/KevinCavanaugh/session5/new/thank_you_Kevin Cavanaugh.txt create mode 100644 students/KevinCavanaugh/session5/new/thank_you_Kim Pinkie.txt create mode 100644 students/KevinCavanaugh/session5/new/thank_you_Piper Long.txt create mode 100644 students/KevinCavanaugh/session5/new/thank_you_Randy Brown.txt create mode 100644 students/KevinCavanaugh/session5/new/thank_you_Victor Murphy.txt create mode 100644 students/KevinCavanaugh/session5/new/thank_you_dan.txt create mode 100644 students/KevinCavanaugh/session5/thank_you_letters/thank_you_Kevin Cavanaugh.txt create mode 100644 students/KevinCavanaugh/session5/thank_you_letters/thank_you_Kim Pinkie.txt create mode 100644 students/KevinCavanaugh/session5/thank_you_letters/thank_you_Piper Long.txt create mode 100644 students/KevinCavanaugh/session5/thank_you_letters/thank_you_Randy Brown.txt create mode 100644 students/KevinCavanaugh/session5/thank_you_letters/thank_you_Victor Murphy.txt diff --git a/students/KevinCavanaugh/session4/.idea/workspace.xml b/students/KevinCavanaugh/session4/.idea/workspace.xml index 724eee0..500744b 100644 --- a/students/KevinCavanaugh/session4/.idea/workspace.xml +++ b/students/KevinCavanaugh/session4/.idea/workspace.xml @@ -10,7 +10,7 @@ - + @@ -19,65 +19,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -102,10 +43,10 @@ - @@ -113,7 +54,6 @@ - @@ -125,6 +65,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1549505284543 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/students/KevinCavanaugh/session5/class_notes.py b/students/KevinCavanaugh/session5/class_notes.py new file mode 100644 index 0000000..e69de29 diff --git a/students/KevinCavanaugh/session5/compreshion_lab.py b/students/KevinCavanaugh/session5/compreshion_lab.py new file mode 100644 index 0000000..f6156ef --- /dev/null +++ b/students/KevinCavanaugh/session5/compreshion_lab.py @@ -0,0 +1,44 @@ +feast = ['spam', 'sloths', 'orangutans', 'breakfast cereals', 'fruit bats'] + +comp = [delicacy for delicacy in feast if len(delicacy) > 6] + +print(len(feast)) + +print(len(comp)) + +list_of_tuples = [(1, 'lumberjack'), (2, 'inquisition'), (4, 'spam')] + +comprehension = [ number * skit for number, skit in list_of_tuples ] + +print(comprehension) + +print(comprehension[0]) + +print(len(comprehension[2])) + +dict_of_weapons = {'first': 'fear', + 'second': 'surprise', + 'third':'ruthless efficiency', + 'forth':'fanatical devotion', + 'fifth': None} + +dict_comprehension = {k.upper(): weapon for k, weapon in dict_of_weapons.items() if weapon} + +print('first' in dict_comprehension) + +print('FIRST' in dict_comprehension) + +print(len(dict_of_weapons)) +print(len(dict_comprehension)) + + +def count_evens(nums): + even_nums = [num for num in nums if num % 2 == 0] + return len(even_nums) + + +print(count_evens([2, 1, 2, 3, 4])) +print(count_evens([1, 3, 5])) + + + diff --git a/students/KevinCavanaugh/session5/except_exercise.py b/students/KevinCavanaugh/session5/except_exercise.py new file mode 100644 index 0000000..26f4d9e --- /dev/null +++ b/students/KevinCavanaugh/session5/except_exercise.py @@ -0,0 +1,55 @@ +#!/usr/bin/python + +""" +An exercise in playing with Exceptions. +Make lots of try/except blocks for fun and profit. + +Make sure to catch specifically the error you find, rather than all errors. +""" + +from except_test import fun, more_fun, last_fun + + +# Figure out what the exception is, catch it and while still +# in that catch block, try again with the second item in the list +first_try = ['spam', 'cheese', 'mr death'] +try: + joke = fun(first_try[0]) +except NameError: + print('Name cannot be found.') + joke = fun(first_try[1]) + +# Here is a try/except block. Add an else that prints not_joke +try: + not_joke = fun(first_try[2]) +except SyntaxError: + print('Run Away!') +else: + print(not_joke) + +# What did that do? You can think of else in this context, as well as in +# loops as meaning: "else if nothing went wrong" +# (no breaks in loops, no exceptions in try blocks) + +# Figure out what the exception is, catch it and in that same block +# +# try calling the more_fun function with the 2nd language in the list, +# again assigning it to more_joke. +# +# If there are no exceptions, call the more_fun function with the last +# language in the list + +# Finally, while still in the try/except block and regardless of whether +# there were any exceptions, call the function last_fun with no +# parameters. (pun intended) + +langs = ['java', 'c', 'python'] + +try: + more_joke = more_fun(langs[0]) +except IndexError: + print('Index out of range.') + more_joke = more_fun(langs[1]) + more_joke = more_fun(langs[2]) + last_fun() + diff --git a/students/KevinCavanaugh/session5/except_test.py b/students/KevinCavanaugh/session5/except_test.py new file mode 100644 index 0000000..905dd67 --- /dev/null +++ b/students/KevinCavanaugh/session5/except_test.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 + +""" +silly little test module that is designed to trigger Exceptions when +run from the except_exercise.py file +""" + +import time + +conclude = "And what leads you to that conclusion?" +district = "Finest in the district, sir." +cheese = "It's certainly uncontaminated by cheese." +clean = "Well, it's so clean." +shop = "Not much of a cheese shop really, is it?" +cust = "Customer: " +clerk = "Shopkeeper: " + + +def fun(reaper): + if reaper == 'spam': + print(s) + elif reaper == 'cheese': + print() + print('Spam, Spam, Spam, Spam, Beautiful Spam') + elif reaper == 'mr death': + print() + return('{}{}\n{}{}'.format(cust, shop, clerk, district)) + + +def more_fun(language): + if language == 'java': + test = [1, 2, 3] + test[5] = language + elif language == 'c': + print('{}{}\n{}{}'.format(cust, conclude, clerk, clean)) + + +def last_fun(): + print(cust, cheese) + time.sleep(1) + import antigravity diff --git a/students/KevinCavanaugh/session5/lab 5-1.py b/students/KevinCavanaugh/session5/lab 5-1.py new file mode 100644 index 0000000..8577212 --- /dev/null +++ b/students/KevinCavanaugh/session5/lab 5-1.py @@ -0,0 +1,33 @@ +def sum_numbers(*args): + sum = 0 + for value in args: + sum += value + return sum + + +def difference_numbers(*args): + difference = 0 + for value in args: + difference -= value + return difference + + +def product_numbers(*args): + product = 1 + for value in args: + product *= value + return product + + +def quotient_numbers(*args): + quotient = 1 + for value in args: + quotient /= value + return quotient + + +print(sum_numbers(1,2,3,4,5)) +print(difference_numbers(1,2,3,4,5)) +print(product_numbers(1,2,3)) +print(quotient_numbers(1,2,3,4,5)) + diff --git a/students/KevinCavanaugh/session5/mailroom_3.py b/students/KevinCavanaugh/session5/mailroom_3.py new file mode 100644 index 0000000..45c2e80 --- /dev/null +++ b/students/KevinCavanaugh/session5/mailroom_3.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python3 + +# ----------------------------------------------------------------------- # +# Title: Mailroom_Part_3 +# Author: Kevin Cavanaugh +# Change Log: (Who,What,When) +# kcavanau, created document & completed assignment, 02/10/2019 +# kcavanau, playing with compression and error handling, 02/10/2019 +# ----------------------------------------------------------------------- # + +import sys, io, os + + +# -------------------- DATA -------------------- # + +donors = {} +donors['Kevin Cavanaugh'] = (500.55, 899.34, 78.94) +donors['Victor Murphy'] = (99.89, 87.02) +donors['Randy Brown'] = (10.11, 1000.01, 99.99) +donors['Piper Long'] = (190.99, 100.02) +donors['Kim Pinkie'] = (2344.44, 8999.66, 345.55) + +prompt = "\n".join(("What would you like to do?", + "1. Send a Thank You to single donor", + "2. Create a Report", + "3. Send letters to all donors", + "4. Quit")) + + +def send_thank_you(name, donation): + ''' + + :param name: + :param donation: + :return: + ''' + letter = '\n Dear {}, \n\n Thank you for the generous donation of ${:.2f}. \n We are very grateful for your' \ + ' donation. \n\n Sincerely, \n The Team'.format(name, donation) + return letter + '\n' + + +def add_donation(record, person, donation): + if person in record: + record[person] += donation, + else: + record[person] = donation, + + +def donor_stats(donor): + total = sum(donors[donor]) + num_donations = int(len(donors[donor])) + avg_donation = int(total / num_donations) + return '{:<20} ${:<15.2f} {:<10} ${:<15.2f} '.format(donor, total, num_donations, avg_donation) + + +def create_report(): + print('{:<20} |{:,<15} |{:<10} |{:,<15} '.format('Donor', 'Total', 'Num Gifts', 'Average Gift')) + print('-' * 60) + for donor in donors: + print(donor_stats(donor)) + print('\n') + + +def write_letters(): + cwd = os.getcwd() + try: + os.mkdir('thank_you_letters') + os.chdir('thank_you_letters') + except FileExistsError: + print('Files already exists. Create new directory.') + new_dir = input('New Directory Name: ') + os.mkdir(new_dir) + os.chdir(new_dir) + + for donor in donors.keys(): + file_name = ('thank_you_{:s}.txt'.format(donor)) + open(file_name, 'a').close() + file = io.open(file_name, 'w') + file.write(send_thank_you(donor, donors[donor][len(donors[donor]) - 1])) + file.close() + + os.chdir(cwd) + + +def thank_single_donor(): + name = input('Enter name of donor: ').lower() + while True: + if name == 'list': + for donor in donors.keys(): + print(donor) + else: + try: + donation = float(input('How much did {:s} donate?'.format(name))) + add_donation(donors, name, donation) + print(send_thank_you(name, donors[name][len(donors[name]) - 1])) + break + except ValueError: + print('You must enter a number.') + + +def quit_mailroom(): + input('Press enter to exit! :) Have nice day') + return sys.exit() + + +def user_input(choice): + options = {'1': thank_single_donor, + '2': create_report, + '3': write_letters, + '4': quit_mailroom} + return options.get(choice)() + + +def main(): + while True: + try: + response = input(prompt) + user_input(response) + except TypeError: + print('\n Select a valid option! \n') + input('Press enter to continue...') + + +if __name__ == "__main__": + main() diff --git a/students/KevinCavanaugh/session5/new/thank_you_Kevin Cavanaugh.txt b/students/KevinCavanaugh/session5/new/thank_you_Kevin Cavanaugh.txt new file mode 100644 index 0000000..663edbd --- /dev/null +++ b/students/KevinCavanaugh/session5/new/thank_you_Kevin Cavanaugh.txt @@ -0,0 +1,8 @@ + + Dear Kevin Cavanaugh, + + Thank you for the generous donation of $78.94. + We are very grateful for your donation. + + Sincerely, + The Team diff --git a/students/KevinCavanaugh/session5/new/thank_you_Kim Pinkie.txt b/students/KevinCavanaugh/session5/new/thank_you_Kim Pinkie.txt new file mode 100644 index 0000000..f8ca8ff --- /dev/null +++ b/students/KevinCavanaugh/session5/new/thank_you_Kim Pinkie.txt @@ -0,0 +1,8 @@ + + Dear Kim Pinkie, + + Thank you for the generous donation of $345.55. + We are very grateful for your donation. + + Sincerely, + The Team diff --git a/students/KevinCavanaugh/session5/new/thank_you_Piper Long.txt b/students/KevinCavanaugh/session5/new/thank_you_Piper Long.txt new file mode 100644 index 0000000..466f27e --- /dev/null +++ b/students/KevinCavanaugh/session5/new/thank_you_Piper Long.txt @@ -0,0 +1,8 @@ + + Dear Piper Long, + + Thank you for the generous donation of $100.02. + We are very grateful for your donation. + + Sincerely, + The Team diff --git a/students/KevinCavanaugh/session5/new/thank_you_Randy Brown.txt b/students/KevinCavanaugh/session5/new/thank_you_Randy Brown.txt new file mode 100644 index 0000000..9345d3e --- /dev/null +++ b/students/KevinCavanaugh/session5/new/thank_you_Randy Brown.txt @@ -0,0 +1,8 @@ + + Dear Randy Brown, + + Thank you for the generous donation of $99.99. + We are very grateful for your donation. + + Sincerely, + The Team diff --git a/students/KevinCavanaugh/session5/new/thank_you_Victor Murphy.txt b/students/KevinCavanaugh/session5/new/thank_you_Victor Murphy.txt new file mode 100644 index 0000000..e5d9683 --- /dev/null +++ b/students/KevinCavanaugh/session5/new/thank_you_Victor Murphy.txt @@ -0,0 +1,8 @@ + + Dear Victor Murphy, + + Thank you for the generous donation of $87.02. + We are very grateful for your donation. + + Sincerely, + The Team diff --git a/students/KevinCavanaugh/session5/new/thank_you_dan.txt b/students/KevinCavanaugh/session5/new/thank_you_dan.txt new file mode 100644 index 0000000..75192f2 --- /dev/null +++ b/students/KevinCavanaugh/session5/new/thank_you_dan.txt @@ -0,0 +1,8 @@ + + Dear dan, + + Thank you for the generous donation of $2.00. + We are very grateful for your donation. + + Sincerely, + The Team diff --git a/students/KevinCavanaugh/session5/thank_you_letters/thank_you_Kevin Cavanaugh.txt b/students/KevinCavanaugh/session5/thank_you_letters/thank_you_Kevin Cavanaugh.txt new file mode 100644 index 0000000..663edbd --- /dev/null +++ b/students/KevinCavanaugh/session5/thank_you_letters/thank_you_Kevin Cavanaugh.txt @@ -0,0 +1,8 @@ + + Dear Kevin Cavanaugh, + + Thank you for the generous donation of $78.94. + We are very grateful for your donation. + + Sincerely, + The Team diff --git a/students/KevinCavanaugh/session5/thank_you_letters/thank_you_Kim Pinkie.txt b/students/KevinCavanaugh/session5/thank_you_letters/thank_you_Kim Pinkie.txt new file mode 100644 index 0000000..f8ca8ff --- /dev/null +++ b/students/KevinCavanaugh/session5/thank_you_letters/thank_you_Kim Pinkie.txt @@ -0,0 +1,8 @@ + + Dear Kim Pinkie, + + Thank you for the generous donation of $345.55. + We are very grateful for your donation. + + Sincerely, + The Team diff --git a/students/KevinCavanaugh/session5/thank_you_letters/thank_you_Piper Long.txt b/students/KevinCavanaugh/session5/thank_you_letters/thank_you_Piper Long.txt new file mode 100644 index 0000000..466f27e --- /dev/null +++ b/students/KevinCavanaugh/session5/thank_you_letters/thank_you_Piper Long.txt @@ -0,0 +1,8 @@ + + Dear Piper Long, + + Thank you for the generous donation of $100.02. + We are very grateful for your donation. + + Sincerely, + The Team diff --git a/students/KevinCavanaugh/session5/thank_you_letters/thank_you_Randy Brown.txt b/students/KevinCavanaugh/session5/thank_you_letters/thank_you_Randy Brown.txt new file mode 100644 index 0000000..9345d3e --- /dev/null +++ b/students/KevinCavanaugh/session5/thank_you_letters/thank_you_Randy Brown.txt @@ -0,0 +1,8 @@ + + Dear Randy Brown, + + Thank you for the generous donation of $99.99. + We are very grateful for your donation. + + Sincerely, + The Team diff --git a/students/KevinCavanaugh/session5/thank_you_letters/thank_you_Victor Murphy.txt b/students/KevinCavanaugh/session5/thank_you_letters/thank_you_Victor Murphy.txt new file mode 100644 index 0000000..e5d9683 --- /dev/null +++ b/students/KevinCavanaugh/session5/thank_you_letters/thank_you_Victor Murphy.txt @@ -0,0 +1,8 @@ + + Dear Victor Murphy, + + Thank you for the generous donation of $87.02. + We are very grateful for your donation. + + Sincerely, + The Team From 04bdaf0ee4bf2b162c96d248e615146558a6de2c Mon Sep 17 00:00:00 2001 From: kevcav91 Date: Tue, 19 Feb 2019 15:27:27 -0800 Subject: [PATCH 2/4] complete and submit session6 --- .../KevinCavanaugh/session6/mailroom_4.py | 136 ++++++++++++++++++ .../KevinCavanaugh/session6/test_mailroom4.py | 37 +++++ .../thank_you_Kevin Cavanaugh.txt | 8 ++ .../thank_you_Kim Pinkie.txt | 8 ++ .../thank_you_Piper Long.txt | 8 ++ .../thank_you_Randy Brown.txt | 8 ++ .../thank_you_Victor Murphy.txt | 8 ++ 7 files changed, 213 insertions(+) create mode 100644 students/KevinCavanaugh/session6/mailroom_4.py create mode 100644 students/KevinCavanaugh/session6/test_mailroom4.py create mode 100644 students/KevinCavanaugh/session6/thank_you_letters/thank_you_Kevin Cavanaugh.txt create mode 100644 students/KevinCavanaugh/session6/thank_you_letters/thank_you_Kim Pinkie.txt create mode 100644 students/KevinCavanaugh/session6/thank_you_letters/thank_you_Piper Long.txt create mode 100644 students/KevinCavanaugh/session6/thank_you_letters/thank_you_Randy Brown.txt create mode 100644 students/KevinCavanaugh/session6/thank_you_letters/thank_you_Victor Murphy.txt diff --git a/students/KevinCavanaugh/session6/mailroom_4.py b/students/KevinCavanaugh/session6/mailroom_4.py new file mode 100644 index 0000000..5a3bd1e --- /dev/null +++ b/students/KevinCavanaugh/session6/mailroom_4.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python3 + +# ----------------------------------------------------------------------- # +# Title: Mailroom_Part_3 +# Author: Kevin Cavanaugh +# Change Log: (Who,What,When) +# kcavanau, created document & completed assignment, 02/10/2019 +# kcavanau, playing with compression and error handling, 02/10/2019 +# ----------------------------------------------------------------------- # + +import sys, io, os + + +# -------------------- DATA -------------------- # + +donors = {} +donors['Kevin Cavanaugh'] = (500.55, 899.34, 78.94) +donors['Victor Murphy'] = (99.89, 87.02) +donors['Randy Brown'] = (10.11, 1000.01, 99.99) +donors['Piper Long'] = (190.99, 100.02) +donors['Kim Pinkie'] = (2344.44, 8999.66, 345.55) + +prompt = "\n".join(("What would you like to do?", + "1. Send a Thank You to single donor", + "2. Create a Report", + "3. Send letters to all donors", + "4. Quit")) + + +def send_thank_you(name, donation): + ''' + + :param name: + :param donation: + :return: + ''' + letter = '\n Dear {}, \n\n Thank you for the generous donation of ${:.2f}. \n We are very grateful for your' \ + ' donation. \n\n Sincerely, \n The Team'.format(name, donation) + return letter + '\n' + + +def add_donation(record, person, donation): + if person in record: + record[person] += donation, + else: + record[person] = donation, + return record + + +def donor_stats(donor): + total = sum(donors[donor]) + num_donations = int(len(donors[donor])) + avg_donation = int(total / num_donations) + return '{:<20} ${:<15.2f} {:<10} ${:<15.2f} '.format(donor, total, num_donations, avg_donation) + + +def create_report(database): + report = ('{:<20} |{:<15} |{:<10} |{:<15}\n '.format('Donor', 'Total', 'Num Gifts', 'Average Gift')) + report += '-' * 60 + '\n' + for donor in database: + report += donor_stats(donor) + '\n' + return report + + +def display_report(): + print(create_report(donors)) + +def write_letters(): + cwd = os.getcwd() + try: + os.mkdir('thank_you_letters') + os.chdir('thank_you_letters') + except FileExistsError: + print('Files already exists. Create new directory.') + new_dir = input('New Directory Name: ') + os.mkdir(new_dir) + os.chdir(new_dir) + + for donor in donors.keys(): + file_name = ('thank_you_{:s}.txt'.format(donor)) + open(file_name, 'a').close() + file = io.open(file_name, 'w') + file.write(send_thank_you(donor, donors[donor][len(donors[donor]) - 1])) + file.close() + + os.chdir(cwd) + + +def thank_single_donor(): + name = input('Enter name of donor: ').lower() + while True: + if name == 'list': + print(create_donor_list()) + break + else: + try: + donation = float(input('How much did {:s} donate?'.format(name))) + add_donation(donors, name, donation) + print(send_thank_you(name, donors[name][len(donors[name]) - 1])) + break + except ValueError: + print('You must enter a number.') + + +def create_donor_list(): + donor_list = 'Donors: \n' + for donor in donors: + donor_list += donor + '\n' + return donor_list + + +def quit_mailroom(): + input('Press enter to exit! :) Have nice day') + return sys.exit() + + +def user_input(choice): + options = {'1': thank_single_donor, + '2': display_report, + '3': write_letters, + '4': quit_mailroom} + return options.get(choice)() + + +def main(): + while True: + try: + response = input(prompt) + user_input(response) + except TypeError: + print('\n Select a valid option! \n') + input('Press enter to continue...') + + +if __name__ == "__main__": + main() diff --git a/students/KevinCavanaugh/session6/test_mailroom4.py b/students/KevinCavanaugh/session6/test_mailroom4.py new file mode 100644 index 0000000..8b3ee6f --- /dev/null +++ b/students/KevinCavanaugh/session6/test_mailroom4.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +import os + +import mailroom_4 as mailroom + +donors = {} +donors['Kevin Cavanaugh'] = (500.55, 899.34, 78.94) +donors['Victor Murphy'] = (99.89, 87.02) +donors['Randy Brown'] = (10.11, 1000.01, 99.99) +donors['Piper Long'] = (190.99, 100.02) +donors['Kim Pinkie'] = (2344.44, 8999.66, 345.55) + + +def test_donor_list(): + listing = mailroom.create_donor_list() + assert "Kevin Cavanaugh" in listing + assert len(listing.split('\n')) == 7 + assert listing.startswith("Donors: \n") + + +def test_create_report(): + report = mailroom.create_report(donors) + assert report.startswith('Donor |Total |Num Gifts |Average Gift') + + +def test_add_donation(): + name = "Randal Root" + donation = "500" + mailroom.add_donation(donors, name, donation) + assert donors['Randal Root'] + + +def test_write_letter(): + mailroom.write_letters() + assert os.path.isdir('thank_you_letters') + diff --git a/students/KevinCavanaugh/session6/thank_you_letters/thank_you_Kevin Cavanaugh.txt b/students/KevinCavanaugh/session6/thank_you_letters/thank_you_Kevin Cavanaugh.txt new file mode 100644 index 0000000..663edbd --- /dev/null +++ b/students/KevinCavanaugh/session6/thank_you_letters/thank_you_Kevin Cavanaugh.txt @@ -0,0 +1,8 @@ + + Dear Kevin Cavanaugh, + + Thank you for the generous donation of $78.94. + We are very grateful for your donation. + + Sincerely, + The Team diff --git a/students/KevinCavanaugh/session6/thank_you_letters/thank_you_Kim Pinkie.txt b/students/KevinCavanaugh/session6/thank_you_letters/thank_you_Kim Pinkie.txt new file mode 100644 index 0000000..f8ca8ff --- /dev/null +++ b/students/KevinCavanaugh/session6/thank_you_letters/thank_you_Kim Pinkie.txt @@ -0,0 +1,8 @@ + + Dear Kim Pinkie, + + Thank you for the generous donation of $345.55. + We are very grateful for your donation. + + Sincerely, + The Team diff --git a/students/KevinCavanaugh/session6/thank_you_letters/thank_you_Piper Long.txt b/students/KevinCavanaugh/session6/thank_you_letters/thank_you_Piper Long.txt new file mode 100644 index 0000000..466f27e --- /dev/null +++ b/students/KevinCavanaugh/session6/thank_you_letters/thank_you_Piper Long.txt @@ -0,0 +1,8 @@ + + Dear Piper Long, + + Thank you for the generous donation of $100.02. + We are very grateful for your donation. + + Sincerely, + The Team diff --git a/students/KevinCavanaugh/session6/thank_you_letters/thank_you_Randy Brown.txt b/students/KevinCavanaugh/session6/thank_you_letters/thank_you_Randy Brown.txt new file mode 100644 index 0000000..9345d3e --- /dev/null +++ b/students/KevinCavanaugh/session6/thank_you_letters/thank_you_Randy Brown.txt @@ -0,0 +1,8 @@ + + Dear Randy Brown, + + Thank you for the generous donation of $99.99. + We are very grateful for your donation. + + Sincerely, + The Team diff --git a/students/KevinCavanaugh/session6/thank_you_letters/thank_you_Victor Murphy.txt b/students/KevinCavanaugh/session6/thank_you_letters/thank_you_Victor Murphy.txt new file mode 100644 index 0000000..e5d9683 --- /dev/null +++ b/students/KevinCavanaugh/session6/thank_you_letters/thank_you_Victor Murphy.txt @@ -0,0 +1,8 @@ + + Dear Victor Murphy, + + Thank you for the generous donation of $87.02. + We are very grateful for your donation. + + Sincerely, + The Team From 821f0253d0a7c045763ea726e21df305582c06e0 Mon Sep 17 00:00:00 2001 From: kevcav91 Date: Sat, 2 Mar 2019 13:41:14 -0800 Subject: [PATCH 3/4] submit HTML renderer --- .../session7/.idea/encodings.xml | 4 + .../KevinCavanaugh/session7/.idea/misc.xml | 4 + .../KevinCavanaugh/session7/.idea/modules.xml | 8 + .../session7/.idea/session7.iml | 13 + .../KevinCavanaugh/session7/.idea/vcs.xml | 6 + .../session7/.idea/workspace.xml | 315 ++++++++++++++++ .../KevinCavanaugh/session7/html_render.py | 212 +++++++++++ .../session7/run_html_render.py | 231 ++++++++++++ .../session7/test_html_output1.html | 4 + .../session7/test_html_output2.html | 11 + .../session7/test_html_output3.html | 14 + .../session7/test_html_output4.html | 11 + .../session7/test_html_output5.html | 12 + .../session7/test_html_output6.html | 15 + .../session7/test_html_output7.html | 26 ++ .../session7/test_html_output8.html | 27 ++ .../session7/test_html_render.py | 351 ++++++++++++++++++ 17 files changed, 1264 insertions(+) create mode 100644 students/KevinCavanaugh/session7/.idea/encodings.xml create mode 100644 students/KevinCavanaugh/session7/.idea/misc.xml create mode 100644 students/KevinCavanaugh/session7/.idea/modules.xml create mode 100644 students/KevinCavanaugh/session7/.idea/session7.iml create mode 100644 students/KevinCavanaugh/session7/.idea/vcs.xml create mode 100644 students/KevinCavanaugh/session7/.idea/workspace.xml create mode 100644 students/KevinCavanaugh/session7/html_render.py create mode 100644 students/KevinCavanaugh/session7/run_html_render.py create mode 100644 students/KevinCavanaugh/session7/test_html_output1.html create mode 100644 students/KevinCavanaugh/session7/test_html_output2.html create mode 100644 students/KevinCavanaugh/session7/test_html_output3.html create mode 100644 students/KevinCavanaugh/session7/test_html_output4.html create mode 100644 students/KevinCavanaugh/session7/test_html_output5.html create mode 100644 students/KevinCavanaugh/session7/test_html_output6.html create mode 100644 students/KevinCavanaugh/session7/test_html_output7.html create mode 100644 students/KevinCavanaugh/session7/test_html_output8.html create mode 100644 students/KevinCavanaugh/session7/test_html_render.py diff --git a/students/KevinCavanaugh/session7/.idea/encodings.xml b/students/KevinCavanaugh/session7/.idea/encodings.xml new file mode 100644 index 0000000..15a15b2 --- /dev/null +++ b/students/KevinCavanaugh/session7/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/students/KevinCavanaugh/session7/.idea/misc.xml b/students/KevinCavanaugh/session7/.idea/misc.xml new file mode 100644 index 0000000..7868e69 --- /dev/null +++ b/students/KevinCavanaugh/session7/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/students/KevinCavanaugh/session7/.idea/modules.xml b/students/KevinCavanaugh/session7/.idea/modules.xml new file mode 100644 index 0000000..018e292 --- /dev/null +++ b/students/KevinCavanaugh/session7/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/students/KevinCavanaugh/session7/.idea/session7.iml b/students/KevinCavanaugh/session7/.idea/session7.iml new file mode 100644 index 0000000..85c7612 --- /dev/null +++ b/students/KevinCavanaugh/session7/.idea/session7.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/students/KevinCavanaugh/session7/.idea/vcs.xml b/students/KevinCavanaugh/session7/.idea/vcs.xml new file mode 100644 index 0000000..c2365ab --- /dev/null +++ b/students/KevinCavanaugh/session7/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/students/KevinCavanaugh/session7/.idea/workspace.xml b/students/KevinCavanaugh/session7/.idea/workspace.xml new file mode 100644 index 0000000..758b40f --- /dev/null +++ b/students/KevinCavanaugh/session7/.idea/workspace.xml @@ -0,0 +1,315 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1552172101174 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/students/KevinCavanaugh/final_project/DataModel_KevinCavanaugh.py b/students/KevinCavanaugh/final_project/DataModel_KevinCavanaugh.py new file mode 100644 index 0000000..a0d82b0 --- /dev/null +++ b/students/KevinCavanaugh/final_project/DataModel_KevinCavanaugh.py @@ -0,0 +1,135 @@ +from datetime import datetime + + +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 f'{self.product_id},{self.product_name}' + + def __repr__(self): + return f'{Product},[{str(self.__dict__())}' + + def __dict__(self): + return {"product_id": self.product_id, "product_name": self.product_name} + + @property + def product_id(self): + return self.__product_id + + @product_id.setter + def 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 + + @product_name.setter + def product_name(self, product_name): + self.__product_name = str(product_name).strip() + + # Add properties and validation + # product_id > 0 + + +class InventoryCount(object): + + def __init__(self, product: Product, count: int): + self.product = product + self.count = count + + @property + def count(self): + return self.__count + + @count.setter + def count(self, count): + if type(count) is not int: raise TypeError("Requires integer!") + if count <= 0: + raise ValueError("Requires value greater than zero!") + else: + self.__count = count + + @property + def product(self): + return self.__product + + @product.setter + def product(self, product): + if type(product) is not Product: + raise TypeError("Requires product object!") + else: + self.__product = product + + # Add properties and validation + # count >= 0 + # product is Product + + +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 + if inventory_counts is not None: + self.inventory_counts = inventory_counts + + @property + def inventory_id(self): + return self.__inventory_id + + @inventory_id.setter + def inventory_id(self, inventory_id): + if inventory_id <= 0: + raise ValueError("Requires value greater than zero!") + else: + self.__inventory_id = inventory_id + + @property + def inventory_date(self): + return self.__inventory_date + + @inventory_date.setter + def inventory_date(self, inventory_date): + # if type(inventory_date) is not datetime: + # raise TypeError("Requires datetime object!") + # else: + self.__inventory_date = inventory_date + + @property + def inventory_counts(self): + return self.__inventory_counts + + @inventory_counts.setter + def inventory_counts(self, inventory_counts): + # if type(inventory_counts) is not InventoryCount: + # raise TypeError("Requires InventoryCount Object") + # else: + self.__inventory_counts = inventory_counts + + + # Add properties and validation + # inventory_id > 0 + # date is datetime + # inventory_count is inventory_count + + +if __name__ == '__main__': + p1 = Product(100, "ProdA") + p2 = Product(200, "ProdB") + ic1 = InventoryCount(p1, 15) + ic2 = InventoryCount(p2, 45) + invJan0119 = Inventory(1, '2020-01-01', [ic1,ic2]) + for ic in invJan0119.inventory_counts: + print('Jan 2019 -', ic.product.product_name, ' = ', ic.count) + print(p1, str(p1), p1.__str__()) + print(repr(p1)) + print(p1.__dict__()) \ No newline at end of file diff --git a/students/KevinCavanaugh/final_project/DataProcessor_KevinCavanaugh.py b/students/KevinCavanaugh/final_project/DataProcessor_KevinCavanaugh.py new file mode 100644 index 0000000..9c07ae1 --- /dev/null +++ b/students/KevinCavanaugh/final_project/DataProcessor_KevinCavanaugh.py @@ -0,0 +1,264 @@ +import sqlite3 +from sqlite3 import Error as sqlErr +import re as rex + +debugDP = True + +class DBProcessor(object): + + def __init__(self, db_name: str = ":memory:"): # Handy for testing! + 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): + """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 + + def create_connection(self, db_file: str): + """ 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, 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): # create (C/R/U/D) + # Validate Input + sql = str.format("INSERT Not Implemented Yet") + return sql + + def build_sel_code(self): # read + # Validate Input + sql = str.format("SELECT Not Implemented Yet") + return sql + + def build_upd_code(self): # update + # Validate Input + sql = str.format("UPDATE Not Implemented Yet") + return sql + + def build_del_code(self): # delete + # Validate Input + # Validate Input + sql = str.format("DELETE 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 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 ProductProcessor (DBProcessor): + + def build_ins_code(self, product_id: int, product_name: str): + sql = str.format("INSERT 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 ): + sql = str.format("UPDATE Products SET ProductName = '{name}' " + "WHERE InventoryID = {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, inv_count_id: int, product_id: int, count: int): + sql = str.format("INSERT INTO InventoryCounts (InventoryCountID, ProductID, Count) " + "VALUES ({id},{pid},{count});", id=inv_count_id, pid=product_id, count=count) + return sql + + def build_upd_code(self, inv_count_id: int, count: int): + sql = str.format("UPDATE InventoryCounts SET Count = {count} " + "WHERE InventoryCountID = {id};", id=inv_count_id, count=count) + return sql + + def build_del_code(self, inv_count_id: int): + sql = str.format("DELETE FROM InventoryCounts " + "WHERE InventoryCountID = {id};", id=inv_count_id) + return sql + + def build_sel_code(self, inv_count_id: int = None): + if inv_count_id is not None: + w = ' WHERE InventoryCountID = ' + str(inv_count_id) + else: + w = '' + sql = str.format("SELECT InventoryCountID, ProductID, Count " + "FROM InventoryCounts{WHERE};", WHERE=w) + return sql + + +if __name__ == '__main__': + # Test DataProcessor methods + if debugDP == True: + # try: DBProcessor.check_for_or("SELECT * FROM T1 WHERE ID = 1 or 1 = 1") + # except Exception as e: print(e) + # try: DBProcessor.check_for_extra_semicolon("SELECT * ;Delete From T1; FROM T1;") + # except Exception as e: print(e) + # try: DBProcessor.check_for_date('01/01/2000') + # except Exception as e: print(e) + # + # dbp = DBProcessor(':memory:') + # print(dbp.build_ins_code()) + # print(dbp.build_upd_code()) + # print(dbp.build_del_code()) + # print(dbp.build_sel_code()) + # print(dbp.build_sel_code()) + # print(dbp.execute_sql_code("Select 5 + 5;")) + # dbp.db_con.close() + +# Test InventoryProcessor methods ############################## + + # ip = InventoryProcessor(':memory:') + # print(ip.build_ins_code(inventory_id=1, inventory_date='2000-01-01')) + # print(ip.build_upd_code(inventory_id=1, inventory_date='2000-02-02')) + # print(ip.build_del_code(inventory_id=1)) + # print(ip.build_sel_code()) + # + # # Create a table for testing + # crs = ip.db_con.cursor() + # crs.execute("CREATE TABLE Inventories (InventoryID int, InventoryDate date);") + # ip.db_con.commit() + # for row in crs.execute("Select name, sql From sqlite_master Where type='table;'"): + # print(row) + # ip.db_con.commit() + # + # # Test SQL Transactions + # ip.execute_sql_code(ip.build_ins_code(inventory_id=1, inventory_date='2000-01-01')).close() + # for row in ip.execute_sql_code(ip.build_sel_code()): + # print(row) + # + # ip.execute_sql_code(ip.build_upd_code(inventory_id=1, inventory_date='2000-02-02')).close() + # for row in ip.execute_sql_code(ip.build_sel_code(inventory_id=1)): + # print(row) + # + # ip.execute_sql_code(ip.build_del_code(inventory_id=1)).close() + # for row in ip.execute_sql_code(ip.build_sel_code()): + # print(row) + +# Test InventoryCountsProcessor methods ############################## + + icp = InventoryCountsProcessor(':memory:') + print(icp.build_ins_code(inv_count_id=14566543, product_id=1, count=22)) + print(icp.build_upd_code(inv_count_id=14566543, count=33)) + print(icp.build_del_code(inv_count_id=14566543)) + print(icp.build_sel_code()) + + # Create a table for testing + crs = icp.db_con.cursor() + crs.execute("CREATE TABLE InventoryCounts (InventoryCountID int, ProductID int, Count int);") + icp.db_con.commit() + for row in crs.execute("Select name, sql From sqlite_master Where type='table;'"): + print(row) + icp.db_con.commit() + + # Test SQL Transactions + icp.execute_sql_code(icp.build_ins_code(inv_count_id=14566543, product_id=1, count=22)).close() + for row in icp.execute_sql_code(icp.build_sel_code()): + print(row) + + icp.execute_sql_code(icp.build_upd_code(inv_count_id=14566543, count=33)).close() + for row in icp.execute_sql_code(icp.build_sel_code(inv_count_id=14566543)): + print(row) + + icp.execute_sql_code(icp.build_del_code(inv_count_id=14566543)).close() + for row in icp.execute_sql_code(icp.build_sel_code()): + print(row) + diff --git a/students/KevinCavanaugh/final_project/Kcavanaugh_final_project.db b/students/KevinCavanaugh/final_project/Kcavanaugh_final_project.db new file mode 100644 index 0000000000000000000000000000000000000000..1272684fa981d0926c1663dc7d4d199a4d2ed6be GIT binary patch literal 28672 zcmeI&J#W)M7{Kwn^Tm!U(nDe}ODk7lXw(9YfDwtl4HXrlrF&%RKqEDYNZqR0$cNyw zFtc@KrvnR8kq{CpP+kVkO>Ia~7PgfCNw%Lm=g#;1l;zHTw6@wv>fw`irx_*TEpb^$ zDei@#5Mt6Eo;|YS+dyX(dzF90!@@~%fX0tg_0 z00IagfB*srAb`L>2=uNNykKTV_MRruo)+MVuVd$*PBoU6Kv>&x>S%i+fS z!s>E(?q)chH>@m$jaD)nKJ2vP-OVJco{pK_X*8owH@si(4)mMNyHqN7T{l>pk)qLx z>-#&;w(TOc7VReO(|Rp`SbwIq>bVAQ%khGV3E3;3CU!RNPIh$$QpsAw>HPWWJZ%E` zH1lj8M9q4*7j-tbqRw=6Zmv?fsoh|4V%S8pv1`>VDm0}Rl*_U=HDKPT=iW9{0~5@W zvo{93{+?y_%kENS7wxe{YRDTq09$izSEeINmD-mwHtG9+ZQcs=-F!0dZ9qW)0R#|0009ILKmY**5I_Kd Z(Gw`1?Ez@7zXjlU{T%>Rup0n={0l{F@N)nF literal 0 HcmV?d00001 diff --git a/students/KevinCavanaugh/final_project/UserInterface_KevinCavanaugh.py b/students/KevinCavanaugh/final_project/UserInterface_KevinCavanaugh.py new file mode 100644 index 0000000..cc124c6 --- /dev/null +++ b/students/KevinCavanaugh/final_project/UserInterface_KevinCavanaugh.py @@ -0,0 +1,31 @@ +import DataProcessor_KevinCavanaugh as dp +from DataProcessor_KevinCavanaugh import InventoryProcessor as ip +from DataProcessor_KevinCavanaugh import InventoryCountsProcessor as icp +from DataProcessor_KevinCavanaugh import ProductProcessor as pp +import DataModel_KevinCavanaugh as dm + +# Fill Products +# Fill Inventory Counts + +debugDP = False + +if __name__ == '__main__': + + pp = dp.ProductProcessor(':memory:') + # Create a table for testing + crs = pp.db_con.cursor() + crs.execute("CREATE TABLE Products (ProductID int Primary Key, ProductName varchar(100));") + pp.db_con.commit() + pp.execute_sql_code(pp.build_ins_code(product_id=100, product_name='Mouse')) + pp.db_con.commit() + pp.execute_sql_code(pp.build_ins_code(product_id=200, product_name='Keyboard')) + pp.db_con.commit() + + print(pp.build_sel_code()) + plst = [] + for row in crs.execute(pp.build_sel_code()): + print(row) + plst.append(dm.Product(row[0], row[1])) + print(plst) + pp.db_con.commit() + pp.db_con.close() diff --git a/students/KevinCavanaugh/session5/.idea/workspace.xml b/students/KevinCavanaugh/session5/.idea/workspace.xml index 688843c..ce333da 100644 --- a/students/KevinCavanaugh/session5/.idea/workspace.xml +++ b/students/KevinCavanaugh/session5/.idea/workspace.xml @@ -2,7 +2,7 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - + + + + + + + + - - + + - + - + - + - + - - - - - + + + + + @@ -272,12 +228,12 @@ - + - + @@ -316,23 +272,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + - + - + + + + + + + + + + + + + + + - - + + diff --git a/students/KevinCavanaugh/session5/TestData.txt b/students/KevinCavanaugh/session5/TestData.txt new file mode 100644 index 0000000..f58fcd9 --- /dev/null +++ b/students/KevinCavanaugh/session5/TestData.txt @@ -0,0 +1,10 @@ +1,1 +1,2 +1,3 +1,4 +0,1 +0,2 +0,3 +0,4 +2,1 +2,2 diff --git a/students/KevinCavanaugh/session5/cigar_party.py b/students/KevinCavanaugh/session5/cigar_party.py new file mode 100644 index 0000000..3b0230a --- /dev/null +++ b/students/KevinCavanaugh/session5/cigar_party.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +""" +When squirrels get together for a party, they like to have cigars. +A squirrel party is successful when the number of cigars is between +40 and 60, inclusive. Unless it is the weekend, in which case there +is no upper bound on the number of cigars. + +Return True if the party with the given values is successful, +or False otherwise. +""" + + +def cigar_party(cigars, is_weekend): + return cigars >= 40 and is_weekend + diff --git a/students/KevinCavanaugh/session5/test_cigar_party.py b/students/KevinCavanaugh/session5/test_cigar_party.py new file mode 100644 index 0000000..3af7023 --- /dev/null +++ b/students/KevinCavanaugh/session5/test_cigar_party.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +""" +When squirrels get together for a party, they like to have cigars. +A squirrel party is successful when the number of cigars is between +40 and 60, inclusive. Unless it is the weekend, in which case there +is no upper bound on the number of cigars. + +Return True if the party with the given values is successful, +or False otherwise. +""" + +\ +# you can change this import to test different versions +from cigar_party import cigar_party +# from cigar_party import cigar_party2 as cigar_party +# from cigar_party import cigar_party3 as cigar_party + + +def test_1(): + assert cigar_party(30, False) is False + + +def test_2(): + assert cigar_party(50, False) is True + + +def test_3(): + assert cigar_party(70, True) is True + + +def test_4(): + assert cigar_party(30, True) is False + + +def test_5(): + assert cigar_party(50, True) is True + + +def test_6(): + assert cigar_party(60, False) is True + + +def test_7(): + assert cigar_party(61, False) is False + + +def test_8(): + assert cigar_party(40, False) is True + + +def test_9(): + assert cigar_party(39, False) is False + + +def test_10(): + assert cigar_party(40, True) is True + + +def test_11(): + assert cigar_party(39, True) is False diff --git a/students/KevinCavanaugh/session6/notes.py b/students/KevinCavanaugh/session6/notes.py new file mode 100644 index 0000000..cc26c41 --- /dev/null +++ b/students/KevinCavanaugh/session6/notes.py @@ -0,0 +1,21 @@ +class Person: + + # --Constructor-- + def __init__(self, FirstName, Email=None): # Overloaded + # Instance Attributes + self.FirstName = FirstName + self.Email = Email + + # --Methods-- + + def ToString(self): + return self.FirstName + ', ' + str(self.Email) + + +# --End of class-- + +objP1 = Person("Bob", "BSmith@GoMail.com") +objP2 = Person("Sue") +print(objP1.ToString()) +print("-------------") +print(objP2.ToString()) diff --git a/students/KevinCavanaugh/session7/.idea/workspace.xml b/students/KevinCavanaugh/session7/.idea/workspace.xml index 758b40f..f649092 100644 --- a/students/KevinCavanaugh/session7/.idea/workspace.xml +++ b/students/KevinCavanaugh/session7/.idea/workspace.xml @@ -2,8 +2,8 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - @@ -101,18 +48,8 @@ - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1551652660205 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/students/KevinCavanaugh/session8/Generating SQL Code.py b/students/KevinCavanaugh/session8/Generating SQL Code.py new file mode 100644 index 0000000..89144a8 --- /dev/null +++ b/students/KevinCavanaugh/session8/Generating SQL Code.py @@ -0,0 +1,171 @@ +import sqlite3 +from sqlite3 import Error as sqlErr + + +def create_connection(db_file): + try: + con = sqlite3.connect(db_file) + print('SQLite Version is: ', sqlite3.version) + 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(db_con = None, sql_code=''): + try: + if db_con is not None and sql_code != '': + 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 create_connection(): ' + se.__str__()) + except Exception as e: + raise Exception('General Error in create_connection(): ' + e.__str__()) + return csr + + +def create_table_code(name_of_table, col_names=[None]): + """ create table code """ + sql_str = '' + try: + if col_names is None: + raise Exception('You must provide at least one column!') + else: + sql_str = 'CREATE TABLE ' + name_of_table + '\n(' + for col in col_names: + sql_str += str(col) + ' [text], ' + sql_str = sql_str[0:-2] + ');' # Strip off the last comma + except Exception as e: + raise Exception('Error in create_staging_table(): ' + e.__str__()) + return sql_str + + +def create_insert_code(name_of_table, col_names=[None], col_values=[None],): + """ create staging table insert code """ + sql_str = '' + try: + if col_names is None: + raise Exception('You must provide at least one column name!') + else: + sql_str = 'INSERT INTO ' + name_of_table + '\n(' + for col in col_names: + sql_str += str(col) + ', ' + sql_str = sql_str[0:-2] + ')' # Strip off the last comma + if col_values is None: + raise Exception('You must provide at least one column value!') + else: + sql_str += '\nVALUES\n(' + for col in col_values: + sql_str += str(col) + ', ' + sql_str = sql_str[0:-2] + ');' # Strip off the last comma + except Exception as e: + raise Exception('Error in create_insert_code(): ' + e.__str__()) + return sql_str + + +def create_update_code(name_of_table, col_names=[None], col_values=[None], where_col = None, where_equals_value = None): + """ create staging table update code """ + sql_str = '' + try: + if col_names is None: + raise Exception('You must provide at least one column name!') + elif col_values is None: + raise Exception('You must provide at least one column value!') + elif len(col_names) != len(col_values): + raise Exception('You must provide one value for each column') + elif where_col is None or where_equals_value is None: + raise Exception('You must provide a where column and an equals value') + else: + sql_str = 'UPDATE ' + name_of_table + '\nSET\n\t' + counter = 0 + while counter < len(col_names): + sql_str += str(col_names[counter]) + ' = ' + str(col_values[counter]) + ', \n\t' + counter += 1 + sql_str = (sql_str.strip())[0:-1] + '' # Strip off the last comma + sql_str += '\nWHERE ' + where_col + " = " + where_equals_value + except Exception as e: + raise Exception('Error in create_update_code(): ' + e.__str__()) + return sql_str + + +def create_delete_code(name_of_table, where_col = None, where_equals_value = None): + """ create staging table delete code """ + sql_str = '' + try: + if where_col is None or where_equals_value is None: + raise Exception('You must provide a where column and an equals value') + else: + sql_str = 'DELETE FROM ' + name_of_table + sql_str += '\nWHERE ' + where_col + " = " + where_equals_value + except Exception as e: + raise Exception('Error in create_delete_code(): ' + e.__str__()) + return sql_str + + +def create_select_code(name_of_table, col_names=[None]): + """ create staging table select code """ + sql_str = '' + try: + if col_names is None: + raise Exception('You must provide at least one column name!') + else: + sql_str = 'SELECT \n\t' + for col in col_names: + sql_str += str(col) + ', \n\t' + sql_str = sql_str[0:-2] + '\n' # Strip off the last comma + sql_str += 'FROM ' + name_of_table + ';' + except Exception as e: + raise Exception('Error in create_select_code(): ' + e.__str__()) + return sql_str + +# SQL Validators +def check_for_extra_semicolon(SQLStr): + try: + if SQLStr.find(';') != -1: + raise Exception("Extra Semi-Colon Detected!") + except Exception as e: + raise e + + +def check_for_or(SQLStr): + try: + if SQLStr.find('or') != -1: + raise Exception("OR Detected!") + except Exception as e: + raise e + + +if __name__ == '__main__': + + try: + print('\ntest CREATE TABLE','-'*40, '\n') + print(create_table_code('StagingStudents', ['ID','Name','Email'])) + except Exception as e: + print(e) + + try: + print('\ntest SELECT','-'*40, '\n') + print(create_select_code('StagingStudents', ['ID','Name','Email'])) + except Exception as e: + print(e) + + try: + print('\ntest INSERT','-'*40, '\n') + print(create_insert_code('StagingStudents', ['ID','Name','Email'], [1,'Bob Smith', 'BSmith@gomail.com'])) + except Exception as e: + print(e) + + try: + print('\ntest UPDATE','-'*40, '\n') + print(create_update_code('StagingStudents', ['Name','Email'], ['Rob Smith', 'RSmith@gomail.com'], 'ID', '1')) + except Exception as e: + print(e) + + try: + print('\ntest DELETE','-'*40, '\n') + print(create_delete_code('StagingStudents', 'ID', '1')) + except Exception as e: + print(e) \ No newline at end of file diff --git a/students/KevinCavanaugh/session8/Lab8-3 Create DB.py b/students/KevinCavanaugh/session8/Lab8-3 Create DB.py new file mode 100644 index 0000000..d380f2b --- /dev/null +++ b/students/KevinCavanaugh/session8/Lab8-3 Create DB.py @@ -0,0 +1,41 @@ +import sqlite3 +from sqlite3 import Error as sqlErr + +def create_connection(db_file): + """ Create or connect to a SQLite database """ + try: + con = sqlite3.connect(db_file) + print('SQLite Version is: ', sqlite3.version) + 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 main_menu(): + """ Present a menu to the user """ + print('\n', '='*50, sep='') + print("Choose an option by number: ") + print("\t 1 = Create or Connect to a new file database") + print("\t 2 = Create a new memory database") + print('Type exit to quit program!') + print('='*50, '\n', sep='') + +if __name__ == '__main__': + dbconnection = None + while True: + try: + main_menu() + choice = input("Option: ") + if choice == '1': + fn = input("Enter file name and path: ") + dbconnection = create_connection(fn) + elif choice == '2': + dbconnection = create_connection(':memory:') + elif choice.lower() == 'exit': + break + else: + print('Please enter a number for the option you want!') + except Exception as e: + print('Error ->\t', e.__str__()) \ No newline at end of file diff --git a/students/KevinCavanaugh/session8/Lab8-4 Create Table.py b/students/KevinCavanaugh/session8/Lab8-4 Create Table.py new file mode 100644 index 0000000..dd84c32 --- /dev/null +++ b/students/KevinCavanaugh/session8/Lab8-4 Create Table.py @@ -0,0 +1,83 @@ +import sqlite3 +from sqlite3 import Error as sqlErr + +def create_connection(db_file): + """ Create or connect to a SQLite database """ + try: + con = sqlite3.connect(db_file) + print('SQLite Version is: ', sqlite3.version) + 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(db_con = None, sql_code=''): + """ Execute SQL code on a open connection """ + try: + if db_con is not None and sql_code != '': + 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 create_connection(): ' + se.__str__()) + except Exception as e: + raise Exception('General Error in create_connection(): ' + e.__str__()) + return csr + +def create_table_code(name_of_table, col_names=[None]): + """ Create table code """ + sql_str = '' + try: + if col_names is None: + raise Exception('You must provide at least one column!') + else: + sql_str = 'create table ' + name_of_table + ' (' + for col in col_names: + sql_str += str(col) + ' [text], ' + sql_str = sql_str[0:-2] + ');' # Strip off the last comma + except Exception as e: + raise Exception('Error in create_table_code(): ' + e.__str__()) + return sql_str + + +def main_menu(): + print('\n', '='*50, sep='') + print("Choose an option by number: ") + print("\t 1 = Create or Connect to a new file database") + print("\t 2 = Create a new memory database") + print("\t 3 = Create a new table") + print('Type exit to quit program!') + print('='*50, '\n', sep='') + +if __name__ == '__main__': + dbconnection = None + while True: + try: + main_menu() + choice = input("Option: ") + if choice == '1': + fn = input("Enter file name and path: ") + dbconnection = create_connection(fn) + elif choice == '2': + dbconnection = create_connection(':memory:') + elif choice == '3': + name = input("Enter a name for the table: ") + cols = input("Enter a comma separated list of column names (col1,col2,etc...): ").strip() + sql = create_table_code(name, cols.split(',')) + opt = input('\nPreview:\n\n' + sql + '\n\nCreate the following table?(y/n):') + if opt.lower() == 'y': + csr = execute_sql_code(db_con=dbconnection, sql_code=sql) + csr.close() + else: + print('Info ->\tTable creation cancelled!') + elif choice.lower() == 'exit': + break + else: + print('Please enter a number for the option you want!') + except Exception as e: + print('Error ->\t', e.__str__()) + + dbconnection.close() diff --git a/students/KevinCavanaugh/session8/Lab8-6 Dynamic SQL Transactions.py b/students/KevinCavanaugh/session8/Lab8-6 Dynamic SQL Transactions.py new file mode 100644 index 0000000..a35e3e4 --- /dev/null +++ b/students/KevinCavanaugh/session8/Lab8-6 Dynamic SQL Transactions.py @@ -0,0 +1,200 @@ +import sqlite3 +from sqlite3 import Error as sqlErr + +def create_connection(db_file): + """ Create or connect to a SQLite database """ + try: + con = sqlite3.connect(db_file) + print('SQLite Version is: ', sqlite3.version) + 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(db_con = None, sql_code=''): + """ Execute SQL code on a open connection """ + try: + if db_con is not None and sql_code != '': + csr = db_con.cursor() + csr.execute(sql_code) + db_con.commit() + else: + raise Exception('SQL Code or Connection is missing!') + 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 csr + +def create_table_code(name_of_table, col_names=[None]): + """ Create table code """ + sql_str = '' + try: + if col_names is None: + raise Exception('You must provide at least one column!') + else: + sql_str = 'CREATE TABLE ' + name_of_table + '(' + for col in col_names: + sql_str += str(col) + ' [text], ' + sql_str = sql_str[0:-2] + ');' # Strip off the last comma + except Exception as e: + raise Exception('Error in create_table(): ' + e.__str__()) + return sql_str + +def create_select_code(name_of_table, col_names=[None]): + """ create table select code """ + sql_str = '' + try: + if col_names is None: + raise Exception('You must provide at least one column name!') + else: + sql_str = 'SELECT \n' + for col in col_names: + sql_str += str(col) + ', ' + sql_str = sql_str[0:-2] + '\n' # Strip off the last comma + sql_str += 'FROM ' + name_of_table + ';' + except Exception as e: + raise Exception('Error in create_select_code(): ' + e.__str__()) + return sql_str + +def create_insert_code(name_of_table, col_names=[None], col_values=[None],): + """ create table insert code """ + sql_str = '' + try: + if col_names is None: + raise Exception('You must provide at least one column name!') + else: + sql_str = 'INSERT INTO ' + str(name_of_table).strip() + '\n(' + for col in col_names: + sql_str += str(col) + ', ' + sql_str = sql_str[0:-2] + ')' # Strip off the last comma + if col_values is None: + raise Exception('You must provide at least one column value!') + else: + sql_str += '\nVALUES\n(' + for col in col_values: + sql_str += str(col) + ', ' + sql_str = sql_str[0:-2] + ');' # Strip off the last comma + except Exception as e: + raise Exception('Error in create_insert_code(): ' + e.__str__()) + return sql_str + +def create_update_code(name_of_table, col_names=[None], col_values=[None], where_col = None, where_equals_value = None): + """ create table update code """ + sql_str = '' + try: + if col_names is None: + raise Exception('You must provide at least one column name!') + elif col_values is None: + raise Exception('You must provide at least one column value!') + elif len(col_names) != len(col_values): + raise Exception('You must provide one value for each column') + elif where_col is None or where_equals_value is None: + raise Exception('You must provide a where column and an equals value') + else: + sql_str = 'UPDATE ' + str(name_of_table).strip() + '\nSET\n\t' + counter = 0 + while counter < len(col_names): + sql_str += str(col_names[counter]).strip() \ + + ' = ' + str(col_values[counter]).strip() + ', \n\t' + counter += 1 + sql_str = (sql_str.strip())[0:-1] + '' # Strip off the last comma + sql_str += '\nWHERE ' + where_col + " = " + where_equals_value + except Exception as e: + raise Exception('Error in create_update_code(): ' + e.__str__()) + return sql_str + +def create_delete_code(name_of_table, where_col = None, where_equals_value = None): + """ create table delete code """ + sql_str = '' + try: + if where_col is None or where_equals_value is None: + raise Exception('You must provide a where column and an equals value') + else: + sql_str = 'DELETE FROM ' + str(name_of_table).strip() + sql_str += '\nWHERE ' + where_col + " = " + str(where_equals_value).strip() + except Exception as e: + raise Exception('Error in create_delete_code(): ' + e.__str__()) + return sql_str + + +def main_menu(): + print('\n', '='*50, sep='') + print("Choose an option by number: ") + print("\t 1 = Create or Connect to a new file database") + print("\t 2 = Create a new memory database") + print("\t 3 = Create a new table") + print("\t [s] = Select from table") + print("\t [i] = Insert into table") + print("\t [u] = Update in table") + print("\t [d] = Delete from table") + print('Type exit to quit program!') + print('='*50, '\n', sep='') + + +if __name__ == '__main__': + dbconnection = None + while True: + try: + main_menu() + choice = input("Option: ").strip() + if choice == '1': + fn = input("Enter file name and path: ").strip() + dbconnection = create_connection(fn) + elif choice == '2': + dbconnection = create_connection(':memory:') + elif choice == '3': + t = input("Enter a name for the table: ").strip() + cols = input("Enter a comma separated list of column names (col1,col2,etc...): ").strip() + sql = create_table_code(t, cols.split(',')) + opt = input('\nPreview:\n\n\t' + sql + '\n\nCreate the following table?(y/n):') + if opt.lower() == 'y': + execute_sql_code(db_con=dbconnection, sql_code=sql).close() # Close Cursor + else: + print('Info ->\tTable creation cancelled!') + elif choice == 's': + t = input("Enter a name for the table: ").strip() + cols = input("Enter a comma separated list of column names (col1,col2,etc...): ").strip() + sql = create_select_code(t, cols.split(',')) + print('\nCode Used : ' + sql + '\n') + csrData = execute_sql_code(db_con=dbconnection, sql_code=sql) # Don't close cursor + for row in csrData: + for col in row: + print(col, end=' | ') + print() + csrData.close() # Now close cursor! + elif choice == 'i': + t = input("Enter a name for the table: ").strip() + cols = input("Enter a comma separated list of column names (col1,col2,etc...): ").strip() + colvals = input("Enter a comma separated list of column VALUES (col1,col2,etc...): ").strip() + sql = create_insert_code(t, cols.split(','), colvals.split(',')) + opt = input('\nPreview:\n\n' + sql + '\n\nInsert this data?(y/n):') + if opt.lower() == 'y': + execute_sql_code(db_con=dbconnection, sql_code=sql).close() # Close Cursor + elif choice == 'u': + t = input("Enter a name for the table: ").strip() + cols = input("Enter a comma separated list of column names (col1,col2,etc...): ").strip() + colvals = input("Enter a comma separated list of column VALUES (col1,col2,etc...): ").strip() + wc = input("Enter one WHERE column Name: ").strip() + wv = input("Enter one WHERE column Equals Value: ").strip() + sql = create_update_code(t, cols.split(','), colvals.split(','),where_col=wc, where_equals_value=wv) + opt = input('\nPreview:\n\n' + sql + '\n\nUpdate this data?(y/n):') + if opt.lower() == 'y': + execute_sql_code(db_con=dbconnection, sql_code=sql).close() # Close Cursor + elif choice == 'd': + t = input("Enter a name for the table: ").strip() + wc = input("Enter one WHERE column Name: ").strip() + wv = input("Enter one WHERE column Equals Value: ").strip() + sql = create_delete_code(t, where_col=wc, where_equals_value=wv) + opt = input('\nPreview:\n\n' + sql + '\n\nDelete this data?(y/n):') + if opt.lower() == 'y': + execute_sql_code(db_con=dbconnection, sql_code=sql).close() # Close Cursor + elif choice.lower() == 'exit': + break + else: + print('Please enter a number for the option you want!') + except Exception as e: + print('Error ->\t', e.__str__()) + dbconnection() + diff --git a/students/KevinCavanaugh/session8/SQLValidators.py b/students/KevinCavanaugh/session8/SQLValidators.py new file mode 100644 index 0000000..4dd6753 --- /dev/null +++ b/students/KevinCavanaugh/session8/SQLValidators.py @@ -0,0 +1,14 @@ +# SQL Validators +def check_for_extra_semicolon(SQLStr): + try: + if SQLStr.find(';') != -1: + raise Exception("Extra Semi-Colon Detected!") + except Exception as e: + raise e + +def check_for_or(SQLStr): + try: + if SQLStr.find('or') != -1: + raise Exception("OR Detected!") + except Exception as e: + raise e \ No newline at end of file diff --git a/students/KevinCavanaugh/session8/Simple SQL Transactions.py b/students/KevinCavanaugh/session8/Simple SQL Transactions.py new file mode 100644 index 0000000..625b683 --- /dev/null +++ b/students/KevinCavanaugh/session8/Simple SQL Transactions.py @@ -0,0 +1,51 @@ +import sqlite3 +from sqlite3 import Error as SqlErr + +def create_demo(con): + with db_con: + csr = db_con.cursor() + csr.execute("CREATE TABLE IF NOT EXISTS Demo (ID [integer], Name [text]);") + db_con.commit() + +def sel_demo(con): + with db_con: + csr = db_con.cursor() + csr.execute("SELECT * FROM DEMO;") + db_con.commit() + return csr + +def ins_demo(con, values=[None]): + if values is not None: + with db_con: + csr = db_con.cursor() + csr.execute("INSERT INTO Demo (ID, Name) values (?,?);", values) + db_con.commit() + +def upd_demo(con, values=[None]): + if values is not None: + with db_con: + csr = db_con.cursor() + csr.execute("UPDATE Demo SET ID = ?, Name = ? WHERE ID = ?;", values) + db_con.commit() + +def del_demo(con, values=[None]): + if values is not None: + with db_con: + csr = db_con.cursor() + csr.execute("DELETE FROM Demo WHERE ID = ?;", values) + db_con.commit() + +if __name__ == '__main__': + db_con = sqlite3.connect('Lab8-5.db') + create_demo(db_con) + + ins_demo(db_con, [1,'Bob']) # Must use single quotes + for row in sel_demo(db_con): print(row) + + upd_demo(db_con,[1,'Rob', 1]) + for row in sel_demo(db_con): print(row) + + del_demo(db_con, [1]) + for row in sel_demo(db_con): print(row) + + diff --git a/students/KevinCavanaugh/session8/SimpleDemo.db b/students/KevinCavanaugh/session8/SimpleDemo.db new file mode 100644 index 0000000000000000000000000000000000000000..ee94ce655c5e437d3bbd5fba988e3003e26f8a02 GIT binary patch literal 12288 zcmeI#y$ZrG5Ww*yiks*nb-YnQTzmnm?I4KY$0iOHq7XPlj9&MiIrYEx`v$A&f;x^q-*Me3{@5?HY%}zy{w;ILCw-QBf?wfuB0R#|0009ILKmY** l5I_I{1b$e6{{M$Rm!~0s00IagfB*srAb 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): + """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 + + def create_connection(self, db_file: str): + """ 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, 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): # create (C/R/U/D) + # Validate Input + sql = str.format("INSERT Not Implemented Yet") + return sql + + def build_sel_code(self): # read + # Validate Input + sql = str.format("SELECT Not Implemented Yet") + return sql + + def build_upd_code(self): # update + # Validate Input + sql = str.format("UPDATE Not Implemented Yet") + return sql + + def build_del_code(self): # delete + # Validate Input + # Validate Input + sql = str.format("DELETE 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 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 + + + diff --git a/students/KevinCavanaugh/session8/circle_classes_assignment.py b/students/KevinCavanaugh/session8/circle_classes_assignment.py new file mode 100644 index 0000000..e4ddf82 --- /dev/null +++ b/students/KevinCavanaugh/session8/circle_classes_assignment.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 + +# ----------------------------------------------------------------------- # +# Title: html_render +# Author: Kevin Cavanaugh +# Change Log: (Who,What,When) +# kcavanau, started assignment, 03/03/2019 +# ----------------------------------------------------------------------- # + +''' +The purpose of this assignment is to create a nifty Circle class that will +demonstrate properties and Python's magic methods +''' + +from math import pi + +########## +# STEP 1 # +########## + +class Circle(object): + ''' + This is a simple class utilzed to represent a circle + ''' + + def __init__(self, radius): + self.radius = float(radius) + + ########## + # STEP 2 # + ########## + + @property + def diameter(self): + return self.radius * 2 + + ########## + # STEP 3 # + ########## + + @diameter.setter + def diameter(self, value): + self.radius = value / 2 + + ########## + # STEP 4 # + ########## + + @property + def area(self): + return self.radius ** 2 * pi + + ########## + # STEP 5 # + ########## + + @classmethod + def from_diameter(cls, diameter): + return cls(diameter/2) + + ########## + # STEP 6 # + ########## + + def __str__(self): + return f'Circle with radius: {self.radius:6f}' + + def __repr__(self): + return f'Circle({self.radius})' + +c = Circle(4) +d = eval(repr(c)) + +print(d) + + diff --git a/students/KevinCavanaugh/session8/demo.py b/students/KevinCavanaugh/session8/demo.py new file mode 100644 index 0000000..fbdfacd --- /dev/null +++ b/students/KevinCavanaugh/session8/demo.py @@ -0,0 +1,146 @@ +import sqlite3 +from sqlite3 import Error as sqlErr + +def create_connection(db_file): + """ Create or connect to a SQLite database """ + try: + con = sqlite3.connect(db_file) + print('SQLite Version is: ', sqlite3.version) + 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(db_con = None, sql_code=''): + """ Execute SQL code on a open connection """ + try: + if db_con is not None and sql_code != '': + csr = db_con.cursor() + csr.execute(sql_code) + db_con.commit() + else: + raise Exception('SQL Code or Connection is missing!') + 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 csr + +def create_table_code(name_of_table, col_names=[None]): + """ Create staging table code """ + sql_str = '' + try: + if col_names is None: + raise Exception('You must provide at least one column!') + else: + sql_str = 'CREATE TABLE ' + name_of_table + '(' + for col in col_names: + sql_str += str(col) + ' [text], ' + sql_str = sql_str[0:-2] + ');' # Strip off the last comma + except Exception as e: + raise Exception('Error in create_table(): ' + e.__str__()) + return sql_str + +def create_select_code(name_of_table, col_names=[None]): + """ create staging table select code """ + sql_str = '' + try: + if col_names is None: + raise Exception('You must provide at least one column name!') + else: + sql_str = 'SELECT \n' + for col in col_names: + sql_str += str(col) + ', ' + sql_str = sql_str[0:-2] + '\n' # Strip off the last comma + sql_str += 'FROM ' + name_of_table + ';' + except Exception as e: + raise Exception('Error in create_select_code(): ' + e.__str__()) + return sql_str + +def create_insert_code(name_of_table, col_names=[None], col_values=[None],): + """ create staging table insert code """ + sql_str = '' + try: + if col_names is None: + raise Exception('You must provide at least one column name!') + else: + sql_str = 'INSERT INTO ' + str(name_of_table).strip() + '\n(' + for col in col_names: + sql_str += str(col) + ', ' + sql_str = sql_str[0:-2] + ')' # Strip off the last comma + if col_values is None: + raise Exception('You must provide at least one column value!') + else: + sql_str += '\nVALUES\n(' + for col in col_values: + sql_str += str(col) + ', ' + sql_str = sql_str[0:-2] + ');' # Strip off the last comma + except Exception as e: + raise Exception('Error in create_insert_code(): ' + e.__str__()) + return sql_str + +def create_update_code(name_of_table, col_names=[None], col_values=[None], where_col = None, where_equals_value = None): + """ create staging table update code """ + sql_str = '' + try: + if col_names is None: + raise Exception('You must provide at least one column name!') + elif col_values is None: + raise Exception('You must provide at least one column value!') + elif len(col_names) != len(col_values): + raise Exception('You must provide one value for each column') + elif where_col is None or where_equals_value is None: + raise Exception('You must provide a where column and an equals value') + else: + sql_str = 'UPDATE ' + str(name_of_table).strip() + '\nSET\n\t' + counter = 0 + while counter < len(col_names): + sql_str += str(col_names[counter]).strip() \ + + ' = ' + str(col_values[counter]).strip() + ', \n\t' + counter += 1 + sql_str = (sql_str.strip())[0:-1] + '' # Strip off the last comma + sql_str += '\nWHERE ' + where_col + " = " + where_equals_value + except Exception as e: + raise Exception('Error in create_update_code(): ' + e.__str__()) + return sql_str + +def create_delete_code(name_of_table, where_col = None, where_equals_value = None): + """ create staging table delete code """ + sql_str = '' + try: + if where_col is None or where_equals_value is None: + raise Exception('You must provide a where column and an equals value') + else: + sql_str = 'DELETE FROM ' + str(name_of_table).strip() + sql_str += '\nWHERE ' + where_col + " = " + str(where_equals_value).strip() + except Exception as e: + raise Exception('Error in create_delete_code(): ' + e.__str__()) + return sql_str + + +if __name__ == '__main__': + + try: + print('\ntest SELECT','-'*40, '\n') + print(create_select_code('StagingStudents', ['ID,Name,Email'])) + except Exception as e: + print(e) + + try: + print('\ntest INSERT','-'*40, '\n') + print(create_insert_code('StagingStudents', ['ID,Name,Email'], [1,'Bob Smith', 'BSmith@gomail.com'])) + except Exception as e: + print(e) + + try: + print('\ntest UPDATE','-'*40, '\n') + print(create_update_code('StagingStudents', ['Name','Email'], ['Rob Smith', 'RSmith@gomail.com'], 'ID', '1')) + except Exception as e: + print(e) + + try: + print('\ntest DELETE','-'*40, '\n') + print(create_delete_code('StagingStudents', 'ID', '1')) + except Exception as e: + print(e) \ No newline at end of file diff --git a/students/KevinCavanaugh/session8/demo_2.py b/students/KevinCavanaugh/session8/demo_2.py new file mode 100644 index 0000000..d152a30 --- /dev/null +++ b/students/KevinCavanaugh/session8/demo_2.py @@ -0,0 +1,62 @@ +#!/usr/bin/python3 + +from tkinter import * +fields = ('Annual Rate', 'Number of Payments', 'Loan Principle', 'Monthly Payment', 'Remaining Loan') + +def monthly_payment(entries): + # period rate: + r = (float(entries['Annual Rate'].get()) / 100) / 12 + print("r", r) + # principal loan: + loan = float(entries['Loan Principle'].get()) + n = float(entries['Number of Payments'].get()) + remaining_loan = float(entries['Remaining Loan'].get()) + q = (1 + r)** n + monthly = r * ( (q * loan - remaining_loan) / ( q - 1 )) + monthly = ("%8.2f" % monthly).strip() + entries['Monthly Payment'].delete(0,END) + entries['Monthly Payment'].insert(0, monthly ) + print("Monthly Payment: %f" % float(monthly)) + +def final_balance(entries): + # period rate: + r = (float(entries['Annual Rate'].get()) / 100) / 12 + print("r", r) + # principal loan: + loan = float(entries['Loan Principle'].get()) + n = float(entries['Number of Payments'].get()) + q = (1 + r)** n + monthly = float(entries['Monthly Payment'].get()) + q = (1 + r)** n + remaining = q * loan - ( (q - 1) / r) * monthly + remaining = ("%8.2f" % remaining).strip() + entries['Remaining Loan'].delete(0,END) + entries['Remaining Loan'].insert(0, remaining ) + print("Remaining Loan: %f" % float(remaining)) + +def makeform(root, fields): + entries = {} + for field in fields: + row = Frame(root) + lab = Label(row, width=22, text=field+": ", anchor='w') + ent = Entry(row) + ent.insert(0,"0") + row.pack(side=TOP, fill=X, padx=5, pady=5) + lab.pack(side=LEFT) + ent.pack(side=RIGHT, expand=YES, fill=X) + entries[field] = ent + return entries + +if __name__ == '__main__': + root = Tk() + ents = makeform(root, fields) + root.bind('', (lambda event, e=ents: fetch(e))) + b1 = Button(root, text='Final Balance', + command=(lambda e=ents: final_balance(e))) + b1.pack(side=LEFT, padx=5, pady=5) + b2 = Button(root, text='Monthly Payment', + command=(lambda e=ents: monthly_payment(e))) + b2.pack(side=LEFT, padx=5, pady=5) + b3 = Button(root, text='Quit', command=root.quit) + b3.pack(side=LEFT, padx=5, pady=5) + root.mainloop() \ No newline at end of file diff --git a/students/KevinCavanaugh/session8/inventory_processor.py b/students/KevinCavanaugh/session8/inventory_processor.py new file mode 100644 index 0000000..75ee129 --- /dev/null +++ b/students/KevinCavanaugh/session8/inventory_processor.py @@ -0,0 +1,30 @@ +from base_class import DBProcessor + + +class InventoryProcessor(DBProcessor): + + def build_ins_code(self, inventory_id: int, inventory_date: str): + DBProcessor.check_for_date(inventory_date) + sql = str.format("INSERT 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 diff --git a/students/KevinCavanaugh/session8/lesson_08.db b/students/KevinCavanaugh/session8/lesson_08.db new file mode 100644 index 0000000000000000000000000000000000000000..e8e37e43a5a3675284b135df3ee3e7bb987cc197 GIT binary patch literal 8192 zcmeI#F$%&k6vpvH1Sip@==eqjaq$9H=~fW6n>a*_ZNXZQ46dHYYj`XZusC*?|3@Cl zOEUeox8J6vvvR5Lm2t9AL#4G^iYTSDua2)Kq3<@0-$UOPt>)u*-~ZBsm-34sfB*sr zAb 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): + 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 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 + + +# Inventory +def ins_inventory(inventory_id: int, inventory_date: str): + check_for_date(inventory_date) + sql = str.format("INSERT INTO Inventories (InventoryID, InventoryDate) " + "VALUES ({id},'{date}');", id=inventory_id, date=inventory_date) + return sql + + +def upd_inventory(inventory_id: int, inventory_date: str): + 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 del_inventory(inventory_id: int): + sql = str.format("DELETE FROM Inventories WHERE InventoryID = {id};", id=inventory_id) + return sql + + +def sel_inventory(inventory_id: int = None): + if inventory_id is not None: + inventory_id = ' WHERE inventory_id = ' + str(inventory_id) # Will be validated at execution! + else: + inventory_id = '' + sql = str.format("SELECT InventoryID, InventoryDate FROM Inventories{id};", id=inventory_id) + return sql + + +if __name__ == '__main__': + try: + db = create_connection() + except Exception as e: + print('Connection failed!', e) + + # Test SQL creation + sql_str = ins_inventory(inventory_id=3, inventory_date='2000-03-01') + print(sql_str) + sql_str = upd_inventory(inventory_id=3, inventory_date='2000-03-02') + print(sql_str) + sql_str = del_inventory(inventory_id=3) + print(sql_str) + sql_str = sel_inventory() + print(sql_str) + sql_str = sel_inventory(inventory_id=3) + print(sql_str) + + # Test SQL validation + try: + check_for_or(sel_inventory(inventory_id="2 OR 1 = 1")) # SQL Injection + except Exception as e: + print(e) + try: + check_for_extra_semicolon(sel_inventory(inventory_id="1;Delete From T1;")) # SQL Injection + except Exception as e: + print(e) + try: + check_for_date(ins_inventory(inventory_id=3, inventory_date='03/03/2000')) # Date Format Error + except Exception as e: + print(e) + + # Test SQL execution + csr = execute_sql_code(db_con=db, sql_code=sel_inventory()) + for row in csr: + print(row) diff --git a/students/KevinCavanaugh/session8/test final.py b/students/KevinCavanaugh/session8/test final.py new file mode 100644 index 0000000..b702e19 --- /dev/null +++ b/students/KevinCavanaugh/session8/test final.py @@ -0,0 +1,143 @@ +import sqlite3 +from sqlite3 import Error as sqlErr +import re as rex + +from sqlite3 import Error as sql_err + +#!/usr/bin/env python3 + +# ----------------------------------------------------------------------- # +# Title: sqlite3_project +# Author: Kevin Cavanaugh +# Change Log: (Who,What,When) +# kcavanau, started assignment, 03/05/2019 +# ----------------------------------------------------------------------- # +def create_connection(db_file: str = ':memory:'): + """ 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): + 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 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 + + +# Inventory +def ins_inventory(inventory_id: int, inventory_date: str): + check_for_date(inventory_date) + sql = str.format("INSERT INTO Inventories (InventoryID, InventoryDate) " + "VALUES ({id},'{date}');", id=inventory_id, date=inventory_date) + return sql + + +def upd_inventory(inventory_id: int, inventory_date: str): + 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 del_inventory(inventory_id: int): + sql = str.format("DELETE FROM Inventories WHERE InventoryID = {id};", id=inventory_id) + return sql + + +def sel_inventory(inventory_id: int = None): + if inventory_id is not None: + inventory_id = ' WHERE inventory_id = ' + str(inventory_id) # Will be validated at execution! + else: + inventory_id = '' + sql = str.format("SELECT InventoryID, InventoryDate FROM Inventories{id};", id=inventory_id) + return sql + + +if __name__ == '__main__': + try: + db = create_connection() + except Exception as e: + print('Connection failed!', e) + + # Test SQL creation + str_create_table = """CREATE TABLE Inventories (InventoryID int Primary Key, InventoryDate date);""" + sql_str = ins_inventory(inventory_id=3, inventory_date='2000-03-01') + print(sql_str) + sql_str = upd_inventory(inventory_id=3, inventory_date='2000-03-02') + print(sql_str) + sql_str = del_inventory(inventory_id=3) + print(sql_str) + sql_str = sel_inventory() + print(sql_str) + sql_str = sel_inventory(inventory_id=3) + print(sql_str) + + # Test SQL validation + try: + check_for_or(sel_inventory(inventory_id="2 OR 1 = 1")) # SQL Injection + except Exception as e: + print(e) + try: + check_for_extra_semicolon(sel_inventory(inventory_id="1;Delete From T1;")) # SQL Injection + except Exception as e: + print(e) + try: + check_for_date(ins_inventory(inventory_id=3, inventory_date='03/03/2000')) # Date Format Error + except Exception as e: + print(e) + + + # Test SQL execution + csr = execute_sql_code(db_con=db, sql_code=sel_inventory()) + for row in csr: + print(row) diff --git a/students/KevinCavanaugh/session8/test_base.py b/students/KevinCavanaugh/session8/test_base.py new file mode 100644 index 0000000..376bacb --- /dev/null +++ b/students/KevinCavanaugh/session8/test_base.py @@ -0,0 +1,56 @@ + +import base_class as dp + +debugDP = False +debugIP = True + +if __name__ == '__main__': + # Test DataProcessor methods + if debugDP == True: + try: dp.DBProcessor.check_for_or("SELECT * FROM T1 WHERE ID = 1 or 1 = 1") + except Exception as e: print(e) + try: dp.DBProcessor.check_for_extra_semicolon("SELECT * ;Delete From T1; FROM T1;") + except Exception as e: print(e) + try: dp.DBProcessor.check_for_date('01/01/2000') + except Exception as e: print(e) + + dbp = dp.DBProcessor(':memory:') + print(dbp.build_ins_code()) + print(dbp.build_upd_code()) + print(dbp.build_del_code()) + print(dbp.build_sel_code()) + print(dbp.build_sel_code()) + csr = dbp.execute_sql_code("Select 5 + 5;") + for e in csr: + print(e) + print(dbp.execute_sql_code("Select 5 + 5;")) + dbp.db_con.close() + + if debugIP == True: + ip = dp.InventoryProcessor(':memory:') + print(ip.build_ins_code(inventory_id=1, inventory_date='2000-01-01')) + print(ip.build_upd_code(inventory_id=1, inventory_date='2000-02-02')) + print(ip.build_del_code(inventory_id=1)) + print(ip.build_sel_code()) + + # Create a table for testing + crs = ip.db_con.cursor() + crs.execute("CREATE TABLE Inventories (InventoryID int, InventoryDate date);") + ip.db_con.commit() + for row in crs.execute("Select name, sql From sqlite_master Where type='table;'"): + print(row) + ip.db_con.commit() + + # Test SQL Transactions + ip.execute_sql_code(ip.build_ins_code(inventory_id=1, inventory_date='2000-01-01')).close() + for row in ip.execute_sql_code(ip.build_sel_code()): + print(row) + + ip.execute_sql_code(ip.build_upd_code(inventory_id=1, inventory_date='2000-02-02')).close() + for row in ip.execute_sql_code(ip.build_sel_code(inventory_id=1)): + print(row) + + ip.execute_sql_code(ip.build_del_code(inventory_id=1)).close() + for row in ip.execute_sql_code(ip.build_sel_code()): + print(row) +