diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/.DS_Store differ
diff --git a/.ipynb_checkpoints/Untitled-checkpoint.ipynb b/.ipynb_checkpoints/Untitled-checkpoint.ipynb
new file mode 100644
index 0000000..efed0b5
--- /dev/null
+++ b/.ipynb_checkpoints/Untitled-checkpoint.ipynb
@@ -0,0 +1,110 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "752d422d-b865-40b5-a41f-ee5d3c4a3505",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2.0.39\n"
+ ]
+ }
+ ],
+ "source": [
+ "import sqlalchemy\n",
+ "print(sqlalchemy.__version__)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "8599e393-0a2e-44e0-ad64-42504e8e29d6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "from sqlalchemy import create_engine, text\n",
+ "import getpass\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "a31784fe-2018-42f2-bbad-43c376e770ee",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ " ········\n"
+ ]
+ }
+ ],
+ "source": [
+ "password = getpass.getpass()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "23c3299c-0e05-4cd1-8760-c20852e382b2",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Engine(mysql+pymysql://root:***@localhost/sakila)"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bd = \"sakila\"\n",
+ "connection_string = 'mysql+pymysql://root:' + password + '@localhost/'+ bd\n",
+ "engine = create_engine(connection_string)\n",
+ "engine"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2c2c7fe7-9029-4067-b93f-e62ee9304bd8",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "with engine.connect() as connection:\n",
+ " result = connection.execute(text(\"SELECT DATABASE();\"))\n",
+ " print(result.scalar())"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.13.5"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/.ipynb_checkpoints/python_connection_lab-checkpoint.ipynb b/.ipynb_checkpoints/python_connection_lab-checkpoint.ipynb
new file mode 100644
index 0000000..edc267d
--- /dev/null
+++ b/.ipynb_checkpoints/python_connection_lab-checkpoint.ipynb
@@ -0,0 +1,815 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "id": "752d422d-b865-40b5-a41f-ee5d3c4a3505",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2.0.39\n"
+ ]
+ }
+ ],
+ "source": [
+ "import sqlalchemy\n",
+ "print(sqlalchemy.__version__)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "id": "8599e393-0a2e-44e0-ad64-42504e8e29d6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "from sqlalchemy import create_engine, text\n",
+ "import getpass\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "id": "a31784fe-2018-42f2-bbad-43c376e770ee",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ " ········\n"
+ ]
+ }
+ ],
+ "source": [
+ "password = getpass.getpass()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "id": "23c3299c-0e05-4cd1-8760-c20852e382b2",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Engine(mysql+pymysql://root:***@localhost/sakila)"
+ ]
+ },
+ "execution_count": 31,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bd = \"sakila\"\n",
+ "connection_string = 'mysql+pymysql://root:' + password + '@localhost/'+ bd\n",
+ "engine = create_engine(connection_string)\n",
+ "engine"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "id": "2c2c7fe7-9029-4067-b93f-e62ee9304bd8",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "sakila\n"
+ ]
+ }
+ ],
+ "source": [
+ "with engine.connect() as connection:\n",
+ " result = connection.execute(text(\"SELECT DATABASE();\"))\n",
+ " print(result.scalar())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 33,
+ "id": "a6e0413f-9277-4722-a43c-8bd76297c7a9",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[('actor',), ('actor_info',), ('address',), ('category',), ('city',), ('country',), ('customer',), ('customer_list',), ('film',), ('film_actor',), ('film_category',), ('film_list',), ('film_text',), ('inventory',), ('language',), ('nicer_but_slower_film_list',), ('payment',), ('rental',), ('sales_by_film_category',), ('sales_by_store',), ('staff',), ('staff_list',), ('store',), ('v_rental_info_customer',)]\n"
+ ]
+ }
+ ],
+ "source": [
+ "with engine.connect() as connection:\n",
+ " \n",
+ " result = connection.execute(text(\"SHOW TABLES;\"))\n",
+ " print(result.fetchall())\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "id": "92aa2451-ae29-4f37-80b9-a17ff954327a",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " rental_id | \n",
+ " rental_date | \n",
+ " inventory_id | \n",
+ " customer_id | \n",
+ " return_date | \n",
+ " staff_id | \n",
+ " last_update | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 1 | \n",
+ " 2005-05-24 22:53:30 | \n",
+ " 367 | \n",
+ " 130 | \n",
+ " 2005-05-26 22:04:30 | \n",
+ " 1 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 2 | \n",
+ " 2005-05-24 22:54:33 | \n",
+ " 1525 | \n",
+ " 459 | \n",
+ " 2005-05-28 19:40:33 | \n",
+ " 1 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 3 | \n",
+ " 2005-05-24 23:03:39 | \n",
+ " 1711 | \n",
+ " 408 | \n",
+ " 2005-06-01 22:12:39 | \n",
+ " 1 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 4 | \n",
+ " 2005-05-24 23:04:41 | \n",
+ " 2452 | \n",
+ " 333 | \n",
+ " 2005-06-03 01:43:41 | \n",
+ " 2 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 5 | \n",
+ " 2005-05-24 23:05:21 | \n",
+ " 2079 | \n",
+ " 222 | \n",
+ " 2005-06-02 04:33:21 | \n",
+ " 1 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " rental_id rental_date inventory_id customer_id \\\n",
+ "0 1 2005-05-24 22:53:30 367 130 \n",
+ "1 2 2005-05-24 22:54:33 1525 459 \n",
+ "2 3 2005-05-24 23:03:39 1711 408 \n",
+ "3 4 2005-05-24 23:04:41 2452 333 \n",
+ "4 5 2005-05-24 23:05:21 2079 222 \n",
+ "\n",
+ " return_date staff_id last_update \n",
+ "0 2005-05-26 22:04:30 1 2006-02-15 21:30:53 \n",
+ "1 2005-05-28 19:40:33 1 2006-02-15 21:30:53 \n",
+ "2 2005-06-01 22:12:39 1 2006-02-15 21:30:53 \n",
+ "3 2005-06-03 01:43:41 2 2006-02-15 21:30:53 \n",
+ "4 2005-06-02 04:33:21 1 2006-02-15 21:30:53 "
+ ]
+ },
+ "execution_count": 34,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Write a Python function called rentals_month that retrieves rental data for a given month and year (passed as parameters) from the \n",
+ "# Sakila database as a Pandas DataFrame.\n",
+ "\n",
+ "with engine.connect() as connection:\n",
+ " query = text(\"SELECT * FROM rental LIMIT 5;\")\n",
+ " result = connection.execute(query)\n",
+ " df = pd.DataFrame(result.all(), columns=result.keys())\n",
+ "\n",
+ "df"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 35,
+ "id": "039c1489-f49d-4ce9-a333-336eb5d53816",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def rentals_month(engine, month, year):\n",
+ " query = text(\"\"\"\n",
+ " SELECT *\n",
+ " FROM rental\n",
+ " WHERE MONTH(rental_date) = :month\n",
+ " AND YEAR(rental_date) = :year;\n",
+ " \"\"\")\n",
+ "\n",
+ " with engine.connect() as connection:\n",
+ " result = connection.execute(query, {\n",
+ " \"month\": month,\n",
+ " \"year\": year})\n",
+ " rentals_df = pd.DataFrame(\n",
+ " result.all(), \n",
+ " columns=result.keys())\n",
+ "\n",
+ " return rentals_df"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 36,
+ "id": "b2469d5a-3586-421d-a2de-83a143444014",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " rental_id | \n",
+ " rental_date | \n",
+ " inventory_id | \n",
+ " customer_id | \n",
+ " return_date | \n",
+ " staff_id | \n",
+ " last_update | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 3470 | \n",
+ " 2005-07-05 22:49:24 | \n",
+ " 883 | \n",
+ " 565 | \n",
+ " 2005-07-07 19:36:24 | \n",
+ " 1 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 3471 | \n",
+ " 2005-07-05 22:51:44 | \n",
+ " 1724 | \n",
+ " 242 | \n",
+ " 2005-07-13 01:38:44 | \n",
+ " 2 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 3472 | \n",
+ " 2005-07-05 22:56:33 | \n",
+ " 841 | \n",
+ " 37 | \n",
+ " 2005-07-13 17:18:33 | \n",
+ " 2 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 3473 | \n",
+ " 2005-07-05 22:57:34 | \n",
+ " 2735 | \n",
+ " 60 | \n",
+ " 2005-07-12 23:53:34 | \n",
+ " 1 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 3474 | \n",
+ " 2005-07-05 22:59:53 | \n",
+ " 97 | \n",
+ " 594 | \n",
+ " 2005-07-08 20:32:53 | \n",
+ " 1 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " | 6704 | \n",
+ " 10176 | \n",
+ " 2005-07-31 23:40:35 | \n",
+ " 1181 | \n",
+ " 19 | \n",
+ " 2005-08-09 00:46:35 | \n",
+ " 2 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 6705 | \n",
+ " 10177 | \n",
+ " 2005-07-31 23:42:33 | \n",
+ " 2242 | \n",
+ " 279 | \n",
+ " 2005-08-03 01:30:33 | \n",
+ " 2 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 6706 | \n",
+ " 10178 | \n",
+ " 2005-07-31 23:43:04 | \n",
+ " 1582 | \n",
+ " 491 | \n",
+ " 2005-08-03 00:43:04 | \n",
+ " 1 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 6707 | \n",
+ " 10179 | \n",
+ " 2005-07-31 23:49:54 | \n",
+ " 2136 | \n",
+ " 131 | \n",
+ " 2005-08-01 20:46:54 | \n",
+ " 2 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 6708 | \n",
+ " 10180 | \n",
+ " 2005-07-31 23:57:43 | \n",
+ " 757 | \n",
+ " 50 | \n",
+ " 2005-08-09 04:04:43 | \n",
+ " 2 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
6709 rows × 7 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " rental_id rental_date inventory_id customer_id \\\n",
+ "0 3470 2005-07-05 22:49:24 883 565 \n",
+ "1 3471 2005-07-05 22:51:44 1724 242 \n",
+ "2 3472 2005-07-05 22:56:33 841 37 \n",
+ "3 3473 2005-07-05 22:57:34 2735 60 \n",
+ "4 3474 2005-07-05 22:59:53 97 594 \n",
+ "... ... ... ... ... \n",
+ "6704 10176 2005-07-31 23:40:35 1181 19 \n",
+ "6705 10177 2005-07-31 23:42:33 2242 279 \n",
+ "6706 10178 2005-07-31 23:43:04 1582 491 \n",
+ "6707 10179 2005-07-31 23:49:54 2136 131 \n",
+ "6708 10180 2005-07-31 23:57:43 757 50 \n",
+ "\n",
+ " return_date staff_id last_update \n",
+ "0 2005-07-07 19:36:24 1 2006-02-15 21:30:53 \n",
+ "1 2005-07-13 01:38:44 2 2006-02-15 21:30:53 \n",
+ "2 2005-07-13 17:18:33 2 2006-02-15 21:30:53 \n",
+ "3 2005-07-12 23:53:34 1 2006-02-15 21:30:53 \n",
+ "4 2005-07-08 20:32:53 1 2006-02-15 21:30:53 \n",
+ "... ... ... ... \n",
+ "6704 2005-08-09 00:46:35 2 2006-02-15 21:30:53 \n",
+ "6705 2005-08-03 01:30:33 2 2006-02-15 21:30:53 \n",
+ "6706 2005-08-03 00:43:04 1 2006-02-15 21:30:53 \n",
+ "6707 2005-08-01 20:46:54 2 2006-02-15 21:30:53 \n",
+ "6708 2005-08-09 04:04:43 2 2006-02-15 21:30:53 \n",
+ "\n",
+ "[6709 rows x 7 columns]"
+ ]
+ },
+ "execution_count": 36,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# testing the function\n",
+ "rentals_july_2005 = rentals_month(engine, 7, 2005)\n",
+ "rentals_july_2005"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 43,
+ "id": "1eeee65b-8ef5-4e53-8566-5e5cefb9749c",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " year | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 2005 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 2006 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " year\n",
+ "0 2005\n",
+ "1 2006"
+ ]
+ },
+ "execution_count": 43,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# checking the unique values for month\n",
+ "with engine.connect() as connection:\n",
+ " query = text(\"\"\"\n",
+ " SELECT DISTINCT YEAR(rental_date) AS year\n",
+ " FROM rental\n",
+ " ORDER BY year;\n",
+ " \"\"\")\n",
+ " result = connection.execute(query)\n",
+ " df_months = pd.DataFrame(result.all(), columns=result.keys())\n",
+ "\n",
+ "df_months"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 44,
+ "id": "235dd0c5-0516-42aa-9aa0-a6ed7d1f0675",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def rental_count_month(rentals_df, month, year):\n",
+ " \n",
+ " rental_count = (\n",
+ " rentals_df\n",
+ " .groupby(\"customer_id\")\n",
+ " .size()\n",
+ " .reset_index(name=f\"rentals_{month:02d}_{year}\")\n",
+ " )\n",
+ " \n",
+ " return rental_count"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 46,
+ "id": "def6f1ac-3d4d-48dd-a8c2-e82af0901e2c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "rentals_may = rentals_month(engine, 5, 2005)\n",
+ "\n",
+ "rental_count_may = rental_count_month(\n",
+ " rentals_may,\n",
+ " 5,\n",
+ " 2005\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 47,
+ "id": "6bab7e65-91b0-412b-824d-c7a591d9c43a",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " customer_id | \n",
+ " rentals_05_2005 | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 5 | \n",
+ " 3 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 6 | \n",
+ " 3 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " customer_id rentals_05_2005\n",
+ "0 1 2\n",
+ "1 2 1\n",
+ "2 3 2\n",
+ "3 5 3\n",
+ "4 6 3"
+ ]
+ },
+ "execution_count": 47,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "rental_count_may.head()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 51,
+ "id": "1629ba9e-00f0-4207-9882-70f95ef3db13",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "rentals_june = rentals_month(engine, 6, 2005)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 52,
+ "id": "ce8ed30f-7f33-4fb3-ba51-6d5898794fa5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "rental_count_june = rental_count_month(\n",
+ " rentals_june,\n",
+ " 6,\n",
+ " 2005\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 48,
+ "id": "7a55fd28-644f-488b-bbcd-6b304c480865",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def compare_rentals(df1, df2):\n",
+ " comparison = pd.merge(\n",
+ " df1,\n",
+ " df2,\n",
+ " on=\"customer_id\",\n",
+ " how=\"inner\"\n",
+ " )\n",
+ "\n",
+ " comparison[\"difference\"] = (\n",
+ " comparison.iloc[:, 2] - comparison.iloc[:, 1]\n",
+ " )\n",
+ "\n",
+ " return comparison"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 53,
+ "id": "a77ebd69-1852-4658-8bfb-53579fd5321a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "comparison = compare_rentals(\n",
+ " rental_count_may,\n",
+ " rental_count_june\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 55,
+ "id": "7184c304-1a11-442d-9461-037e5d1cb5af",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " customer_id | \n",
+ " rentals_05_2005 | \n",
+ " rentals_06_2005 | \n",
+ " difference | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 7 | \n",
+ " 5 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " 4 | \n",
+ " 2 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 5 | \n",
+ " 3 | \n",
+ " 5 | \n",
+ " 2 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 6 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " customer_id rentals_05_2005 rentals_06_2005 difference\n",
+ "0 1 2 7 5\n",
+ "1 2 1 1 0\n",
+ "2 3 2 4 2\n",
+ "3 5 3 5 2\n",
+ "4 6 3 4 1"
+ ]
+ },
+ "execution_count": 55,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "comparison.head()"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.13.5"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/python_connection_lab.ipynb b/python_connection_lab.ipynb
new file mode 100644
index 0000000..edc267d
--- /dev/null
+++ b/python_connection_lab.ipynb
@@ -0,0 +1,815 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "id": "752d422d-b865-40b5-a41f-ee5d3c4a3505",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2.0.39\n"
+ ]
+ }
+ ],
+ "source": [
+ "import sqlalchemy\n",
+ "print(sqlalchemy.__version__)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "id": "8599e393-0a2e-44e0-ad64-42504e8e29d6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "from sqlalchemy import create_engine, text\n",
+ "import getpass\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "id": "a31784fe-2018-42f2-bbad-43c376e770ee",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ " ········\n"
+ ]
+ }
+ ],
+ "source": [
+ "password = getpass.getpass()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "id": "23c3299c-0e05-4cd1-8760-c20852e382b2",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Engine(mysql+pymysql://root:***@localhost/sakila)"
+ ]
+ },
+ "execution_count": 31,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bd = \"sakila\"\n",
+ "connection_string = 'mysql+pymysql://root:' + password + '@localhost/'+ bd\n",
+ "engine = create_engine(connection_string)\n",
+ "engine"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "id": "2c2c7fe7-9029-4067-b93f-e62ee9304bd8",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "sakila\n"
+ ]
+ }
+ ],
+ "source": [
+ "with engine.connect() as connection:\n",
+ " result = connection.execute(text(\"SELECT DATABASE();\"))\n",
+ " print(result.scalar())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 33,
+ "id": "a6e0413f-9277-4722-a43c-8bd76297c7a9",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[('actor',), ('actor_info',), ('address',), ('category',), ('city',), ('country',), ('customer',), ('customer_list',), ('film',), ('film_actor',), ('film_category',), ('film_list',), ('film_text',), ('inventory',), ('language',), ('nicer_but_slower_film_list',), ('payment',), ('rental',), ('sales_by_film_category',), ('sales_by_store',), ('staff',), ('staff_list',), ('store',), ('v_rental_info_customer',)]\n"
+ ]
+ }
+ ],
+ "source": [
+ "with engine.connect() as connection:\n",
+ " \n",
+ " result = connection.execute(text(\"SHOW TABLES;\"))\n",
+ " print(result.fetchall())\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "id": "92aa2451-ae29-4f37-80b9-a17ff954327a",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " rental_id | \n",
+ " rental_date | \n",
+ " inventory_id | \n",
+ " customer_id | \n",
+ " return_date | \n",
+ " staff_id | \n",
+ " last_update | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 1 | \n",
+ " 2005-05-24 22:53:30 | \n",
+ " 367 | \n",
+ " 130 | \n",
+ " 2005-05-26 22:04:30 | \n",
+ " 1 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 2 | \n",
+ " 2005-05-24 22:54:33 | \n",
+ " 1525 | \n",
+ " 459 | \n",
+ " 2005-05-28 19:40:33 | \n",
+ " 1 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 3 | \n",
+ " 2005-05-24 23:03:39 | \n",
+ " 1711 | \n",
+ " 408 | \n",
+ " 2005-06-01 22:12:39 | \n",
+ " 1 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 4 | \n",
+ " 2005-05-24 23:04:41 | \n",
+ " 2452 | \n",
+ " 333 | \n",
+ " 2005-06-03 01:43:41 | \n",
+ " 2 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 5 | \n",
+ " 2005-05-24 23:05:21 | \n",
+ " 2079 | \n",
+ " 222 | \n",
+ " 2005-06-02 04:33:21 | \n",
+ " 1 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " rental_id rental_date inventory_id customer_id \\\n",
+ "0 1 2005-05-24 22:53:30 367 130 \n",
+ "1 2 2005-05-24 22:54:33 1525 459 \n",
+ "2 3 2005-05-24 23:03:39 1711 408 \n",
+ "3 4 2005-05-24 23:04:41 2452 333 \n",
+ "4 5 2005-05-24 23:05:21 2079 222 \n",
+ "\n",
+ " return_date staff_id last_update \n",
+ "0 2005-05-26 22:04:30 1 2006-02-15 21:30:53 \n",
+ "1 2005-05-28 19:40:33 1 2006-02-15 21:30:53 \n",
+ "2 2005-06-01 22:12:39 1 2006-02-15 21:30:53 \n",
+ "3 2005-06-03 01:43:41 2 2006-02-15 21:30:53 \n",
+ "4 2005-06-02 04:33:21 1 2006-02-15 21:30:53 "
+ ]
+ },
+ "execution_count": 34,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Write a Python function called rentals_month that retrieves rental data for a given month and year (passed as parameters) from the \n",
+ "# Sakila database as a Pandas DataFrame.\n",
+ "\n",
+ "with engine.connect() as connection:\n",
+ " query = text(\"SELECT * FROM rental LIMIT 5;\")\n",
+ " result = connection.execute(query)\n",
+ " df = pd.DataFrame(result.all(), columns=result.keys())\n",
+ "\n",
+ "df"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 35,
+ "id": "039c1489-f49d-4ce9-a333-336eb5d53816",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def rentals_month(engine, month, year):\n",
+ " query = text(\"\"\"\n",
+ " SELECT *\n",
+ " FROM rental\n",
+ " WHERE MONTH(rental_date) = :month\n",
+ " AND YEAR(rental_date) = :year;\n",
+ " \"\"\")\n",
+ "\n",
+ " with engine.connect() as connection:\n",
+ " result = connection.execute(query, {\n",
+ " \"month\": month,\n",
+ " \"year\": year})\n",
+ " rentals_df = pd.DataFrame(\n",
+ " result.all(), \n",
+ " columns=result.keys())\n",
+ "\n",
+ " return rentals_df"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 36,
+ "id": "b2469d5a-3586-421d-a2de-83a143444014",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " rental_id | \n",
+ " rental_date | \n",
+ " inventory_id | \n",
+ " customer_id | \n",
+ " return_date | \n",
+ " staff_id | \n",
+ " last_update | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 3470 | \n",
+ " 2005-07-05 22:49:24 | \n",
+ " 883 | \n",
+ " 565 | \n",
+ " 2005-07-07 19:36:24 | \n",
+ " 1 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 3471 | \n",
+ " 2005-07-05 22:51:44 | \n",
+ " 1724 | \n",
+ " 242 | \n",
+ " 2005-07-13 01:38:44 | \n",
+ " 2 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 3472 | \n",
+ " 2005-07-05 22:56:33 | \n",
+ " 841 | \n",
+ " 37 | \n",
+ " 2005-07-13 17:18:33 | \n",
+ " 2 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 3473 | \n",
+ " 2005-07-05 22:57:34 | \n",
+ " 2735 | \n",
+ " 60 | \n",
+ " 2005-07-12 23:53:34 | \n",
+ " 1 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 3474 | \n",
+ " 2005-07-05 22:59:53 | \n",
+ " 97 | \n",
+ " 594 | \n",
+ " 2005-07-08 20:32:53 | \n",
+ " 1 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " | 6704 | \n",
+ " 10176 | \n",
+ " 2005-07-31 23:40:35 | \n",
+ " 1181 | \n",
+ " 19 | \n",
+ " 2005-08-09 00:46:35 | \n",
+ " 2 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 6705 | \n",
+ " 10177 | \n",
+ " 2005-07-31 23:42:33 | \n",
+ " 2242 | \n",
+ " 279 | \n",
+ " 2005-08-03 01:30:33 | \n",
+ " 2 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 6706 | \n",
+ " 10178 | \n",
+ " 2005-07-31 23:43:04 | \n",
+ " 1582 | \n",
+ " 491 | \n",
+ " 2005-08-03 00:43:04 | \n",
+ " 1 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 6707 | \n",
+ " 10179 | \n",
+ " 2005-07-31 23:49:54 | \n",
+ " 2136 | \n",
+ " 131 | \n",
+ " 2005-08-01 20:46:54 | \n",
+ " 2 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ " | 6708 | \n",
+ " 10180 | \n",
+ " 2005-07-31 23:57:43 | \n",
+ " 757 | \n",
+ " 50 | \n",
+ " 2005-08-09 04:04:43 | \n",
+ " 2 | \n",
+ " 2006-02-15 21:30:53 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
6709 rows × 7 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " rental_id rental_date inventory_id customer_id \\\n",
+ "0 3470 2005-07-05 22:49:24 883 565 \n",
+ "1 3471 2005-07-05 22:51:44 1724 242 \n",
+ "2 3472 2005-07-05 22:56:33 841 37 \n",
+ "3 3473 2005-07-05 22:57:34 2735 60 \n",
+ "4 3474 2005-07-05 22:59:53 97 594 \n",
+ "... ... ... ... ... \n",
+ "6704 10176 2005-07-31 23:40:35 1181 19 \n",
+ "6705 10177 2005-07-31 23:42:33 2242 279 \n",
+ "6706 10178 2005-07-31 23:43:04 1582 491 \n",
+ "6707 10179 2005-07-31 23:49:54 2136 131 \n",
+ "6708 10180 2005-07-31 23:57:43 757 50 \n",
+ "\n",
+ " return_date staff_id last_update \n",
+ "0 2005-07-07 19:36:24 1 2006-02-15 21:30:53 \n",
+ "1 2005-07-13 01:38:44 2 2006-02-15 21:30:53 \n",
+ "2 2005-07-13 17:18:33 2 2006-02-15 21:30:53 \n",
+ "3 2005-07-12 23:53:34 1 2006-02-15 21:30:53 \n",
+ "4 2005-07-08 20:32:53 1 2006-02-15 21:30:53 \n",
+ "... ... ... ... \n",
+ "6704 2005-08-09 00:46:35 2 2006-02-15 21:30:53 \n",
+ "6705 2005-08-03 01:30:33 2 2006-02-15 21:30:53 \n",
+ "6706 2005-08-03 00:43:04 1 2006-02-15 21:30:53 \n",
+ "6707 2005-08-01 20:46:54 2 2006-02-15 21:30:53 \n",
+ "6708 2005-08-09 04:04:43 2 2006-02-15 21:30:53 \n",
+ "\n",
+ "[6709 rows x 7 columns]"
+ ]
+ },
+ "execution_count": 36,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# testing the function\n",
+ "rentals_july_2005 = rentals_month(engine, 7, 2005)\n",
+ "rentals_july_2005"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 43,
+ "id": "1eeee65b-8ef5-4e53-8566-5e5cefb9749c",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " year | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 2005 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 2006 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " year\n",
+ "0 2005\n",
+ "1 2006"
+ ]
+ },
+ "execution_count": 43,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# checking the unique values for month\n",
+ "with engine.connect() as connection:\n",
+ " query = text(\"\"\"\n",
+ " SELECT DISTINCT YEAR(rental_date) AS year\n",
+ " FROM rental\n",
+ " ORDER BY year;\n",
+ " \"\"\")\n",
+ " result = connection.execute(query)\n",
+ " df_months = pd.DataFrame(result.all(), columns=result.keys())\n",
+ "\n",
+ "df_months"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 44,
+ "id": "235dd0c5-0516-42aa-9aa0-a6ed7d1f0675",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def rental_count_month(rentals_df, month, year):\n",
+ " \n",
+ " rental_count = (\n",
+ " rentals_df\n",
+ " .groupby(\"customer_id\")\n",
+ " .size()\n",
+ " .reset_index(name=f\"rentals_{month:02d}_{year}\")\n",
+ " )\n",
+ " \n",
+ " return rental_count"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 46,
+ "id": "def6f1ac-3d4d-48dd-a8c2-e82af0901e2c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "rentals_may = rentals_month(engine, 5, 2005)\n",
+ "\n",
+ "rental_count_may = rental_count_month(\n",
+ " rentals_may,\n",
+ " 5,\n",
+ " 2005\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 47,
+ "id": "6bab7e65-91b0-412b-824d-c7a591d9c43a",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " customer_id | \n",
+ " rentals_05_2005 | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 5 | \n",
+ " 3 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 6 | \n",
+ " 3 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " customer_id rentals_05_2005\n",
+ "0 1 2\n",
+ "1 2 1\n",
+ "2 3 2\n",
+ "3 5 3\n",
+ "4 6 3"
+ ]
+ },
+ "execution_count": 47,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "rental_count_may.head()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 51,
+ "id": "1629ba9e-00f0-4207-9882-70f95ef3db13",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "rentals_june = rentals_month(engine, 6, 2005)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 52,
+ "id": "ce8ed30f-7f33-4fb3-ba51-6d5898794fa5",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "rental_count_june = rental_count_month(\n",
+ " rentals_june,\n",
+ " 6,\n",
+ " 2005\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 48,
+ "id": "7a55fd28-644f-488b-bbcd-6b304c480865",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def compare_rentals(df1, df2):\n",
+ " comparison = pd.merge(\n",
+ " df1,\n",
+ " df2,\n",
+ " on=\"customer_id\",\n",
+ " how=\"inner\"\n",
+ " )\n",
+ "\n",
+ " comparison[\"difference\"] = (\n",
+ " comparison.iloc[:, 2] - comparison.iloc[:, 1]\n",
+ " )\n",
+ "\n",
+ " return comparison"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 53,
+ "id": "a77ebd69-1852-4658-8bfb-53579fd5321a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "comparison = compare_rentals(\n",
+ " rental_count_may,\n",
+ " rental_count_june\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 55,
+ "id": "7184c304-1a11-442d-9461-037e5d1cb5af",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " customer_id | \n",
+ " rentals_05_2005 | \n",
+ " rentals_06_2005 | \n",
+ " difference | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 7 | \n",
+ " 5 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 2 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 3 | \n",
+ " 2 | \n",
+ " 4 | \n",
+ " 2 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 5 | \n",
+ " 3 | \n",
+ " 5 | \n",
+ " 2 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 6 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " customer_id rentals_05_2005 rentals_06_2005 difference\n",
+ "0 1 2 7 5\n",
+ "1 2 1 1 0\n",
+ "2 3 2 4 2\n",
+ "3 5 3 5 2\n",
+ "4 6 3 4 1"
+ ]
+ },
+ "execution_count": 55,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "comparison.head()"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.13.5"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}