diff --git a/assignment7/order_summary.csv b/assignment7/order_summary.csv new file mode 100644 index 0000000..6f7d91c --- /dev/null +++ b/assignment7/order_summary.csv @@ -0,0 +1,60 @@ +product_id,order_count,total_sales,product_name +59,14,1385.8,Ball +23,12,16.56,Bike +55,19,818.12,Chair +8,12,186.88,Concrete Cheese +28,12,633.81,Concrete Gloves +34,19,1942.56,Concrete Pants +40,21,1285.05,Cotton Ball +6,26,2168.4,Cotton Bike +10,30,3263.7000000000003,Cotton Sausages +53,21,1282.56,Ergonomic Cheese +4,21,2058.71,Ergonomic Wooden Soap +50,18,2330.37,Fantastic Fish +17,19,1458.0,Fantastic Sausages +1,21,506.25,Fantastic Shoes +29,21,2213.14,For repair Fresh Fish +2,28,1780.17,For repair Soft Table +37,21,555.9599999999999,Frozen Computer +16,12,1211.55,Gorgeous Salad +14,19,720.65,Handcrafted Hat +45,22,1968.9999999999998,Handcrafted Wooden Fish +19,17,1335.56,Hat +25,20,378.24,Incredible Hat +58,17,1499.5500000000002,Intelligent Chips +20,22,982.5000000000001,Licensed Cheese +54,21,2362.2000000000003,Licensed Plastic Bike +42,14,1400.0800000000002,Mouse +12,19,1348.2,Mouse +57,20,1306.3700000000001,New Fresh Chips +51,18,1651.63,Pants +24,20,1290.9,Plastic Pants +35,15,1633.5500000000002,Practical Fish +41,14,588.19,Practical Steel Towels +44,18,224.0,Practical Tuna +56,16,1045.8,Refined Ball +30,14,483.84,Refined Cotton Sausages +48,16,1499.35,Rubber Mouse +52,19,1052.56,Rubber Towels +43,15,76.85000000000001,Salad +3,19,986.44,Sausages +46,15,560.9200000000001,Sausages +18,13,25.300000000000004,Shirt +11,23,1896.58,Shoes +36,21,878.08,Sleek Concrete Cheese +7,18,2067.87,Sleek Granite Car +15,30,438.18,Small Fish +22,17,1069.17,Small Shirt +13,19,352.95,Soft Pizza +21,18,1799.28,Steel Car +33,10,734.58,Steel Computer +31,23,264.12,Steel Mouse +49,17,1348.1999999999998,Steel Sausages +27,17,453.9,Table +32,19,850.75,Tasty Pizza +47,13,1535.7600000000002,Tuna +26,24,1433.7,Unbranded Chicken +39,13,992.1600000000001,Unbranded Wooden Hat +9,22,211.64999999999998,Unbranded Wooden Keyboard +38,18,952.5600000000001,Wooden Mouse +5,20,1767.3000000000002,Wooden Shoes diff --git a/assignment7/school_a.py b/assignment7/school_a.py new file mode 100644 index 0000000..9cda136 --- /dev/null +++ b/assignment7/school_a.py @@ -0,0 +1,39 @@ +import sqlite3 + +# Connect to a new SQLite database +with sqlite3.connect("../db/school.db") as conn: # Create the file here, so that it is not pushed to GitHub! + print("Database created and connected successfully.") + +# The "with" statement closes the connection at the end of that block. You could close it explicitly with conn.close(), but in this case +# the "with" statement takes care of that. + cursor = conn.cursor() + + # Create tables + cursor.execute(""" + CREATE TABLE IF NOT EXISTS Students ( + student_id INTEGER PRIMARY KEY, + name TEXT NOT NULL UNIQUE, + age INTEGER, + major TEXT + ) + """) + + cursor.execute(""" + CREATE TABLE IF NOT EXISTS Courses ( + course_id INTEGER PRIMARY KEY, + course_name TEXT NOT NULL UNIQUE, + instructor_name TEXT + ) + """) + + cursor.execute(""" + CREATE TABLE IF NOT EXISTS Enrollments ( + enrollment_id INTEGER PRIMARY KEY, + student_id INTEGER, + course_id INTEGER, + FOREIGN KEY (student_id) REFERENCES Students (student_id), + FOREIGN KEY (course_id) REFERENCES Courses (course_id) + ) + """) + + print("Tables created successfully.") \ No newline at end of file diff --git a/assignment7/school_b.py b/assignment7/school_b.py new file mode 100644 index 0000000..f8194d0 --- /dev/null +++ b/assignment7/school_b.py @@ -0,0 +1,89 @@ +import sqlite3 + +# Connect to the database + +def add_student(cursor, name, age, major): + try: + cursor.execute("INSERT INTO Students (name, age, major) VALUES (?,?,?)", (name, age, major)) + except sqlite3.IntegrityError: + print(f"{name} is already in the database.") + +def add_course(cursor, name, instructor): + try: + cursor.execute("INSERT INTO Courses (course_name, instructor_name) VALUES (?,?)", (name, instructor)) + except sqlite3.IntegrityError: + print(f"{name} is already in the database.") + +def enroll_student(cursor, student, course): + cursor.execute("SELECT * FROM Students WHERE name = ?", (student,)) # For a tuple with one element, you need to include the comma + results = cursor.fetchall() + if len(results) > 0: + student_id = results[0][0] + else: + print(f"There was no student named {student}.") + return + cursor.execute("SELECT * FROM Courses WHERE course_name = ?", (course,)) + results = cursor.fetchall() + if len(results) > 0: + course_id = results[0][0] + else: + print(f"There was no course named {course}.") + return + + #cursor.execute("INSERT INTO Enrollments (student_id, course_id) VALUES (?, ?)", (1, 1)) + cursor.execute("SELECT * FROM Enrollments WHERE student_id = ? AND course_id = ?", (student_id, course_id)) + results = cursor.fetchall() + if len(results) > 0: + print(f"Student {student} is already enrolled in course {course}.") + return + cursor.execute("INSERT INTO Enrollments (student_id, course_id) VALUES (?, ?)", (student_id, course_id)) +with sqlite3.connect("../db/school.db") as conn: + conn.execute("PRAGMA foreign_keys = 1") # This turns on the foreign key constraint + cursor = conn.cursor() + + # Insert sample data into tables + + add_student(cursor, 'Alice', 20, 'Computer Science') + add_student(cursor, 'Bob', 22, 'History') + add_student(cursor, 'Charlie', 19, 'Biology') + add_course(cursor, 'Math 101', 'Dr. Smith') + add_course(cursor, 'English 101', 'Ms. Jones') + add_course(cursor, 'Chemistry 101', 'Dr. Lee') + + conn.commit() + # If you don't commit the transaction, it is rolled back at the end of the with statement, and the data is discarded. + print("Sample data inserted successfully.") + + cursor.execute("SELECT * FROM Students WHERE name = 'Alice'") + result = cursor.fetchall() + for row in result: + print(row) + + + + + ... # And at the bottom of your "with" block + + enroll_student(cursor, "Alice", "Math 101") + enroll_student(cursor, "Alice", "Chemistry 101") + enroll_student(cursor, "Bob", "Math 101") + enroll_student(cursor, "Bob", "English 101") + enroll_student(cursor, "Charlie", "English 101") + conn.commit() # more writes, so we have to commit to make them final! + +#TO CLEAN DUPLICATES, WORKS 1 TIME WITH PYTHON X.PY EXECUTION +cursor.execute(""" +WITH CTE AS ( +SELECT enrollment_id, +ROW_NUMBER() OVER (PARTITION BY student_id, course_id ORDER BY enrollment_id) AS row_num +FROM Enrollments +) +DELETE FROM Enrollments +WHERE enrollment_id IN ( +SELECT enrollment_id FROM CTE WHERE row_num > 1 +) +""") +cursor.execute(""" +CREATE UNIQUE INDEX IF NOT EXISTS unique_enrollment +ON Enrollments(student_id, course_id) +""") \ No newline at end of file diff --git a/assignment7/sql_intro.py b/assignment7/sql_intro.py new file mode 100644 index 0000000..43d0f85 --- /dev/null +++ b/assignment7/sql_intro.py @@ -0,0 +1,108 @@ +import sqlite3 + +with sqlite3.connect("../db/magazines.db") as conn: + print("Database connected successfully.") + cursor = conn.cursor() + conn.execute("PRAGMA foreign_keys = 1") + + cursor.execute(""" + CREATE TABLE IF NOT EXISTS publishers ( + id INTEGER PRIMARY KEY, + name TEXT NOT NULL UNIQUE + ) + """) + + cursor.execute(""" + CREATE TABLE IF NOT EXISTS magazines ( + id INTEGER PRIMARY KEY, + name TEXT NOT NULL UNIQUE, + publisher_id INTEGER NOT NULL, + FOREIGN KEY (publisher_id) REFERENCES publishers (id) + ) + """) + + cursor.execute(""" + CREATE TABLE IF NOT EXISTS subscribers ( + id INTEGER PRIMARY KEY, + name TEXT NOT NULL, + address TEXT NOT NULL, + UNIQUE(name, address) + ) + """) + cursor.execute(""" + CREATE TABLE IF NOT EXISTS subscribers ( + id INTEGER PRIMARY KEY, + name TEXT NOT NULL, + address TEXT NOT NULL + ) + """) + + cursor.execute(""" + CREATE TABLE IF NOT EXISTS subscriptions ( + id INTEGER PRIMARY KEY, + subscriber_id INTEGER NOT NULL, + magazine_id INTEGER NOT NULL, + expiration_date TEXT NOT NULL, + FOREIGN KEY (subscriber_id) REFERENCES subscribers (id), + FOREIGN KEY (magazine_id) REFERENCES magazines (id), + UNIQUE(subscriber_id, magazine_id) + ) + """) + +cursor.execute('SELECT * FROM subscribers') +cursor.execute('SELECT * FROM magazines ORDER BY name ASC') +publisher_name = 'Tech Monthly' +print(f"\nMagazines by Publisher: {publisher_name}") +cursor.execute(''' + SELECT magazines.* + FROM magazines + JOIN publishers ON magazines.publisher_id = publishers.id + WHERE publishers.name = ? +''', (publisher_name,)) + + + +rows=cursor.fetchall() +for row in rows: + print(row) + +def add_publisher(cursor, name): + try: + cursor.execute("INSERT INTO publishers (name) VALUES (?)", (name,)) + except sqlite3.IntegrityError: + print(f"{name} is already in the database.") + +def add_magazin(cursor, name, publisher_id): + try: + cursor.execute("INSERT INTO magazines (name, publisher_id) VALUES (?,?)", (name, publisher_id)) + except sqlite3.IntegrityError: + print(f"{name} is already in the database.") + +def add_subscriber(cursor, name, address): + try: + cursor.execute("INSERT INTO subscribers (name, address) VALUES (?,?)", (name, address)) + except sqlite3.IntegrityError: + print(f"{name}, {address} is already in the database.") + + +def add_subscriptions(cursor, subscriber_id, magazine_id, expiration_date): + try: + cursor.execute("INSERT INTO subscriptions (subscriber_id, magazine_id, expiration_date) VALUES (?,?,?)", (subscriber_id, magazine_id, expiration_date)) + except sqlite3.IntegrityError: + print(f"Subscription for subscriber {subscriber_id} to magazine {magazine_id} already exists.") + +add_publisher(cursor, 'Tech Monthly') +add_publisher(cursor, 'Another One') +add_magazin(cursor, 'One Magazine', 1) +add_magazin(cursor, 'Two Magazine', 2) +add_subscriber(cursor, 'John Doe', '123 Main St') +add_subscriber(cursor, 'Jane Smith', '456 Elm St') +add_subscriber(cursor, 'John Doe', '789 Oak St') +add_subscriber(cursor, 'Bob Brown', '456 Elm St') +add_subscriber(cursor, 'John Doe', '123 Main St') +add_subscriptions(cursor, 1, 1, '2024-01-01') +add_subscriptions(cursor, 1, 2, '2024-02-01') +add_subscriptions(cursor, 2, 1, '2024-03-01') +add_subscriptions(cursor, 2, 2, '2024-04-01') +conn.commit() + diff --git a/assignment7/sql_intro_2.py b/assignment7/sql_intro_2.py new file mode 100644 index 0000000..4cefece --- /dev/null +++ b/assignment7/sql_intro_2.py @@ -0,0 +1,45 @@ +import sqlite3 +import pandas as pd + +with sqlite3.connect("../db/lesson.db") as conn: + print("Database connected successfully.") + + query = """ + SELECT + line_items.line_item_id, + line_items.quantity, + line_items.product_id, + products.product_name, + products.price + FROM line_items + JOIN products ON line_items.product_id = products.product_id + """ + + df = pd.read_sql_query(query, conn) + +print(df.head()) +df['total'] = df['quantity'] * df['price'] +print(df.head()) + +grouped_df = df.groupby('product_id').agg({ + 'line_item_id': 'count', + 'total': 'sum', + 'product_name': 'first' +}) + + +grouped_df.rename(columns={ + 'line_item_id': 'order_count', + 'total': 'total_sales' +}, inplace=True) + + +print(grouped_df.head()) + +grouped_df = grouped_df.sort_values(by='product_name') + + +grouped_df.to_csv("order_summary.csv") + +print("CSV file 'order_summary.csv' has been written to the assignment7 directory.") +print(grouped_df.head()) \ No newline at end of file