diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..44fcab8 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.ipynb filter=nbstripout \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c07589 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.idea ++.DS_Store* +.pytest_cache +__pycache__/ +*.rb +.vscode +CACHEDIR.TAG +.venv/ \ No newline at end of file diff --git a/assignment1/assignment1-test.py b/assignment1/assignment1-test.py new file mode 100644 index 0000000..9333a2e --- /dev/null +++ b/assignment1/assignment1-test.py @@ -0,0 +1,59 @@ +import assignment1 as a1 + +def test_hello(): + assert a1.hello() == "Hello!" + +def test_greet(): + assert a1.greet("James") == "Hello, James!" + +def test_calc(): + assert a1.calc(5,6) == 30 + assert a1.calc(5,6,"add") == 11 + assert a1.calc(20,5,"divide") == 4 + assert a1.calc(14,2.0,"multiply") == 28.0 + assert a1.calc(12.6, 4.4, "subtract") == 8.2 + assert a1.calc(9,5, "modulo") == 4 + assert a1.calc(10,0,"divide") == "You can't divide by 0!" + assert a1.calc("first", "second", "multiply") == "You can't multiply those values!" + +def test_data_type_conversion(): + result = a1.data_type_conversion("110", "int") + assert type(result).__name__ == "int" + assert result == 110 + result = a1.data_type_conversion("5.5", "float") + assert type(result).__name__ == "float" + assert result == 5.5 + result = a1.data_type_conversion(7,"float") + assert type(result).__name__ == "float" + assert result == 7.0 + result = a1.data_type_conversion(91.1,"str") + assert type(result).__name__ == "str" + assert result == "91.1" + assert a1.data_type_conversion("banana", "int") == "You can't convert banana into a int." + +def test_grade(): + assert a1.grade(75,85,95) == "B" + assert a1.grade("three", "blind", "mice") == "Invalid data was provided." + +def test_repeat(): + assert a1.repeat("up,", 4) == "up,up,up,up," + +def test_student_scores(): + assert a1.student_scores("mean", Tom=75, Dick=89, Angela=91) == (75 + 89 + 91) / 3 + assert a1.student_scores("best", Tom=75, Dick=89, Angela=91, Frank=50 ) == "Angela" + +def test_titleize(): + assert a1.titleize("war and peace") == "War and Peace" + assert a1.titleize("a separate peace") == "A Separate Peace" + assert a1.titleize("after on") == "After On" + +def test_hangman(): + assert a1.hangman("difficulty","ic") == "_i__ic____" + +def test_pig_latin(): + assert a1.pig_latin("apple") == "appleay" + assert a1.pig_latin("banana") == "ananabay" + assert a1.pig_latin("cherry") == "errychay" + assert a1.pig_latin("quiet") == "ietquay" + assert a1.pig_latin("square") == "aresquay" + assert a1.pig_latin("the quick brown fox") == "ethay ickquay ownbray oxfay" \ No newline at end of file diff --git a/assignment1/assignment1.py b/assignment1/assignment1.py new file mode 100644 index 0000000..fafa187 --- /dev/null +++ b/assignment1/assignment1.py @@ -0,0 +1 @@ +# Write your code here. \ No newline at end of file diff --git a/assignment10/.keep b/assignment10/.keep new file mode 100644 index 0000000..e69de29 diff --git a/assignment2/assignment2-test.py b/assignment2/assignment2-test.py new file mode 100644 index 0000000..68560d8 --- /dev/null +++ b/assignment2/assignment2-test.py @@ -0,0 +1,73 @@ +import assignment2 as a2 +import os + +def test_read_employees(): + employees = a2.read_employees() + assert employees != None + assert a2.employees != None + assert len(a2.employees["fields"]) == 4 + assert a2.employees["fields"][1] == "first_name" + assert len(a2.employees["rows"]) == 20 + +def test_column_name(): + assert a2.column_index("last_name") == 2 + assert a2.employee_id_column != None + +def test_first_name(): + assert a2.first_name(2) in ("David","Lauren") # values before and after sort + +def test_employee_find(): + match = a2.employee_find(3) + assert match[0][0] == "3" + assert len(match[0]) == 4 + +def test_employee_find_2(): + match = a2.employee_find_2(4) + assert match[0][0] == "4" + assert len(match[0]) == 4 + +def test_sort_by_last_name(): + rows = a2.sort_by_last_name() + assert len(rows) == 20 + assert rows[0][2]== "Bowman" + +def test_employee_dict(): + dict_result = a2.employee_dict(a2.employees["rows"][0]) + assert dict_result["last_name"] == "Bowman" + assert "employee_id" not in dict_result.keys() + +def test_all_employees_dict(): + dict_result = a2.all_employees_dict() + assert len(dict_result.keys()) == 20 + assert dict_result["9"]["first_name"] == "Phillip" + +def test_get_this_value(): + assert a2.get_this_value() == "ABC" + +def test_set_that_secret(): + import custom_module + a2.set_that_secret("swordfish") + assert custom_module.secret == "swordfish" + +def test_read_minutes(): + d1, d2 = a2.read_minutes() + assert d1["rows"][1] == ("Tony Henderson","November 15, 1991") + assert d2["rows"][2] == ("Sarah Murray","November 19, 1988") + assert a2.minutes1 != None + +def test_create_minutes_set(): + minutes_set = a2.create_minutes_set() + assert type(minutes_set).__name__ == "set" + assert len(minutes_set) == 46 + assert a2.minutes_set != None + +def test_create_minutes_list(): + minutes_list = a2.create_minutes_list() + assert type(minutes_list[0][1]).__name__ == "datetime" + assert type(minutes_list[0]).__name__ == "tuple" + assert a2.minutes_list != None + +def test_write_sorted_list(): + sorted_list = a2.write_sorted_list() + assert sorted_list[0] == ("Jason Tucker","September 20, 1980") + assert os.access("./minutes.csv", os.F_OK) == True \ No newline at end of file diff --git a/assignment2/minutes.csv b/assignment2/minutes.csv new file mode 100644 index 0000000..0acabb7 --- /dev/null +++ b/assignment2/minutes.csv @@ -0,0 +1,47 @@ +Name,Date +Jason Tucker,"September 20, 1980" +Austin Hester,"March 8, 1981" +Daniel Jackson,"October 2, 1981" +Mrs. Samantha Johnson,"December 17, 1981" +Joseph Harris,"March 3, 1982" +Mrs. Samantha Johnson,"March 12, 1982" +Gina Maldonado,"December 16, 1982" +Mrs. Samantha Johnson,"December 23, 1982" +Yesenia Smith,"August 10, 1983" +Lori Martin,"February 5, 1984" +Jonathan Parrish,"June 12, 1984" +Mrs. Samantha Johnson,"July 20, 1984" +Amanda Brown,"August 8, 1984" +Sarah Murray,"October 30, 1984" +Mrs. Samantha Johnson,"November 28, 1984" +Austin Hester,"June 4, 1985" +Jonathan Parrish,"March 18, 1986" +Yesenia Smith,"May 6, 1986" +Daniel Jackson,"December 13, 1986" +Gina Maldonado,"February 13, 1987" +Kimberly Stewart,"December 12, 1987" +Mrs. Samantha Johnson,"July 10, 1988" +Sarah Murray,"August 16, 1988" +Aaron Kaufman,"October 24, 1988" +Tony Henderson,"November 7, 1988" +Sarah Murray,"November 19, 1988" +Austin Hester,"January 18, 1989" +Joseph Harris,"March 1, 1989" +Gina Maldonado,"April 7, 1989" +Aaron Kaufman,"November 14, 1989" +Daniel Jackson,"April 8, 1990" +Aaron Kaufman,"May 1, 1990" +Aaron Kaufman,"July 21, 1990" +Tony Henderson,"October 4, 1990" +Yesenia Smith,"November 23, 1990" +Joseph Harris,"April 3, 1991" +Jason Tucker,"April 30, 1991" +Matthew Russell,"May 31, 1991" +Lori Martin,"July 8, 1991" +Mrs. Samantha Johnson,"July 23, 1991" +Tony Henderson,"November 15, 1991" +Gina Maldonado,"February 9, 1992" +Sarah Murray,"June 27, 1992" +Gina Maldonado,"October 31, 1992" +Austin Hester,"December 10, 1992" +Mrs. Samantha Johnson,"December 12, 1992" diff --git a/assignment3/.keep b/assignment3/.keep new file mode 100644 index 0000000..e69de29 diff --git a/assignment3/decorator.log b/assignment3/decorator.log new file mode 100644 index 0000000..3a29aee --- /dev/null +++ b/assignment3/decorator.log @@ -0,0 +1,15 @@ +function: task_1a +positional parameters: none +keyword parameters: none +return: None + +function: task_1b +positional parameters: [10, 20] +keyword parameters: none +return: True + +function: task_1c +positional parameters: none +keyword parameters: {'user': 'Ricardo', 'status': 'Student'} +return: logger_decorator + diff --git a/assignment3/developer-class.py b/assignment3/developer-class.py new file mode 100644 index 0000000..746ed2a --- /dev/null +++ b/assignment3/developer-class.py @@ -0,0 +1,15 @@ +class Employee: + def __init__(self, first, last, salary): + self.first = first + self.last = last + self.salary = float(salary) + +class Developer(Employee): + def __init__(self, first, last, salary, prog_lang): + super().__init__(first, last, salary) + self.prog_lang = prog_lang + +dev_1 = Developer("Ricardo", "Santiz", 60000, "Python") +print(f"Name: {dev_1.first} {dev_1.last}") +print(f"Language: {dev_1.prog_lang}") +print(f"Salary: {dev_1.salary}") \ No newline at end of file diff --git a/assignment3/employee-class.py b/assignment3/employee-class.py new file mode 100644 index 0000000..aa48b5d --- /dev/null +++ b/assignment3/employee-class.py @@ -0,0 +1,16 @@ + +class Employee: + def __init__(self, first, last, salary): + self.first = first + self.last = last + self.salary = float(salary) + self.email = f"{first.lower()}.{last.lower()}@company.com" + + def give_raise(self, amount): + self.salary += amount + +emp_1 = Employee("Ricardo", "Santiz", 50000) +print(emp_1.email) +print(f"Old Salary: {emp_1.salary}") +emp_1.give_raise(5555) +print(f"New Salary: {emp_1.salary}") diff --git a/assignment3/hangman-closure.py b/assignment3/hangman-closure.py new file mode 100644 index 0000000..4577aca --- /dev/null +++ b/assignment3/hangman-closure.py @@ -0,0 +1,25 @@ +def hangman_game(word): + word = word.lower() + guessed_letters = [] + + def guess(letter): + letter = letter.lower() + if letter in guessed_letters: + return f"You already guessed '{letter}'." + + guessed_letters.append(letter) + + display_word = [char if char in guessed_letters else "_" for char in word] + + if letter in word: + return f"Correct! {' '.join(display_word)}" + else: + return f"Incorrect. {' '.join(display_word)}" + + return guess + +play = hangman_game("Python") +print(play("p")) +print(play("y")) +print(play("z")) +print(play("p")) diff --git a/assignment3/list-comprehensions.py b/assignment3/list-comprehensions.py new file mode 100644 index 0000000..29dd0da --- /dev/null +++ b/assignment3/list-comprehensions.py @@ -0,0 +1,12 @@ +import csv + +with open('csv/employees.csv', 'r') as file: + reader = csv.reader(file) + data = list(reader) + + +full_names = [f"{row[0]} {row[1]}" for row in data[1:]] +print(full_names) + +names_with_e = [name for name in full_names if 'e' in name.lower()] +print(names_with_e) \ No newline at end of file diff --git a/assignment3/log-decorator.py b/assignment3/log-decorator.py new file mode 100644 index 0000000..dd5b90a --- /dev/null +++ b/assignment3/log-decorator.py @@ -0,0 +1,34 @@ +import logging +logger = logging.getLogger(__name__ + "_parameter_log") +logger.setLevel(logging.INFO) +logger.addHandler(logging.FileHandler("./assignment3/decorator.log","a")) + +def logger_decorator(func): + def wrapper(*args, **kwargs): + pos_params = list(args) if args else "none" + kw_params = kwargs if kwargs else "none" + result = func(*args, **kwargs) + + log_msg = (f"function: {func.__name__}\n" + f"positional parameters: {pos_params}\n" + f"keyword parameters: {kw_params}\n" + f"return: {result}\n") + logger.info(log_msg) + return result + return wrapper + +@logger_decorator +def task_1a(): + print("Hello, World!") + +@logger_decorator +def task_1b(*args): + return True + +@logger_decorator +def task_1c(**kwargs): + return "logger_decorator" + +task_1a() +task_1b(10, 20) +task_1c(user="Ricardo", status="Student") diff --git a/assignment3/type-decorator.py b/assignment3/type-decorator.py new file mode 100644 index 0000000..8c14d41 --- /dev/null +++ b/assignment3/type-decorator.py @@ -0,0 +1,21 @@ +def type_converter(type_of_output): + def decorator(func): + def wrapper(*args, **kwargs): + value = func(*args, **kwargs) + return type_of_output(value) + return wrapper + return decorator + +@type_converter(str) +def return_int(): + return 5 + +@type_converter(int) +def return_string_num(): + return "123" + +string_five = return_int() +int_one_two_three = return_string_num() + +print(f"Value: {string_five}, Type: {type(string_five).__name__}") +print(f"Value: {int_one_two_three}, Type: {type(int_one_two_three).__name__}") diff --git a/assignment4/assignment4-test.py b/assignment4/assignment4-test.py new file mode 100644 index 0000000..3ad40a9 --- /dev/null +++ b/assignment4/assignment4-test.py @@ -0,0 +1,133 @@ +import assignment4 as a4 +import numpy as np +import pandas as pd +import os + +test1_df = pd.DataFrame({ 'Name': ['Alice', 'Bob', 'Charlie'], + 'Age': [25, 30, 35], + 'City': ['New York', 'Los Angeles', 'Chicago']}) + +# Task 1 +def test_data_frame_from_dictionary(): + assert test1_df.equals(a4.task1_data_frame) + +def test_added_column(): + assert a4.task1_with_salary['Salary'].equals(pd.Series([70000, 80000, 90000])) + +def test_increment_column(): + assert a4.task1_older["Age"].equals(pd.Series([26, 31, 36])) + +def test_write_csv(): + assert os.access("./employees.csv", os.F_OK) == True + # make sure there is no index + assert pd.read_csv('employees.csv').shape == (3, 4) + + + +# Task 2 +def test_read_data_frame_from_csv(): + assert a4.task1_older.equals(a4.task2_employees) + +test2_json_df = pd.DataFrame({ 'Name': ['Eve', 'Frank'], + 'Age': [28, 40], + 'City': ['Miami', 'Seattle'], + 'Salary': [60000, 95000]}) + +def test_read_data_frame_from_json(): + assert os.access("./additional_employees.json", os.F_OK) == True + assert a4.json_employees.equals(test2_json_df) + +def test_concat_json_employees(): + assert a4.more_employees.equals(pd.concat([a4.task2_employees, a4.json_employees], ignore_index=True)) + assert a4.more_employees.shape == (5, 4) + + +# Task 3 +def test_head(): + assert a4.first_three.equals(a4.more_employees.head(3)) + +def test_tail(): + assert a4.last_two.equals(a4.more_employees.tail(2)) + +def test_shape(): + assert a4.employee_shape == (5, 4) + + +# Task 4 +from io import StringIO +sample_data = """Name,Age,Salary,Hire Date,Department +Alice, 29,50000,2021/01/15, Sales +Bob, 32, unknown,2020-03-18,MARKETING + charlie, NaN, 70000,3/25/2019,marketinG +Dana, 41, n/a,2020/12/01, HR +Eve, 24,65000,2021/06/07, hr +Frank, 32,75000, 2019-07-11,Sales +Bob, 32, unknown,2020-03-18,MARKETING +""" +# Read into DataFrame +ddf = pd.read_csv(StringIO(sample_data)) +tdf = ddf.copy() + +# Perform the same cleaning steps +tdf.drop_duplicates(inplace=True) +tdf['Age'] = pd.to_numeric(tdf['Age'], errors='coerce') +tdf['Salary'] = tdf['Salary'].replace(['unknown', 'n/a'], pd.NA) +tdf['Salary'] = pd.to_numeric(tdf['Salary'], errors='coerce') +tdf['Hire Date'] = pd.to_datetime(tdf['Hire Date'], errors='coerce') +tdf['Name'] = tdf['Name'].str.strip() +tdf['Department'] = tdf['Department'].str.strip().str.upper() + +def test_dirty_data_read(): + assert a4.dirty_data.equals(ddf) + +def test_no_duplicate_rows(): + assert len(a4.clean_data) == 6 + +def test_age_numeric(): + assert pd.api.types.is_numeric_dtype(a4.clean_data['Age']) + assert a4.clean_data['Age'].dropna().between(1, 100).all() + +def test_salary_numeric(): + assert pd.api.types.is_numeric_dtype(a4.clean_data['Salary']) + +def test_no_missing_age_or_salary(): + assert not a4.clean_data['Age'].isnull().any() + assert not a4.clean_data['Salary'].isnull().any() + +def test_hire_date_datetime(): + assert pd.api.types.is_datetime64_any_dtype(a4.clean_data['Hire Date']) + +def test_department_uppercase(): + all_upper = True + for dept in a4.clean_data['Department']: + if not dept.isupper(): + all_upper = False + assert all_upper + +# April 2: If dates are not converted properly with form="mixed" will end up with NaTs +def test_hire_date_notNAT(): + nat_count = a4.clean_data['Hire Date'].isna().sum() + assert nat_count == 0 + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assignment4/assignment4.py b/assignment4/assignment4.py new file mode 100644 index 0000000..e69de29 diff --git a/assignment4/dirty_data.csv b/assignment4/dirty_data.csv new file mode 100644 index 0000000..0eb86b4 --- /dev/null +++ b/assignment4/dirty_data.csv @@ -0,0 +1,8 @@ +Name,Age,Salary,Hire Date,Department +Alice, 29,50000,2021/01/15, Sales +Bob, 32, unknown,2020-03-18,MARKETING + charlie, NaN, 70000,3/25/2019,marketinG +Dana, 41, n/a,2020/12/01, HR +Eve, 24,65000,2021/06/07, hr +Frank, 32,75000, 2019-07-11,Sales +Bob, 32, unknown,2020-03-18,MARKETING diff --git a/assignment8/.keep b/assignment8/.keep new file mode 100644 index 0000000..e69de29 diff --git a/assignment8/challenges.txt b/assignment8/challenges.txt new file mode 100644 index 0000000..d07eee1 --- /dev/null +++ b/assignment8/challenges.txt @@ -0,0 +1,12 @@ +One challenge I faced was locating the OWASP Top 10 vulnerabilities. + I first tried scraping the main OWASP project page, but it + did not contain the A01-A10 entries directly. I solved this + by inspecting the website and navigating to the OWASP Top + 10:2025 page, where the vulnerability links were listed. + +Another challenge was learning how to use Selenium, XPath, +and browser developer tools to find the correct elements. + After examining the HTML structure, I updated my script to + collect the vulnerability titles and links and save them to + a CSV file. + \ No newline at end of file diff --git a/assignment8/ethical_scraping.txt b/assignment8/ethical_scraping.txt new file mode 100644 index 0000000..aa7995e --- /dev/null +++ b/assignment8/ethical_scraping.txt @@ -0,0 +1,11 @@ +I reviewed the Durham County Library robots.txt file. + +The robots.txt file allows access to most of the website but restricts access to the /staff/ directory. It also blocks several AI-related crawlers and automated bots. + +When collecting data from a website, it is important to follow the robots.txt rules, avoid making excessive requests, and only gather publicly available information. + +Ethical web scraping helps respect website policies and reduces unnecessary load on website servers. + +I also reviewed the Wikipedia robots.txt file. Wikipedia includes different rules for different user agents and restricts some areas from automated crawling. This shows that websites can allow some crawlers while limiting others. + +Robots.txt helps website owners control automated access to their site. Following robots.txt is important because it helps avoid overloading servers and respects the website owner's rules. \ No newline at end of file diff --git a/assignment8/get_books.csv b/assignment8/get_books.csv new file mode 100644 index 0000000..37ff990 --- /dev/null +++ b/assignment8/get_books.csv @@ -0,0 +1,21 @@ +Title,Author,Format-Year +Spanish Romance Stories for Language Learning,"Rowett, Mary","eAudiobook, 2026" +Real-World Spanish: The Conversation Learning System,Camila Vega Rivera,"eAudiobook, 2025" +Learning Spanish-beginner I,"Iris Acevedo A.; Spanishonline, Costarica","eBook, 2025 — Spanish" +100 Facts About Learning Spanish,Science-Based Language Learning Lab,"eAudiobook, 2024" +A Beginner's Guide to Learning Spanish,"Miller, Jackson","eAudiobook, 2024" +No Tears Spanish Grammar: Easy Learning: Essential Rules for Beginners,"Bennett, Olivia","eBook, 2024" +100 Facts About Learning Spanish,Science-Based Language Learning Lab,"eBook, 2024" +The Ultimate Learning Spanish Blueprint - 10 Essential Steps,"Ramirez, Andres","eAudiobook, 2024" +Learning Spanish for Adults Beginner,"World, Spain","eBook, 2023" +Learning to Read in English and Spanish Made Easy,"Navarijo, Susie G.","eBook, 2022" +Spanish for Beginners: A Comprehensive Guide for Learning the Spanish Language Fast,Language Equipped Travelers,"eBook, 2021" +"Spanish: Beginner's Step by Step Course to Quickly Learning the Spanish Language, Spanish Grammar &","Michaels, Steven J.","eBook, 2021" +Learn Spanish Like a Native for Beginners - Level 1: Learning Spanish in Your Car Has Never Been Eas,Learn Like a Native,"eBook, 2021" +Learn Spanish Like a Native for Beginners - Level 2: Learning Spanish in Your Car Has Never Been Eas,Learn Like a Native,"eBook, 2021" +I'm Learning Spanish,"Gardner, James M.","eAudiobook, 2020 — Chinese" +I am learning Spanish,"Gardner, James M.","eAudiobook, 2018" +The Best Spanish Learning Games for Children,"Professor, Baby","eBook, 2017" +Easy Learning Spanish Vocabulary,"Dictionaries, Collins","eBook, 2016 — Spanish" +Spanish Easy Learning Complete Course,"Carmen García del Río; Fitzsimons, Ronan","eAudiobook, 2016" +Learning the Local Language: Your Guide to Real World Spanish,"Romey, Jared","eBook, 2013" diff --git a/assignment8/get_books.json b/assignment8/get_books.json new file mode 100644 index 0000000..aea30bb --- /dev/null +++ b/assignment8/get_books.json @@ -0,0 +1,102 @@ +[ + { + "Title": "Spanish Romance Stories for Language Learning", + "Author": "Rowett, Mary", + "Format-Year": "eAudiobook, 2026" + }, + { + "Title": "Real-World Spanish: The Conversation Learning System", + "Author": "Camila Vega Rivera", + "Format-Year": "eAudiobook, 2025" + }, + { + "Title": "Learning Spanish-beginner I", + "Author": "Iris Acevedo A.; Spanishonline, Costarica", + "Format-Year": "eBook, 2025 \u2014 Spanish" + }, + { + "Title": "100 Facts About Learning Spanish", + "Author": "Science-Based Language Learning Lab", + "Format-Year": "eAudiobook, 2024" + }, + { + "Title": "A Beginner's Guide to Learning Spanish", + "Author": "Miller, Jackson", + "Format-Year": "eAudiobook, 2024" + }, + { + "Title": "No Tears Spanish Grammar: Easy Learning: Essential Rules for Beginners", + "Author": "Bennett, Olivia", + "Format-Year": "eBook, 2024" + }, + { + "Title": "100 Facts About Learning Spanish", + "Author": "Science-Based Language Learning Lab", + "Format-Year": "eBook, 2024" + }, + { + "Title": "The Ultimate Learning Spanish Blueprint - 10 Essential Steps", + "Author": "Ramirez, Andres", + "Format-Year": "eAudiobook, 2024" + }, + { + "Title": "Learning Spanish for Adults Beginner", + "Author": "World, Spain", + "Format-Year": "eBook, 2023" + }, + { + "Title": "Learning to Read in English and Spanish Made Easy", + "Author": "Navarijo, Susie G.", + "Format-Year": "eBook, 2022" + }, + { + "Title": "Spanish for Beginners: A Comprehensive Guide for Learning the Spanish Language Fast", + "Author": "Language Equipped Travelers", + "Format-Year": "eBook, 2021" + }, + { + "Title": "Spanish: Beginner's Step by Step Course to Quickly Learning the Spanish Language, Spanish Grammar &", + "Author": "Michaels, Steven J.", + "Format-Year": "eBook, 2021" + }, + { + "Title": "Learn Spanish Like a Native for Beginners - Level 1: Learning Spanish in Your Car Has Never Been Eas", + "Author": "Learn Like a Native", + "Format-Year": "eBook, 2021" + }, + { + "Title": "Learn Spanish Like a Native for Beginners - Level 2: Learning Spanish in Your Car Has Never Been Eas", + "Author": "Learn Like a Native", + "Format-Year": "eBook, 2021" + }, + { + "Title": "I'm Learning Spanish", + "Author": "Gardner, James M.", + "Format-Year": "eAudiobook, 2020 \u2014 Chinese" + }, + { + "Title": "I am learning Spanish", + "Author": "Gardner, James M.", + "Format-Year": "eAudiobook, 2018" + }, + { + "Title": "The Best Spanish Learning Games for Children", + "Author": "Professor, Baby", + "Format-Year": "eBook, 2017" + }, + { + "Title": "Easy Learning Spanish Vocabulary", + "Author": "Dictionaries, Collins", + "Format-Year": "eBook, 2016 \u2014 Spanish" + }, + { + "Title": "Spanish Easy Learning Complete Course", + "Author": "Carmen Garc\u00eda del R\u00edo; Fitzsimons, Ronan", + "Format-Year": "eAudiobook, 2016" + }, + { + "Title": "Learning the Local Language: Your Guide to Real World Spanish", + "Author": "Romey, Jared", + "Format-Year": "eBook, 2013" + } +] \ No newline at end of file diff --git a/assignment8/get_books.py b/assignment8/get_books.py new file mode 100644 index 0000000..7ecb7b9 --- /dev/null +++ b/assignment8/get_books.py @@ -0,0 +1,82 @@ +import json +import pandas as pd + +from selenium import webdriver +from selenium.webdriver.chrome.service import Service as ChromeService +from selenium.webdriver.common.by import By +from webdriver_manager.chrome import ChromeDriverManager + + +# Task 3 + +options = webdriver.ChromeOptions() +options.add_argument("--disable-gpu") +options.add_argument("--window-size=1920,1080") + +driver = webdriver.Chrome( + service=ChromeService(ChromeDriverManager().install()), + options=options +) + + +url = "https://durhamcounty.bibliocommons.com/v2/search?query=learning%20spanish&searchType=smart" +driver.get(url) + +results = [] +results = [] + +book_cards = driver.find_elements( + By.CSS_SELECTOR, + "li" +) + +for book in book_cards: + title_elements = book.find_elements( + By.CSS_SELECTOR, + "span.title-content" + ) + + if len(title_elements) > 0: + title = title_elements[0].text + + author_elements = book.find_elements( + By.CSS_SELECTOR, + "a.author-link" + ) + + authors = [] + for author in author_elements: + authors.append(author.text) + + author_text = "; ".join(authors) + + format_elements = book.find_elements( + By.CSS_SELECTOR, + "span.display-info-primary" + ) + + format_year = "" + if len(format_elements) > 0: + format_year = format_elements[0].text + + results.append( + { + "Title": title, + "Author": author_text, + "Format-Year": format_year + } + ) + +books_df = pd.DataFrame(results) + +print(books_df) + +books_df.to_csv( + "assignment8/get_books.csv", + index=False +) + +with open("assignment8/get_books.json", "w") as file: + json.dump(results, file, indent=4) + +driver.quit() \ No newline at end of file diff --git a/assignment8/owasp_top_10.csv b/assignment8/owasp_top_10.csv new file mode 100644 index 0000000..e2069dc --- /dev/null +++ b/assignment8/owasp_top_10.csv @@ -0,0 +1,11 @@ +Title,Link +A01 Broken Access Control,https://owasp.org/Top10/2025/A01_2025-Broken_Access_Control/ +A02 Security Misconfiguration,https://owasp.org/Top10/2025/A02_2025-Security_Misconfiguration/ +A03 Software Supply Chain Failures,https://owasp.org/Top10/2025/A03_2025-Software_Supply_Chain_Failures/ +A04 Cryptographic Failures,https://owasp.org/Top10/2025/A04_2025-Cryptographic_Failures/ +A05 Injection,https://owasp.org/Top10/2025/A05_2025-Injection/ +A06 Insecure Design,https://owasp.org/Top10/2025/A06_2025-Insecure_Design/ +A07 Authentication Failures,https://owasp.org/Top10/2025/A07_2025-Authentication_Failures/ +A08 Software or Data Integrity Failures,https://owasp.org/Top10/2025/A08_2025-Software_or_Data_Integrity_Failures/ +A09 Security Logging and Alerting Failures,https://owasp.org/Top10/2025/A09_2025-Security_Logging_and_Alerting_Failures/ +A01:2025 - Broken Access Control,https://owasp.org/Top10/2025/A01_2025-Broken_Access_Control/ diff --git a/assignment8/owasp_top_10.py b/assignment8/owasp_top_10.py new file mode 100644 index 0000000..44fef69 --- /dev/null +++ b/assignment8/owasp_top_10.py @@ -0,0 +1,51 @@ +import pandas as pd + +from selenium import webdriver +from selenium.webdriver.chrome.service import Service as ChromeService +from selenium.webdriver.common.by import By +from webdriver_manager.chrome import ChromeDriverManager + +options = webdriver.ChromeOptions() +options.add_argument("--headless=new") +options.add_argument("--disable-gpu") +options.add_argument("--window-size=1920,1080") + +driver = webdriver.Chrome( + service=ChromeService(ChromeDriverManager().install()), + options=options +) + +url = "https://owasp.org/Top10/2025/" +driver.get(url) + +top_ten = [] + +links = driver.find_elements( + By.XPATH, + "//a[contains(@href, 'A0')]" +) + +for link in links: + title = link.text.strip() + href = link.get_attribute("href") + + if title and href: + top_ten.append( + { + "Title": title, + "Link": href + } + ) + +top_ten = top_ten[:10] + +print(top_ten) + +owasp_df = pd.DataFrame(top_ten) + +owasp_df.to_csv( + "assignment8/owasp_top_10.csv", + index=False +) + +driver.quit() diff --git a/assignment9/.keep b/assignment9/.keep new file mode 100644 index 0000000..e69de29 diff --git a/csv/customers.csv b/csv/customers.csv new file mode 100644 index 0000000..4ab941b --- /dev/null +++ b/csv/customers.csv @@ -0,0 +1,101 @@ +customer_id,customer_name,contact,street,city,country,postal_code,phone +1,"Short, Taylor and Brown",Andrew Woods,3104 Allen Mall,Scottton,Mauritania,91825,+82 +1-536-993-0030 +2,Glover-Hernandez,Kathleen Callahan,46716 Graves Drive,West Kimberg,Myanmar,75905,+234 447-861-4700x71251 +3,Conrad-Harris,Mark Hill,4945 Harvey Greens Suite 329,Matthewmouth,Northern Mariana Islands,23860,+262 639 691.737.9008 +4,Patterson-Smith,Russell Peterson,574 Harvey Vista Suite 020,Lake Tammyport,San Marino,75100,+373 2 001-230-218-0321x1805 +5,Mccann-Thompson,Jacob Myers,988 Brittney Walk Suite 803,New Rebecca,Albania,04586,+358 18 001-264-844-5618x991 +6,Kelly-Oconnell,Amber Harmon,5076 Pamela Estates,Lake Rachel,Malawi,59981,+39 06 698 262.613.2527 +7,"Stephens, King and Johnson",Amanda Walker,8142 Crawford Mission,Port Jonathanshire,Grenada,15468,+1 284 001-675-402-4532x8276 +8,Williams-Mack,Zachary Walker,24067 David Land,North Rickytown,Sri Lanka,23962,+420 (989)498-0714 +9,Clark-Brooks,Matthew Nguyen,852 Melton Fall,West Mariafurt,Turkey,35212,+57 (899)758-1468x885 +10,Galloway-Coleman,Sean Chang,64742 Darren Parkway,Matthewhaven,Nicaragua,71733,+216 001-669-730-9178 +11,"Mills, Torres and Graham",Matthew Rangel,521 Sampson Loop Suite 683,West Dawn,Algeria,85945,+507 366.980.7640 +12,Preston-Wright,Shawn Weber,18139 Christian Island Apt. 864,Richardfort,Senegal,29567,+211 6025619622 +13,Owens-Mclaughlin,Matthew Pierce,96172 Barbara Highway,Lisaside,Netherlands Antilles,40335,+356 (322)267-5055x817 +14,Dean Ltd,Benjamin Huber,2887 Mills Vista Apt. 076,North Lisa,Zambia,57988,+39 (306)239-8565 +15,Mills Inc,Gilbert Ramos,721 Barrett Path Apt. 626,Frankland,Libyan Arab Jamahiriya,27619,+596 +1-276-449-4908x293 +16,Perez and Sons,Margaret Gardner,279 Angie Circles,Lake Rebeccaborough,Maldives,03033,+882 16 702-415-0969x8783 +17,"Neal, Baxter and Thompson",Kristen Flynn MD,42153 Smith Plaza,Hallbury,Germany,53344,+39 9158142105 +18,Garcia-Mcgrath,John Johnson,19407 Gallagher Crossroad Suite 600,South Matthewland,Sudan,45340,+683 4684301465 +19,"Serrano, Armstrong and Taylor",Stacy Allen,494 Debra Land,Matthewborough,Guinea-Bissau,16386,+678 (234)657-2167x436 +20,Salas-Ruiz,Arthur Chavez,185 Lee Street Suite 551,Trevorfurt,Pakistan,04412,+1 664 +1-749-367-7829x2179 +21,Meyer Ltd,Lisa Patton,292 Hutchinson Court Apt. 294,Jillianfurt,Tonga,53888,+32 872.578.2697 +22,Williams-Higgins,David Robinson,6150 Jennifer Rue Apt. 594,West Peter,Nepal,17401,+888 (760)264-2789x3312 +23,"Davis, Salinas and Johnson",Maria Ali,2253 Robert Course,West Rachael,Norway,11260,+882 13 250-992-3486x06384 +24,Ross Ltd,April Lee,9927 Rangel Union,Brennanland,Pitcairn Islands,68459,+1 345 +1-990-442-2922 +25,Vasquez and Sons,Dominic Freeman,1997 Cohen Crossing Suite 001,South Daniel,New Caledonia,90989,+52 +1-460-874-7358 +26,Johnson Inc,Dennis Nielsen,346 Linda Plains Suite 250,New Julie,Tunisia,78450,+973 878-371-0298x9071 +27,Smith-Moore,Chris Kim,2952 Richardson Wells,Port Larry,Zambia,32492,+91 (359)757-9911 +28,Bryant-Hinton,Matthew Francis,81705 Jennifer Branch,Lake Robertview,Guinea-Bissau,01736,+686 370-603-2757 +29,"Reynolds, Pollard and Day",Cody Harrell,51011 Martinez Island,East Michael,Saint Helena,49122,+599 9 760-278-8510x36690 +30,"Weiss, Sanders and Clark",Alicia Doyle,82122 Keith Center,Brianashire,Afghanistan,15308,+92 001-636-335-4769 +31,"Lowe, Acevedo and Thompson",Heather Gutierrez,69013 Kelley Springs Apt. 481,Ronaldland,United Arab Emirates,23846,+590 +1-765-786-8831x539 +32,Chambers-Anderson,Victoria Ali,7284 Shane Ports Apt. 317,West Douglas,Guam,41321,+44 7924 (690)421-4096x407 +33,Delacruz-Powell,Evelyn Neal,6109 Dawn Cliff,South Cynthia,Bangladesh,59906,+256 001-786-917-7545x549 +34,Wise Group,Jeremy Holland,6905 Andrade Square,West Matthew,Austria,16337,+994 318.723.5942x03732 +35,Espinoza Inc,David Hudson,720 Amber Estate,Port Cassandraview,Sierra Leone,94780,+598 827.804.7412x684 +36,"Burke, Wilkerson and Coleman",Kim Davis MD,68999 Pierce Way Apt. 263,North Scott,Reunion,82849,+968 650-402-5555 +37,Cox-Moyer,Shannon Mccullough,007 David Avenue Suite 742,Campbellburgh,Cambodia,72332,+685 996-802-9411x841 +38,"Walsh, Costa and Oconnor",Christine Taylor,30328 Gregory Station Apt. 545,North Daniel,Spain,14265,+255 24 +1-553-492-1933x589 +39,"Ray, Shaw and Miller",Jason Rush,349 Rivera Rapid Apt. 628,Spencerland,Fiji,26741,+979 001-224-412-7788x646 +40,"Proctor, Cooley and Coleman",Melanie Woods,839 Mccormick Bridge,East John,Oman,76457,+590 (380)583-9156x7682 +41,Hogan Inc,Michael Jones,37445 Joseph Valley Suite 003,Jonmouth,Palestinian Territory,57860,+975 (948)612-0559x419 +42,"Phillips, Bush and Miller",Andrea Stevens,55310 Harris Springs,Schmidtmouth,Qatar,59359,+672 +1-261-295-9832x1971 +43,Solis Group,Tammy Walters,6393 Patricia Circles,North John,Brunei Darussalam,17162,+237 4783325433 +44,Esparza-Terry,Jason Dawson,21012 Brock Tunnel,Christinefurt,Palau,40098,+55 714-878-1327x79527 +45,"Bailey, Henderson and Bailey",Joshua Morgan,39079 Yoder Ridge,Martinezburgh,Austria,66784,+964 880.421.9411x37322 +46,Walters Inc,Eddie Olson,60648 Kaitlyn Ways,Erikfort,Bermuda,06185,+66 001-885-880-1386 +47,Johnson PLC,Glenda Gregory,09100 Greg Fields Suite 841,North Kayla,Serbia,01909,+970 490-988-7105 +48,Anderson and Sons,Abigail Riley,5846 Joseph Branch Apt. 487,Holdenchester,Saint Martin,10136,+299 669-515-9554x3928 +49,Powell Group,Shawn Cruz,27581 Lee Island,Codyberg,Ghana,49748,+223 609-203-8403 +50,"Hardy, Smith and Smith",Brian Stephens,3736 Harris Oval Apt. 027,Rileytown,Palestinian Territory,07020,+61 89164 343-410-8563x426 +51,Fox Inc,Terry Allen,2597 Antonio Locks Apt. 946,Garzaville,Central African Republic,37216,+500 438.443.9141 +52,Young-Cobb,Tammy Taylor,7877 Edwards Stravenue,New Wandachester,Luxembourg,50287,+881 1 001-574-923-7538x0257 +53,"Martin, Harris and Brooks",Jennifer Douglas,8304 Mia Court,Lake Carl,Isle of Man,98247,+290 783-894-7720 +54,Hodges and Sons,Karen Barron,6331 Cole Glen Apt. 945,Ariasfort,American Samoa,77767,+599 9 +1-808-423-4564x033 +55,Wilson Inc,Shawn Benjamin,154 Pollard Junction,Beckerfort,Ukraine,35477,+33 3632393107 +56,Saunders-Huffman,Andrea Foster,86832 Morrow Prairie,North Kelly,Somalia,75324,+234 729.843.1316x90623 +57,"Owens, Reese and Villa",Tyler Watson,267 Hart Drive Apt. 357,Brentport,Rwanda,22919,+211 5402700198 +58,Schroeder Ltd,Mike Baldwin,38983 Jason Square Suite 828,North Dustinmouth,Trinidad and Tobago,26171,+1 784 (432)493-4710x7366 +59,"Frazier, Brooks and Ramirez",Karla Church,333 Jill Alley Suite 373,West Paul,Malaysia,86114,+881 6 001-690-676-5097x1557 +60,"Barber, Warner and Moon",Jay Stone,576 Meghan Groves,Patriciaville,Burkina Faso,77025,+687 (908)791-0226x4365 +61,Conner-Cunningham,Gregory Benjamin,506 Richard Road Apt. 608,Richardsmouth,Oman,05983,+878 (889)917-8446 +62,Jordan Ltd,Jonathan Anderson,08205 Trevino Extensions,Erinshire,Mongolia,73172,+881 9 +1-378-478-0918x277 +63,Dennis Group,Craig Lee,82763 Melendez Underpass,Port Ryan,Saint Helena,31457,+359 +1-970-903-0707x31839 +64,Wall-Mcmillan,Joseph Martin,883 Jamie Forge Apt. 064,Aliciaberg,Guadeloupe,83751,+240 335.817.2866 +65,Smith-Walker,Michael White,0118 Hubbard Center,Jasonburgh,Tanzania,86309,+420 707-654-5891 +66,Graham Inc,Amber Allen,578 Alyssa Mission Suite 337,Careytown,Cuba,26775,+670 472.311.5090x63460 +67,Williams LLC,Charles Berger,59807 Nunez Ports,Evansstad,Tonga,19622,+86 553-685-4446x005 +68,"Brooks, Cox and Martin",Ariana Murphy,508 Veronica Parkway Apt. 411,Carrollshire,Ukraine,91146,+504 572.871.1204x32747 +69,Johnson-Dillon,Dawn Tanner,16284 Marcus Road Apt. 687,Hammondstad,Heard Island and McDonald Islands,09847,+90 392 410-249-4779 +70,Sullivan Ltd,Maria Massey,8808 Reyes Plains,Sullivanfurt,British Virgin Islands,30660,+64 614.901.7994x8695 +71,Collins-Cabrera,Tony Olsen,01686 Christopher Flats,Yolandafort,Chile,76327,+963 507.706.7176x72538 +72,Snyder-Ward,Vincent Nunez,33923 Hernandez Ridge Apt. 431,Brownfurt,Bulgaria,88381,+257 (935)568-2730 +73,"Ramsey, Buchanan and Berger",Lee Welch,166 Ashley Rapids Apt. 508,East Brian,Papua New Guinea,14997,+239 969-816-1425x5451 +74,"Callahan, Melendez and Brooks",Lisa Ramsey,80540 Mike Corners,Gallaghermouth,Timor-Leste,05763,+881 7 864-849-0165x383 +75,Rodriguez-Smith,Haley Jackson,13865 Leah Shoals,Daniellebury,Singapore,88899,+262 639 (656)266-9976x155 +76,Rivera Group,Danielle Small,7504 Michael Forges,Lake Scottside,Peru,10107,+66 334-271-4947x543 +77,Moss LLC,Teresa French,358 Hawkins Cape Suite 179,Port Jamesfurt,Equatorial Guinea,39282,+1 869 001-702-453-4851 +78,Miller Ltd,Christopher Harding,16779 Gaines Pines,Port Emilybury,French Polynesia,49688,+1 787 773.486.4294x4654 +79,Gill-Wu,Lauren Wallace,3979 Hernandez Dam,Maldonadoland,Seychelles,94705,+7 7 445-368-2918 +80,Russell Ltd,Adam Wells,6349 Dillon Walks,East Leroy,Netherlands,89085,+27 (511)539-8534x5085 +81,Wright-Liu,Scott Cooley,272 Jason Summit,New Josephmouth,Bolivia,32636,+44 7624 255-335-6363 +82,Johnson LLC,Roger Johnson,745 Howell Square Suite 402,West Sharonbury,Reunion,56963,+359 001-577-254-3040x65663 +83,Roach-Vance,Heather Carter,70512 Jennifer Court Apt. 111,East Ian,Denmark,31831,+500 473.526.3442x778 +84,Zimmerman-Nichols,Steven Adams,53941 Jenkins Squares Apt. 306,Jacksonville,Italy,20728,+61 5355112995 +85,Mills-Lee,Paul Butler,83012 Cameron Alley Suite 465,Alexanderberg,Mauritius,10366,+356 349.304.2204x4442 +86,Williams and Sons,Larry Wolf,567 Bryan Loop,West Douglasville,Hungary,83329,+682 (844)836-0249x3395 +87,"Morse, Gamble and Nielsen",Caleb Martinez,192 Clements Cove Suite 383,Allisonland,Benin,86961,+46 821.455.0676 +88,"Turner, Brown and Humphrey",Bryan Donaldson,46960 Kristy Point,South Richard,Heard Island and McDonald Islands,40299,+30 (336)873-3292 +89,"Jones, Perry and Simpson",Gary Leonard,2750 Smith Rapids,South Vincent,Ethiopia,24732,+222 001-448-765-4306x27651 +90,"Brown, Gutierrez and Trevino",Francisco Reid,1419 Anderson Locks Apt. 916,Charlesview,Uganda,34086,+44 1481 001-679-940-4293x148 +91,Gray and Sons,Walter Cortez,27982 Alex Groves Suite 195,South Chelsea,Belarus,21157,+881 0 +1-540-968-2323 +92,Hall LLC,David Valenzuela,617 Lin Springs,Martinezton,Faroe Islands,71641,+358 001-961-604-6400x66330 +93,"Flores, Day and Thomas",Sarah Bailey,7512 Ricardo Spur Apt. 129,West Wendy,Lesotho,53521,+690 965-950-8716 +94,Mcmahon-Russell,Susan Wilson,6027 White Shoal Apt. 389,North Heathermouth,Norway,59569,+681 6432858874 +95,Pierce LLC,Renee Hamilton,77190 Elizabeth Lights,Lake Michaelburgh,Northern Mariana Islands,74306,+881 6 (991)217-9581x447 +96,Smith Group,James Campbell,683 Alan Drive,East Davidfort,Belarus,65957,+1 264 001-984-480-8124x56878 +97,"Herrera, Griffin and Collins",Colleen Anderson,6755 Jorge Cliffs Suite 040,Robertfort,Christmas Island,81718,+689 9344130980 +98,Fisher and Sons,Brittany Hall,7226 Wells Vista,North Leonardland,Andorra,52421,+46 +1-893-925-6674x565 +99,Martinez LLC,Alexander Moore,51881 Moore Inlet,Crystalfurt,Estonia,59493,+222 (616)864-3066 +100,Pierce-Smith,Sabrina Johnson,8823 Todd Lights Suite 381,Williamsview,Venezuela,22397,+230 +1-382-617-8013x5888 diff --git a/csv/employees.csv b/csv/employees.csv new file mode 100644 index 0000000..13cb08c --- /dev/null +++ b/csv/employees.csv @@ -0,0 +1,21 @@ +employee_id,first_name,last_name,phone +1,Cindy,Wade,+222 656-486-3727 +2,David,Thornton,+882 (369)732-4858x56864 +3,Lauren,Martinez,+250 8878764159 +4,Kenneth,White,+64 4924992211 +5,James,Torres,+267 +1-471-316-0190x308 +6,Tracy,Foster,+237 6225761379 +7,Miranda,Harris,+370 001-563-522-4308x77248 +8,Destiny,Nguyen,+226 284.891.0715 +9,Phillip,Williams,+423 4943292679 +10,Kelli,Bowman,+379 (843)240-1818x77648 +11,Gregory,Pittman,+264 9864625899 +12,Natasha,Hoover,+234 649.763.1540x547 +13,Gregory,Jackson,+243 (871)628-0556 +14,David,Clark,+882 805-740-2877x32513 +15,Sarah,Shepherd,+267 721-710-7210x8468 +16,Michael,Quinn,+972 826.201.6869 +17,Logan,Lopez,+64 +1-264-270-6434 +18,Donald,Hunt,+47 79 (579)967-8837x893 +19,Matthew,Meyers,+378 +1-720-722-2062x240 +20,Thomas,Calderon,+64 +1-380-200-3211 diff --git a/csv/line_items.csv b/csv/line_items.csv new file mode 100644 index 0000000..e1f1d68 --- /dev/null +++ b/csv/line_items.csv @@ -0,0 +1,1110 @@ +line_item_id,order_id,product_id,quantity +1,1,45,6 +2,1,49,20 +3,1,51,11 +4,1,54,17 +5,1,51,7 +6,1,6,2 +7,2,41,6 +8,2,37,5 +9,3,24,16 +10,3,26,18 +11,3,51,5 +12,4,39,18 +13,4,52,20 +14,4,34,16 +15,4,26,6 +16,4,34,14 +17,4,45,19 +18,4,29,14 +19,5,4,14 +20,5,24,9 +21,5,13,1 +22,5,58,11 +23,6,47,11 +24,6,14,7 +25,6,6,9 +26,6,54,15 +27,6,9,12 +28,6,35,14 +29,6,6,6 +30,7,1,18 +31,7,51,1 +32,7,35,1 +33,7,45,3 +34,8,2,5 +35,8,15,5 +36,8,9,16 +37,8,1,7 +38,8,36,7 +39,8,2,16 +40,8,15,19 +41,8,4,12 +42,9,36,14 +43,9,45,14 +44,9,44,16 +45,9,21,13 +46,9,2,9 +47,10,20,12 +48,10,33,8 +49,10,38,19 +50,10,12,1 +51,10,58,16 +52,10,34,19 +53,10,14,5 +54,11,49,19 +55,11,15,11 +56,11,47,16 +57,11,57,11 +58,11,5,5 +59,11,2,14 +60,11,6,18 +61,12,55,18 +62,12,15,10 +63,13,26,9 +64,13,2,1 +65,13,52,4 +66,14,19,5 +67,15,50,20 +68,15,35,17 +69,15,12,5 +70,15,40,13 +71,16,15,14 +72,16,25,10 +73,16,43,7 +74,16,7,7 +75,16,51,3 +76,16,36,3 +77,17,2,17 +78,18,59,15 +79,18,28,12 +80,18,40,4 +81,18,43,20 +82,19,41,13 +83,19,35,5 +84,19,50,16 +85,19,1,1 +86,19,29,5 +87,19,43,3 +88,19,36,11 +89,19,49,18 +90,20,14,5 +91,20,13,7 +92,20,24,10 +93,20,5,6 +94,21,38,14 +95,21,20,5 +96,21,36,5 +97,21,17,14 +98,21,31,17 +99,21,19,7 +100,22,14,14 +101,22,4,9 +102,22,11,13 +103,22,12,11 +104,22,35,16 +105,22,48,9 +106,23,22,8 +107,23,26,14 +108,23,30,1 +109,23,59,4 +110,23,34,8 +111,23,44,7 +112,24,28,1 +113,24,4,14 +114,24,24,3 +115,24,10,4 +116,24,51,10 +117,25,10,4 +118,25,20,14 +119,26,3,2 +120,26,27,18 +121,26,11,8 +122,26,59,3 +123,27,42,15 +124,27,2,19 +125,27,9,14 +126,27,27,16 +127,27,26,14 +128,27,29,16 +129,27,6,5 +130,27,15,16 +131,28,12,10 +132,28,45,20 +133,28,11,17 +134,29,47,14 +135,29,3,14 +136,29,36,5 +137,29,42,10 +138,29,28,10 +139,29,42,15 +140,29,53,19 +141,30,2,11 +142,30,1,17 +143,31,2,14 +144,31,4,13 +145,31,34,16 +146,31,36,9 +147,31,20,6 +148,31,54,2 +149,31,44,13 +150,31,2,17 +151,32,53,7 +152,32,46,3 +153,32,47,3 +154,32,1,1 +155,32,26,1 +156,32,15,15 +157,32,54,20 +158,33,8,14 +159,34,6,2 +160,34,25,5 +161,34,1,11 +162,34,29,3 +163,34,56,7 +164,34,59,16 +165,34,54,8 +166,35,38,20 +167,35,53,19 +168,35,41,12 +169,35,26,19 +170,36,26,20 +171,37,36,12 +172,38,23,5 +173,38,10,10 +174,38,54,4 +175,38,44,2 +176,38,4,13 +177,38,10,13 +178,38,23,1 +179,38,57,11 +180,39,22,19 +181,40,22,10 +182,40,53,20 +183,41,43,14 +184,41,10,19 +185,41,12,20 +186,41,1,2 +187,41,31,10 +188,41,57,2 +189,42,40,8 +190,42,51,5 +191,42,49,12 +192,42,45,19 +193,43,15,12 +194,43,31,9 +195,43,22,13 +196,43,7,7 +197,43,27,6 +198,44,24,11 +199,44,20,6 +200,44,46,17 +201,44,15,9 +202,44,1,11 +203,45,41,10 +204,46,40,9 +205,46,4,5 +206,47,43,6 +207,47,59,18 +208,47,25,4 +209,47,56,18 +210,47,57,13 +211,47,47,20 +212,47,38,15 +213,48,23,19 +214,48,20,16 +215,48,3,20 +216,48,42,16 +217,48,4,7 +218,48,60,1 +219,49,57,14 +220,49,49,17 +221,49,39,6 +222,50,16,10 +223,50,51,2 +224,50,48,7 +225,50,49,20 +226,50,6,3 +227,50,37,18 +228,50,20,9 +229,51,10,12 +230,51,45,18 +231,52,7,16 +232,53,43,9 +233,53,36,16 +234,53,40,15 +235,54,48,16 +236,54,50,8 +237,55,27,11 +238,55,34,20 +239,55,15,16 +240,55,54,5 +241,55,31,11 +242,55,17,6 +243,56,53,5 +244,56,17,11 +245,56,3,12 +246,56,20,17 +247,56,6,13 +248,56,37,19 +249,57,13,14 +250,57,2,1 +251,57,57,8 +252,57,46,13 +253,58,25,10 +254,58,31,3 +255,58,7,18 +256,58,52,5 +257,58,20,5 +258,58,38,19 +259,58,48,18 +260,59,19,9 +261,59,47,20 +262,59,13,4 +263,59,21,20 +264,59,60,9 +265,59,2,2 +266,59,9,8 +267,59,45,17 +268,60,3,12 +269,60,32,3 +270,60,27,7 +271,60,60,1 +272,60,56,12 +273,60,1,5 +274,60,47,12 +275,60,54,2 +276,61,40,1 +277,61,20,9 +278,62,45,10 +279,62,31,7 +280,62,6,2 +281,62,3,1 +282,62,54,12 +283,62,60,19 +284,62,22,4 +285,63,11,18 +286,63,55,1 +287,63,42,10 +288,63,35,8 +289,63,29,12 +290,63,42,9 +291,64,54,9 +292,65,20,2 +293,65,7,20 +294,66,32,3 +295,66,14,14 +296,66,29,7 +297,66,52,13 +298,66,36,15 +299,66,54,20 +300,66,15,7 +301,67,38,15 +302,67,37,11 +303,67,3,9 +304,67,54,14 +305,67,23,20 +306,67,9,17 +307,67,49,20 +308,67,31,4 +309,68,18,18 +310,68,43,11 +311,68,36,6 +312,68,43,14 +313,68,34,20 +314,68,19,20 +315,69,49,18 +316,69,32,13 +317,69,34,10 +318,69,31,4 +319,69,32,18 +320,70,43,1 +321,71,51,17 +322,71,59,11 +323,71,20,18 +324,71,60,10 +325,71,21,10 +326,71,21,6 +327,71,3,1 +328,71,5,9 +329,72,10,1 +330,72,32,3 +331,72,5,20 +332,72,25,11 +333,72,31,11 +334,72,44,19 +335,72,4,11 +336,72,54,2 +337,73,5,1 +338,73,15,11 +339,73,5,17 +340,73,10,12 +341,74,44,8 +342,74,9,10 +343,74,13,12 +344,74,13,3 +345,74,1,19 +346,74,52,15 +347,74,34,5 +348,75,30,19 +349,75,34,12 +350,75,48,20 +351,76,46,10 +352,77,59,15 +353,77,26,17 +354,77,46,8 +355,77,30,9 +356,77,12,12 +357,77,9,15 +358,77,34,5 +359,78,50,9 +360,78,24,5 +361,79,53,15 +362,79,34,13 +363,79,33,7 +364,79,46,14 +365,79,49,12 +366,79,55,6 +367,80,16,15 +368,80,44,16 +369,80,54,14 +370,80,27,8 +371,80,45,16 +372,81,7,7 +373,81,40,18 +374,82,10,17 +375,82,37,13 +376,82,36,20 +377,82,23,7 +378,82,20,6 +379,82,29,10 +380,82,39,2 +381,82,12,19 +382,83,56,5 +383,83,50,17 +384,83,24,13 +385,83,9,11 +386,83,22,12 +387,83,5,13 +388,84,21,11 +389,84,12,6 +390,85,9,18 +391,85,40,12 +392,85,52,14 +393,85,32,15 +394,86,40,5 +395,86,53,1 +396,86,27,1 +397,86,21,3 +398,86,3,2 +399,86,35,11 +400,87,32,3 +401,88,49,19 +402,88,60,19 +403,88,27,14 +404,88,18,1 +405,88,57,1 +406,88,27,20 +407,88,59,9 +408,89,26,11 +409,89,15,4 +410,90,57,8 +411,90,28,5 +412,90,54,20 +413,90,49,11 +414,90,32,20 +415,90,32,12 +416,90,44,7 +417,90,50,18 +418,91,17,19 +419,91,6,2 +420,91,37,19 +421,91,21,6 +422,92,41,10 +423,92,36,12 +424,92,47,6 +425,93,15,8 +426,93,30,13 +427,93,29,12 +428,93,59,3 +429,93,13,11 +430,93,33,13 +431,94,18,6 +432,95,37,17 +433,96,55,17 +434,96,18,17 +435,96,34,1 +436,96,20,1 +437,97,37,7 +438,97,37,17 +439,97,21,5 +440,98,37,4 +441,99,51,17 +442,100,12,19 +443,101,10,18 +444,101,4,6 +445,102,11,3 +446,102,41,5 +447,102,22,9 +448,102,20,18 +449,102,13,9 +450,102,2,8 +451,102,4,7 +452,103,29,12 +453,103,1,4 +454,104,26,14 +455,104,10,14 +456,105,53,9 +457,105,24,11 +458,105,14,6 +459,105,51,20 +460,106,53,8 +461,106,33,4 +462,106,56,17 +463,106,56,4 +464,106,40,9 +465,106,31,10 +466,106,30,1 +467,106,36,20 +468,107,11,16 +469,107,5,16 +470,107,44,20 +471,107,8,13 +472,107,42,2 +473,107,39,20 +474,108,7,17 +475,109,17,20 +476,109,34,14 +477,109,30,16 +478,109,24,16 +479,109,30,14 +480,109,40,11 +481,110,29,19 +482,110,40,3 +483,111,14,5 +484,111,30,4 +485,111,3,17 +486,111,16,2 +487,111,29,3 +488,111,28,6 +489,111,15,7 +490,112,20,12 +491,112,40,8 +492,112,6,10 +493,112,16,1 +494,112,5,17 +495,112,7,7 +496,112,60,17 +497,113,35,18 +498,113,55,3 +499,113,60,9 +500,113,13,15 +501,113,30,1 +502,113,9,16 +503,113,36,13 +504,114,33,5 +505,114,29,11 +506,114,42,15 +507,115,5,6 +508,115,60,1 +509,115,8,10 +510,115,24,2 +511,115,18,3 +512,115,22,11 +513,115,24,5 +514,116,5,1 +515,116,22,12 +516,116,51,8 +517,116,54,14 +518,117,41,17 +519,117,4,12 +520,117,39,16 +521,117,47,6 +522,118,53,2 +523,118,52,2 +524,118,10,2 +525,118,27,12 +526,118,7,14 +527,118,11,6 +528,118,58,20 +529,119,58,10 +530,119,56,16 +531,119,19,17 +532,119,11,13 +533,119,28,6 +534,119,8,10 +535,120,28,16 +536,120,15,8 +537,120,33,5 +538,120,26,7 +539,120,21,14 +540,121,6,8 +541,121,9,1 +542,122,35,18 +543,122,3,7 +544,122,48,14 +545,123,22,13 +546,123,10,7 +547,123,29,11 +548,124,25,1 +549,124,22,9 +550,124,7,8 +551,124,10,4 +552,124,52,15 +553,125,53,20 +554,125,58,14 +555,125,4,13 +556,125,46,11 +557,125,17,2 +558,126,25,13 +559,126,11,14 +560,126,56,16 +561,126,50,20 +562,126,17,14 +563,127,38,9 +564,127,31,12 +565,127,46,3 +566,127,11,11 +567,128,47,15 +568,128,42,19 +569,128,25,13 +570,128,25,17 +571,128,36,2 +572,128,55,18 +573,128,16,15 +574,129,37,5 +575,129,25,3 +576,129,56,16 +577,129,60,19 +578,129,55,18 +579,129,26,14 +580,129,1,20 +581,129,11,11 +582,130,8,8 +583,130,44,20 +584,130,2,14 +585,131,34,5 +586,131,43,1 +587,131,27,9 +588,132,37,1 +589,132,39,7 +590,132,10,20 +591,133,48,16 +592,133,15,10 +593,133,2,13 +594,133,57,13 +595,134,40,4 +596,134,2,19 +597,135,5,13 +598,135,48,19 +599,135,53,14 +600,135,2,14 +601,135,31,7 +602,135,11,10 +603,135,13,16 +604,135,49,15 +605,136,32,11 +606,137,22,5 +607,137,9,14 +608,137,60,17 +609,137,15,9 +610,137,27,15 +611,137,58,15 +612,137,27,7 +613,137,6,2 +614,138,3,16 +615,138,2,15 +616,138,9,10 +617,139,57,15 +618,139,26,16 +619,139,41,15 +620,139,18,11 +621,139,44,9 +622,140,49,1 +623,140,32,19 +624,140,18,13 +625,140,24,17 +626,141,52,3 +627,141,11,15 +628,141,53,11 +629,142,38,16 +630,142,17,9 +631,142,46,12 +632,142,25,8 +633,142,56,8 +634,142,22,8 +635,142,24,6 +636,143,55,17 +637,144,6,16 +638,145,41,2 +639,145,32,15 +640,145,23,17 +641,145,21,14 +642,145,29,11 +643,145,11,20 +644,145,9,11 +645,146,23,4 +646,146,52,13 +647,146,32,4 +648,146,55,9 +649,146,19,19 +650,147,21,10 +651,147,40,15 +652,147,10,2 +653,148,1,10 +654,148,21,11 +655,149,41,6 +656,150,32,13 +657,150,33,10 +658,150,57,12 +659,150,3,11 +660,150,8,20 +661,150,1,13 +662,150,28,13 +663,150,57,19 +664,151,53,14 +665,151,58,14 +666,151,48,14 +667,152,44,19 +668,152,12,3 +669,152,48,6 +670,152,55,17 +671,152,15,5 +672,153,15,6 +673,153,13,12 +674,153,44,4 +675,153,15,6 +676,154,25,18 +677,154,60,9 +678,154,31,15 +679,154,45,12 +680,154,52,19 +681,154,20,18 +682,154,41,18 +683,155,6,9 +684,155,41,10 +685,155,25,9 +686,155,17,4 +687,155,16,12 +688,155,52,11 +689,155,6,19 +690,155,51,1 +691,156,18,4 +692,156,29,7 +693,156,2,18 +694,156,30,1 +695,156,53,20 +696,156,48,8 +697,157,6,10 +698,157,13,16 +699,157,50,7 +700,157,3,5 +701,157,33,17 +702,157,37,6 +703,158,52,15 +704,158,38,5 +705,158,24,15 +706,159,47,14 +707,159,51,9 +708,160,20,18 +709,160,4,4 +710,160,11,4 +711,160,54,20 +712,160,15,11 +713,160,19,13 +714,160,17,11 +715,161,17,14 +716,162,5,14 +717,162,4,13 +718,162,41,5 +719,162,55,18 +720,162,58,18 +721,163,50,15 +722,163,3,5 +723,163,17,1 +724,163,55,19 +725,163,3,20 +726,163,52,5 +727,163,45,4 +728,163,19,6 +729,164,13,17 +730,165,55,4 +731,165,58,8 +732,165,3,7 +733,166,22,3 +734,166,31,6 +735,166,30,10 +736,166,10,18 +737,166,45,2 +738,166,56,14 +739,166,51,7 +740,167,42,3 +741,167,57,3 +742,167,40,9 +743,168,9,19 +744,168,19,4 +745,168,50,11 +746,168,15,11 +747,168,9,11 +748,169,48,11 +749,169,60,1 +750,170,6,11 +751,170,19,16 +752,170,39,11 +753,170,31,9 +754,170,56,3 +755,170,26,17 +756,171,3,19 +757,171,24,4 +758,171,57,12 +759,171,13,2 +760,171,31,16 +761,171,11,15 +762,171,24,12 +763,171,49,15 +764,172,8,11 +765,172,36,17 +766,172,37,8 +767,172,9,11 +768,173,22,10 +769,173,23,19 +770,173,14,15 +771,173,4,13 +772,173,46,13 +773,173,14,16 +774,173,52,20 +775,173,31,10 +776,174,32,1 +777,175,12,20 +778,176,39,11 +779,176,31,14 +780,176,18,8 +781,177,40,9 +782,178,24,8 +783,178,37,7 +784,178,60,17 +785,179,20,17 +786,179,48,11 +787,180,29,18 +788,180,27,13 +789,180,4,15 +790,181,10,5 +791,181,10,6 +792,181,58,5 +793,181,1,17 +794,181,51,11 +795,181,19,8 +796,181,17,1 +797,181,13,11 +798,182,45,7 +799,182,7,20 +800,182,6,12 +801,182,34,18 +802,182,38,14 +803,182,19,15 +804,182,17,14 +805,182,56,18 +806,183,10,4 +807,183,26,15 +808,183,27,1 +809,183,12,9 +810,184,1,3 +811,184,35,13 +812,184,52,19 +813,184,25,16 +814,184,32,20 +815,184,39,19 +816,184,42,8 +817,184,21,7 +818,185,46,2 +819,185,58,18 +820,185,45,5 +821,185,49,13 +822,185,11,6 +823,185,44,8 +824,186,58,1 +825,186,9,3 +826,187,11,14 +827,187,42,2 +828,187,27,3 +829,187,57,11 +830,187,43,8 +831,187,14,18 +832,187,37,19 +833,188,18,5 +834,188,5,16 +835,188,55,3 +836,188,9,14 +837,189,40,12 +838,190,40,8 +839,190,45,3 +840,190,11,17 +841,190,51,14 +842,190,53,14 +843,190,39,16 +844,191,59,15 +845,191,35,18 +846,192,12,6 +847,193,52,11 +848,193,7,14 +849,193,58,5 +850,193,43,6 +851,193,12,19 +852,193,20,9 +853,194,21,12 +854,194,38,4 +855,194,37,9 +856,194,57,3 +857,195,59,20 +858,195,33,16 +859,196,19,7 +860,196,4,17 +861,196,39,4 +862,196,46,14 +863,196,10,7 +864,196,26,9 +865,197,52,7 +866,197,9,15 +867,197,28,12 +868,197,6,14 +869,197,11,6 +870,197,10,20 +871,197,6,20 +872,198,18,3 +873,198,43,13 +874,198,26,16 +875,198,25,4 +876,198,12,1 +877,198,1,9 +878,199,38,1 +879,199,42,12 +880,199,55,9 +881,200,1,13 +882,200,50,7 +883,200,40,20 +884,200,1,20 +885,200,14,3 +886,201,44,12 +887,201,12,9 +888,201,26,2 +889,202,24,15 +890,202,25,3 +891,202,32,5 +892,202,59,8 +893,202,33,14 +894,203,54,16 +895,203,14,15 +896,203,44,18 +897,203,29,11 +898,203,51,19 +899,203,44,15 +900,203,19,6 +901,203,52,12 +902,204,37,19 +903,204,2,10 +904,204,13,6 +905,204,57,7 +906,204,58,13 +907,204,26,6 +908,205,6,11 +909,205,30,13 +910,206,14,13 +911,206,28,2 +912,206,38,2 +913,206,45,3 +914,206,36,16 +915,207,29,17 +916,207,16,20 +917,207,10,13 +918,207,53,10 +919,208,2,18 +920,208,60,14 +921,208,39,7 +922,208,54,20 +923,208,12,15 +924,208,5,8 +925,208,14,13 +926,208,16,20 +927,209,7,10 +928,210,17,19 +929,210,25,15 +930,210,14,14 +931,210,50,19 +932,210,26,20 +933,210,8,1 +934,210,25,19 +935,211,53,1 +936,211,50,16 +937,211,5,20 +938,212,15,3 +939,212,49,16 +940,212,4,6 +941,213,13,11 +942,213,2,6 +943,213,55,9 +944,213,37,13 +945,213,55,7 +946,213,35,11 +947,214,8,6 +948,214,29,18 +949,215,11,15 +950,215,7,18 +951,215,38,5 +952,215,43,20 +953,215,21,7 +954,215,35,11 +955,215,21,17 +956,215,55,15 +957,216,23,10 +958,216,28,12 +959,217,54,19 +960,217,12,16 +961,217,18,9 +962,217,15,11 +963,217,10,15 +964,217,30,8 +965,218,10,20 +966,219,31,3 +967,219,13,10 +968,219,50,15 +969,219,19,8 +970,220,24,2 +971,220,26,16 +972,220,9,5 +973,220,15,13 +974,221,39,19 +975,221,58,10 +976,221,37,17 +977,221,1,6 +978,221,38,3 +979,222,27,9 +980,222,19,19 +981,222,9,4 +982,222,5,7 +983,222,10,11 +984,222,53,20 +985,223,10,4 +986,223,7,5 +987,223,6,12 +988,223,7,18 +989,223,15,16 +990,223,3,2 +991,224,23,13 +992,224,48,12 +993,224,57,1 +994,225,31,7 +995,226,17,7 +996,226,14,4 +997,226,23,20 +998,226,57,1 +999,226,17,3 +1000,226,4,20 +1001,226,60,11 +1002,227,20,13 +1003,227,11,1 +1004,227,5,3 +1005,228,8,7 +1006,228,26,11 +1007,228,48,9 +1008,228,59,12 +1009,228,21,20 +1010,229,25,8 +1011,229,24,15 +1012,229,22,9 +1013,229,34,6 +1014,229,2,9 +1015,229,59,15 +1016,229,28,16 +1017,230,17,10 +1018,230,16,2 +1019,230,31,5 +1020,230,31,19 +1021,231,58,12 +1022,231,53,15 +1023,231,5,17 +1024,231,2,19 +1025,231,38,7 +1026,231,45,13 +1027,232,8,13 +1028,232,45,1 +1029,232,38,13 +1030,232,20,19 +1031,232,15,20 +1032,233,44,11 +1033,233,50,15 +1034,233,29,4 +1035,233,60,9 +1036,233,56,4 +1037,233,10,17 +1038,234,30,18 +1039,234,2,19 +1040,234,16,19 +1041,234,41,2 +1042,234,32,20 +1043,234,48,1 +1044,235,31,4 +1045,235,13,18 +1046,235,14,18 +1047,235,40,2 +1048,235,19,14 +1049,236,11,13 +1050,236,36,11 +1051,236,32,7 +1052,236,42,12 +1053,236,34,20 +1054,236,56,1 +1055,236,22,2 +1056,236,56,7 +1057,237,26,3 +1058,237,25,10 +1059,238,2,10 +1060,238,50,14 +1061,238,36,2 +1062,238,55,18 +1063,238,47,4 +1064,238,14,4 +1065,239,10,11 +1066,239,46,9 +1067,239,43,12 +1068,239,38,8 +1069,239,18,12 +1070,239,7,20 +1071,239,45,10 +1072,239,6,16 +1073,240,17,1 +1074,240,50,5 +1075,240,29,18 +1076,240,49,6 +1077,240,37,12 +1078,240,21,10 +1079,240,36,8 +1080,241,12,9 +1081,241,45,4 +1082,241,1,18 +1083,241,47,17 +1084,242,58,5 +1085,242,8,15 +1086,242,6,9 +1087,243,2,19 +1088,243,15,18 +1089,243,53,12 +1090,243,10,20 +1091,243,34,6 +1092,243,50,11 +1093,244,35,6 +1094,244,45,14 +1095,244,57,4 +1096,244,54,1 +1097,244,16,3 +1098,244,4,5 +1099,245,16,4 +1100,246,46,18 +1101,246,7,3 +1102,246,15,16 +1103,246,23,3 +1104,246,5,6 +1105,247,35,18 +1106,247,14,14 +1107,248,2,6 +1108,249,6,19 +1109,249,46,1 diff --git a/csv/minutes1.csv b/csv/minutes1.csv new file mode 100644 index 0000000..e9fd8d9 --- /dev/null +++ b/csv/minutes1.csv @@ -0,0 +1,31 @@ +Name,Date +Gina Maldonado,"October 31, 1992" +Tony Henderson,"November 15, 1991" +Jonathan Parrish,"June 12, 1984" +Jonathan Parrish,"June 12, 1984" +Mrs. Samantha Johnson,"July 20, 1984" +Mrs. Samantha Johnson,"July 20, 1984" +Joseph Harris,"March 3, 1982" +Aaron Kaufman,"November 14, 1989" +Tony Henderson,"November 7, 1988" +Tony Henderson,"November 7, 1988" +Tony Henderson,"November 7, 1988" +Mrs. Samantha Johnson,"July 23, 1991" +Kimberly Stewart,"December 12, 1987" +Daniel Jackson,"October 2, 1981" +Daniel Jackson,"October 2, 1981" +Joseph Harris,"April 3, 1991" +Joseph Harris,"April 3, 1991" +Mrs. Samantha Johnson,"December 23, 1982" +Mrs. Samantha Johnson,"December 12, 1992" +Tony Henderson,"October 4, 1990" +Yesenia Smith,"August 10, 1983" +Yesenia Smith,"August 10, 1983" +Joseph Harris,"March 1, 1989" +Amanda Brown,"August 8, 1984" +Aaron Kaufman,"October 24, 1988" +Aaron Kaufman,"July 21, 1990" +Gina Maldonado,"April 7, 1989" +Austin Hester,"December 10, 1992" +Austin Hester,"December 10, 1992" +Daniel Jackson,"December 13, 1986" diff --git a/csv/minutes2.csv b/csv/minutes2.csv new file mode 100644 index 0000000..8169be7 --- /dev/null +++ b/csv/minutes2.csv @@ -0,0 +1,31 @@ +Name,Date +Austin Hester,"March 8, 1981" +Mrs. Samantha Johnson,"July 10, 1988" +Sarah Murray,"November 19, 1988" +Sarah Murray,"November 19, 1988" +Sarah Murray,"June 27, 1992" +Gina Maldonado,"February 13, 1987" +Yesenia Smith,"November 23, 1990" +Austin Hester,"January 18, 1989" +Jason Tucker,"April 30, 1991" +Daniel Jackson,"April 8, 1990" +Sarah Murray,"October 30, 1984" +Mrs. Samantha Johnson,"November 28, 1984" +Mrs. Samantha Johnson,"November 28, 1984" +Jason Tucker,"September 20, 1980" +Lori Martin,"July 8, 1991" +Gina Maldonado,"December 16, 1982" +Mrs. Samantha Johnson,"December 17, 1981" +Gina Maldonado,"February 9, 1992" +Lori Martin,"February 5, 1984" +Austin Hester,"June 4, 1985" +Aaron Kaufman,"May 1, 1990" +Yesenia Smith,"May 6, 1986" +Yesenia Smith,"May 6, 1986" +Mrs. Samantha Johnson,"March 12, 1982" +Sarah Murray,"August 16, 1988" +Matthew Russell,"May 31, 1991" +Matthew Russell,"May 31, 1991" +Jonathan Parrish,"March 18, 1986" +Jonathan Parrish,"March 18, 1986" +Jonathan Parrish,"March 18, 1986" diff --git a/csv/orders.csv b/csv/orders.csv new file mode 100644 index 0000000..c42c629 --- /dev/null +++ b/csv/orders.csv @@ -0,0 +1,250 @@ +order_id,date,customer_id,employee_id +1,1970-06-10,45,11 +2,1970-06-28,7,2 +3,1970-10-28,34,5 +4,1970-11-03,36,20 +5,1971-03-14,27,14 +6,1971-07-28,27,14 +7,1971-08-04,71,5 +8,1971-10-21,73,11 +9,1971-12-28,96,16 +10,1972-04-04,45,16 +11,1972-06-23,51,13 +12,1972-07-17,81,19 +13,1973-01-21,95,17 +14,1973-02-14,72,10 +15,1973-12-09,55,17 +16,1973-12-14,58,8 +17,1974-01-08,66,7 +18,1974-03-18,31,18 +19,1974-03-25,70,19 +20,1974-05-25,72,12 +21,1974-06-25,93,1 +22,1974-08-24,81,2 +23,1974-09-21,86,11 +24,1975-01-12,16,16 +25,1975-02-05,43,8 +26,1975-02-09,30,7 +27,1975-02-18,41,19 +28,1975-03-24,48,13 +29,1975-04-07,85,14 +30,1975-06-20,32,1 +31,1975-07-10,39,15 +32,1976-04-03,63,12 +33,1976-10-01,56,3 +34,1977-06-19,46,17 +35,1977-08-18,49,8 +36,1978-04-22,36,19 +37,1978-05-11,62,18 +38,1978-05-31,94,17 +39,1979-02-20,48,16 +40,1979-09-07,97,1 +41,1979-10-02,100,11 +42,1979-11-27,79,18 +43,1979-12-01,13,1 +44,1980-04-01,9,1 +45,1980-04-03,45,1 +46,1980-06-01,47,10 +47,1980-07-18,97,9 +48,1980-08-01,76,17 +49,1980-09-05,25,7 +50,1980-11-26,32,3 +51,1981-02-25,15,16 +52,1981-04-18,69,9 +53,1981-04-18,64,14 +54,1981-05-16,8,3 +55,1981-06-27,62,4 +56,1981-08-18,38,19 +57,1981-12-13,35,15 +58,1982-01-01,65,9 +59,1982-01-03,87,15 +60,1982-07-23,13,19 +61,1982-07-24,29,5 +62,1982-09-04,39,5 +63,1983-05-22,2,17 +64,1983-06-14,92,11 +65,1983-10-27,18,6 +66,1984-04-24,19,15 +67,1984-07-15,50,2 +68,1984-12-05,68,13 +69,1986-04-05,45,10 +70,1986-06-03,34,3 +71,1986-06-06,11,13 +72,1986-06-27,23,19 +73,1986-11-14,16,10 +74,1986-12-25,74,9 +75,1987-01-03,21,2 +76,1987-01-22,34,4 +77,1987-02-23,85,19 +78,1987-03-28,48,6 +79,1987-06-18,46,6 +80,1987-11-02,89,13 +81,1988-09-11,100,6 +82,1988-12-26,10,20 +83,1989-10-21,49,5 +84,1990-04-30,19,1 +85,1990-07-08,92,18 +86,1990-08-07,61,19 +87,1990-12-13,51,19 +88,1991-08-09,47,7 +89,1991-08-23,38,8 +90,1992-04-10,77,20 +91,1992-04-28,42,9 +92,1992-10-16,67,11 +93,1992-12-19,25,12 +94,1992-12-23,27,10 +95,1993-01-15,62,5 +96,1993-03-13,54,6 +97,1993-04-14,32,9 +98,1993-04-18,19,9 +99,1993-07-24,3,16 +100,1993-09-23,16,19 +101,1994-07-17,13,10 +102,1994-08-10,44,14 +103,1995-02-22,72,12 +104,1995-02-24,62,7 +105,1995-06-07,44,14 +106,1995-10-03,22,3 +107,1996-03-08,64,11 +108,1996-05-11,81,18 +109,1996-06-01,1,17 +110,1996-10-29,40,7 +111,1997-03-22,52,16 +112,1997-04-04,69,11 +113,1997-10-05,41,17 +114,1997-11-26,40,7 +115,1998-01-09,71,17 +116,1998-05-02,16,17 +117,1998-09-27,34,17 +118,1998-10-12,19,18 +119,1999-03-08,87,9 +120,1999-04-08,6,1 +121,1999-06-16,76,6 +122,1999-06-24,65,20 +123,1999-07-30,48,4 +124,2000-02-25,31,17 +125,2000-06-30,83,9 +126,2001-01-14,55,14 +127,2001-01-18,98,6 +128,2001-03-11,74,5 +129,2001-04-21,86,3 +130,2001-06-12,53,3 +131,2001-06-16,10,1 +132,2001-07-03,32,1 +133,2001-08-12,15,5 +134,2001-10-02,78,8 +135,2001-12-16,76,16 +136,2002-05-02,55,6 +137,2002-09-09,15,3 +138,2003-08-21,64,10 +139,2003-11-28,66,16 +140,2003-12-28,75,3 +141,2004-02-21,46,3 +142,2004-02-23,82,10 +143,2004-08-31,24,20 +144,2004-10-26,43,11 +145,2004-12-30,37,6 +146,2005-06-05,19,14 +147,2005-07-17,5,5 +148,2005-09-11,87,2 +149,2005-09-27,34,11 +150,2006-02-04,80,17 +151,2006-03-11,53,8 +152,2006-07-28,56,5 +153,2006-08-25,41,12 +154,2006-10-18,68,20 +155,2007-01-16,18,4 +156,2007-01-28,63,9 +157,2007-02-22,38,19 +158,2007-03-04,10,8 +159,2007-04-10,53,13 +160,2007-05-15,72,10 +161,2007-06-12,17,10 +162,2007-08-01,66,3 +163,2007-09-19,96,11 +164,2007-12-12,55,10 +165,2008-02-02,58,20 +166,2008-02-12,14,18 +167,2008-05-24,40,6 +168,2008-12-09,93,2 +169,2009-01-14,86,3 +170,2009-02-23,39,15 +171,2009-04-16,47,3 +172,2009-05-19,45,3 +173,2009-07-28,83,7 +174,2010-06-04,40,20 +175,2010-06-23,20,19 +176,2010-09-07,11,12 +177,2010-10-24,51,6 +178,2010-11-07,44,7 +179,2011-01-10,66,1 +180,2011-01-11,53,6 +181,2011-04-18,79,19 +182,2011-04-29,63,15 +183,2011-05-09,17,19 +184,2011-06-04,55,8 +185,2011-08-02,14,5 +186,2011-11-05,8,11 +187,2012-02-24,51,15 +188,2012-03-18,13,12 +189,2012-03-24,59,9 +190,2012-06-10,86,19 +191,2012-10-12,12,4 +192,2013-05-15,31,2 +193,2013-07-24,28,17 +194,2013-08-13,49,11 +195,2014-03-11,56,16 +196,2014-05-31,5,4 +197,2014-09-17,27,15 +198,2014-10-23,45,2 +199,2015-01-21,98,6 +200,2015-05-03,8,13 +201,2015-07-23,59,1 +202,2015-09-09,48,2 +203,2015-11-16,90,11 +204,2016-01-23,51,8 +205,2016-04-15,64,17 +206,2017-01-08,38,19 +207,2017-05-20,11,2 +208,2017-05-30,89,18 +209,2017-08-14,97,20 +210,2017-11-25,14,13 +211,2018-03-14,11,4 +212,2018-09-12,45,4 +213,2018-11-20,87,18 +214,2018-12-06,64,11 +215,2019-02-18,39,7 +216,2019-07-02,19,6 +217,2019-07-28,49,8 +218,2019-09-07,85,7 +219,2019-09-22,98,2 +220,2019-09-25,79,2 +221,2020-01-15,9,15 +222,2020-06-19,55,18 +223,2021-02-17,22,2 +224,2021-04-20,44,14 +225,2021-05-29,7,13 +226,2021-06-05,32,10 +227,2021-06-30,90,11 +228,2021-07-13,54,9 +229,2021-07-30,25,14 +230,2021-10-26,62,18 +231,2021-11-10,34,13 +232,2021-12-03,80,5 +233,2022-01-19,17,18 +234,2022-06-03,89,10 +235,2022-06-10,23,20 +236,2022-07-26,72,14 +237,2022-08-10,57,16 +238,2022-09-18,1,17 +239,2022-10-22,88,10 +240,2023-01-12,1,9 +241,2023-02-22,47,13 +242,2023-04-19,19,12 +243,2023-06-05,92,16 +244,2023-07-19,19,20 +245,2023-08-12,90,19 +246,2023-08-21,73,7 +247,2023-11-21,96,13 +248,2024-04-27,7,8 +249,2024-07-21,81,12 diff --git a/csv/products.csv b/csv/products.csv new file mode 100644 index 0000000..0d65a3d --- /dev/null +++ b/csv/products.csv @@ -0,0 +1,60 @@ +product_id,product_name,price +1,Fantastic Shoes,2.25 +2,For repair Soft Table,5.19 +3,Sausages,5.42 +4,Ergonomic Wooden Soap,8.99 +5,Wooden Shoes,8.22 +6,Cotton Bike,8.34 +7,Sleek Granite Car,9.03 +8,Concrete Cheese,1.46 +9,Unbranded Wooden Keyboard,0.83 +10,Cotton Sausages,9.89 +11,Shoes,7.13 +12,Mouse,6.42 +13,Soft Pizza,1.81 +14,Handcrafted Hat,3.55 +15,Small Fish,1.34 +16,Gorgeous Salad,9.85 +17,Fantastic Sausages,8.1 +18,Shirt,0.23 +19,Hat,6.92 +20,Licensed Cheese,3.93 +21,Steel Car,9.18 +22,Small Shirt,6.81 +23,Bike,0.12 +24,Plastic Pants,6.62 +25,Incredible Hat,1.92 +26,Unbranded Chicken,4.86 +27,Table,2.67 +28,Concrete Gloves,5.71 +29,For repair Fresh Fish,9.26 +30,Refined Cotton Sausages,3.78 +31,Steel Mouse,1.24 +32,Tasty Pizza,4.15 +33,Steel Computer,7.42 +34,Concrete Pants,8.52 +35,Practical Fish,8.83 +36,Sleek Concrete Cheese,3.92 +37,Frozen Computer,2.26 +38,Wooden Mouse,5.04 +39,Unbranded Wooden Hat,6.36 +40,Cotton Ball,6.59 +41,Practical Steel Towels,4.49 +42,Mouse,9.46 +43,Salad,0.53 +44,Practical Tuna,1.0 +45,Handcrafted Wooden Fish,8.95 +46,Sausages,3.79 +47,Tuna,9.72 +48,Rubber Mouse,7.85 +49,Steel Sausages,5.35 +50,Fantastic Fish,9.59 +51,Pants,9.89 +52,Rubber Towels,4.72 +53,Ergonomic Cheese,5.01 +54,Licensed Plastic Bike,9.3 +55,Chair,3.62 +56,Refined Ball,6.3 +57,New Fresh Chips,7.73 +58,Intelligent Chips,7.69 +59,Ball,8.45 diff --git a/db/.gitignore b/db/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/db/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/load_db.py b/load_db.py new file mode 100644 index 0000000..a75941d --- /dev/null +++ b/load_db.py @@ -0,0 +1,77 @@ +import pandas as pd +import sqlalchemy as sa +import sqlite3 +import os +db_path = "./db/lesson.db" + +if os.path.exists(db_path): + answer = input("The database exists. Do you want to recreate it (y/n)?") + if answer.lower() != 'y': + exit(0) + os.remove(db_path) + +with sqlite3.connect("./db/lesson.db",isolation_level='IMMEDIATE') as conn: + conn = sqlite3.connect("./db/lesson.db",isolation_level='IMMEDIATE') + conn.execute("PRAGMA foreign_keys = 1") + cursor = conn.cursor() + # customer_name,contact,street,city,country,postal_code,phone + # Create tables + cursor.execute(""" + CREATE TABLE IF NOT EXISTS customers ( + customer_id INTEGER PRIMARY KEY, + customer_name TEXT, + contact TEXT, + street TEXT, + city TEXT, + postal_code TEXT, + country TEXT, + phone TEXT + ) + """) + cursor.execute(""" + CREATE TABLE IF NOT EXISTS employees ( + employee_id INTEGER PRIMARY KEY, + first_name TEXT, + last_name TEXT, + phone TEXT + ) + """) + cursor.execute(""" + CREATE TABLE IF NOT EXISTS products ( + product_id INTEGER PRIMARY KEY, + product_name TEXT, + price REAL + ) + """) + cursor.execute(""" + CREATE TABLE IF NOT EXISTS line_items ( + line_item_id INTEGER PRIMARY KEY, + order_id INTEGER, + product_id INTEGER, + quantity INTEGER, + FOREIGN KEY(order_id) REFERENCES orders(order_id), + FOREIGN KEY(product_id) REFERENCES products(product_id) + ) + """) + cursor.execute(""" + CREATE TABLE IF NOT EXISTS orders ( + order_id INTEGER PRIMARY KEY, + customer_id INTEGER, + employee_id INTEGER, + date TEXT, + FOREIGN KEY(customer_id) REFERENCES customers(customer_id), + FOREIGN KEY(employee_id) REFERENCES employees(employee_id) + ) + """) + +# Create a database engine +engine = sa.create_engine('sqlite:///db/lesson.db') + +tables = ["customers", "employees", + "products", "orders", "line_items"] + +for table in tables: + t_name = table.lower() + csv_file = "./csv/" + table + ".csv" + data = pd.read_csv(csv_file, sep=',') + data.to_sql(t_name, engine, if_exists='append', index=False) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..5390e16 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +pytest==8.1.1 +pandas==2.2.3 +sqlalchemy==2.0.36 +jupyter_client==8.6.3 +jupyter_core==5.7.2 +nbstripout==0.8.1 \ No newline at end of file diff --git a/sqlcommand.py b/sqlcommand.py new file mode 100644 index 0000000..f9fa419 --- /dev/null +++ b/sqlcommand.py @@ -0,0 +1,68 @@ +import readline # Provides command line editing and history +import sqlite3 # For SQL command execution +import sys +conn = sqlite3.connect("./db/lesson.db",isolation_level='IMMEDIATE') +conn.execute("PRAGMA foreign_keys = 1") + +cursor = conn.cursor() + + +tables = cursor.execute("SELECT name FROM sqlite_schema WHERE type='table' ORDER BY 'name'").fetchall() +print("The tables in this database are:") +for row in tables: + print(row[0]) +print("Enter SQL statements below, ending with a semicolon. Or, type exit to quit.") + +def main(): + # Connect to an in-memory SQLite database (or replace with a file database) + + # Initialize command history and command input buffer + command_buffer = [] + print("Welcome to the SQL shell! Type 'exit;' to quit.") + + while True: + try: + # Prompt depending on whether we're in the middle of a command + prompt = "sql> " if not command_buffer else " -> " + line = input(prompt) + + # Check for exit command + if line.strip().lower() == "exit;": + print("Exiting.") + break + + # Add line to the command buffer + command_buffer.append(line) + + # If line ends with a semicolon, it's the end of a command + if line.strip().endswith(";"): + # Join all lines in the buffer into a single command + full_command = " ".join(command_buffer).strip() + + # Clear the buffer + command_buffer = [] + + # Execute the command and handle any SQL exceptions + try: + cursor.execute(full_command) + results = cursor.fetchall() + for row in results: + print(row) + except sqlite3.Error as e: + print(f"SQL Error: {e}") + + # Commit changes if it’s an INSERT, UPDATE, or DELETE + conn.commit() + + except EOFError: # Handle Ctrl-D (EOF) gracefully + print("\nExiting.") + break + except KeyboardInterrupt: # Handle Ctrl-C (interrupt) + print("\nCommand canceled.") + command_buffer = [] # Reset the command buffer + + # Clean up the database connection + conn.close() + +if __name__ == "__main__": + main()