diff --git a/.ipynb_checkpoints/lab-python-error-handling-checkpoint.ipynb b/.ipynb_checkpoints/lab-python-error-handling-checkpoint.ipynb
new file mode 100644
index 0000000..f4c6ef6
--- /dev/null
+++ b/.ipynb_checkpoints/lab-python-error-handling-checkpoint.ipynb
@@ -0,0 +1,98 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "25d7736c-ba17-4aff-b6bb-66eba20fbf4e",
+ "metadata": {},
+ "source": [
+ "# Lab | Error Handling"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bc99b386-7508-47a0-bcdb-d969deaf6c8b",
+ "metadata": {},
+ "source": [
+ "## Exercise: Error Handling for Managing Customer Orders\n",
+ "\n",
+ "The implementation of your code for managing customer orders assumes that the user will always enter a valid input. \n",
+ "\n",
+ "For example, we could modify the `initialize_inventory` function to include error handling.\n",
+ " - If the user enters an invalid quantity (e.g., a negative value or a non-numeric value), display an error message and ask them to re-enter the quantity for that product.\n",
+ " - Use a try-except block to handle the error and continue prompting the user until a valid quantity is entered.\n",
+ "\n",
+ "```python\n",
+ "# Step 1: Define the function for initializing the inventory with error handling\n",
+ "def initialize_inventory(products):\n",
+ " inventory = {}\n",
+ " for product in products:\n",
+ " valid_quantity = False\n",
+ " while not valid_quantity:\n",
+ " try:\n",
+ " quantity = int(input(f\"Enter the quantity of {product}s available: \"))\n",
+ " if quantity < 0:\n",
+ " raise ValueError(\"Invalid quantity! Please enter a non-negative value.\")\n",
+ " valid_quantity = True\n",
+ " except ValueError as error:\n",
+ " print(f\"Error: {error}\")\n",
+ " inventory[product] = quantity\n",
+ " return inventory\n",
+ "\n",
+ "# Or, in another way:\n",
+ "\n",
+ "def initialize_inventory(products):\n",
+ " inventory = {}\n",
+ " for product in products:\n",
+ " valid_input = False\n",
+ " while not valid_input:\n",
+ " try:\n",
+ " quantity = int(input(f\"Enter the quantity of {product}s available: \"))\n",
+ " if quantity >= 0:\n",
+ " inventory[product] = quantity\n",
+ " valid_input = True\n",
+ " else:\n",
+ " print(\"Quantity cannot be negative. Please enter a valid quantity.\")\n",
+ " except ValueError:\n",
+ " print(\"Invalid input. Please enter a valid quantity.\")\n",
+ " return inventory\n",
+ "```\n",
+ "\n",
+ "Let's enhance your code by implementing error handling to handle invalid inputs.\n",
+ "\n",
+ "Follow the steps below to complete the exercise:\n",
+ "\n",
+ "2. Modify the `calculate_total_price` function to include error handling.\n",
+ " - If the user enters an invalid price (e.g., a negative value or a non-numeric value), display an error message and ask them to re-enter the price for that product.\n",
+ " - Use a try-except block to handle the error and continue prompting the user until a valid price is entered.\n",
+ "\n",
+ "3. Modify the `get_customer_orders` function to include error handling.\n",
+ " - If the user enters an invalid number of orders (e.g., a negative value or a non-numeric value), display an error message and ask them to re-enter the number of orders.\n",
+ " - If the user enters an invalid product name (e.g., a product name that is not in the inventory), or that doesn't have stock available, display an error message and ask them to re-enter the product name. *Hint: you will need to pass inventory as a parameter*\n",
+ " - Use a try-except block to handle the error and continue prompting the user until a valid product name is entered.\n",
+ "\n",
+ "4. Test your code by running the program and deliberately entering invalid quantities and product names. Make sure the error handling mechanism works as expected.\n"
+ ]
+ }
+ ],
+ "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.9.13"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/.ipynb_checkpoints/lab-python-list-comprehension-checkpoint.ipynb b/.ipynb_checkpoints/lab-python-list-comprehension-checkpoint.ipynb
new file mode 100644
index 0000000..39856c6
--- /dev/null
+++ b/.ipynb_checkpoints/lab-python-list-comprehension-checkpoint.ipynb
@@ -0,0 +1,358 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "25d7736c-ba17-4aff-b6bb-66eba20fbf4e",
+ "metadata": {},
+ "source": [
+ "# Lab | List, Dict and Set Comprehension"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7dd3cbde-675a-4b81-92c3-f728846dbe06",
+ "metadata": {},
+ "source": [
+ "## Exercise: Managing Customer Orders Optimized with Comprehension"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7db6a154-4bbb-439c-9404-5820a799c0af",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5d500160-2fb7-4777-b5e4-09d45ebaf328",
+ "metadata": {},
+ "source": [
+ "In the previous exercise, you developed a program to manage customer orders and inventory. Now, let's take it a step further and incorporate comprehension into your code.\n",
+ "\n",
+ "Follow the steps below to complete the exercise:\n",
+ "\n",
+ "1. Review your code from the previous exercise and identify areas where you can apply comprehension to simplify and streamline your code. \n",
+ "\n",
+ " - *Hint: Apply it to initialize inventory, updating the inventory and printing the updated inventory.*\n",
+ " \n",
+ " - For example, in initializing the inventory, we could have:\n",
+ " \n",
+ " ```python\n",
+ " def initialize_inventory(products):\n",
+ " inventory = {product: int(input(f\"Enter the quantity of {product}s available: \")) for product in products}\n",
+ " return inventory\n",
+ "\n",
+ " ```\n",
+ "
\n",
+ " \n",
+ " \n",
+ "2. Modify the function get_customer_orders so it prompts the user to enter the number of customer orders and gathers the product names using a loop and user input. Use comprehension.\n",
+ "\n",
+ "3. Add a new function to calculate the total price of the customer order. For each product in customer_orders, prompt the user to enter the price of that product. Use comprehension to calculate the total price. Note: assume that the user can only have 1 unit of each product.\n",
+ "\n",
+ "4. Modify the update_inventory function to remove the product from the inventory if its quantity becomes zero after fulfilling the customer orders. Use comprehension to filter out the products with a quantity of zero from the inventory.\n",
+ "\n",
+ "5. Print the total price of the customer order.\n",
+ "\n",
+ "Your code should produce output similar to the following:\n",
+ "\n",
+ "```python\n",
+ "Enter the quantity of t-shirts available: 5\n",
+ "Enter the quantity of mugs available: 4\n",
+ "Enter the quantity of hats available: 3\n",
+ "Enter the quantity of books available: 2\n",
+ "Enter the quantity of keychains available: 1\n",
+ "Enter the number of customer orders: 2\n",
+ "Enter the name of a product that a customer wants to order: hat\n",
+ "Enter the name of a product that a customer wants to order: keychain\n",
+ "\n",
+ "Order Statistics:\n",
+ "Total Products Ordered: 2\n",
+ "Percentage of Unique Products Ordered: 40.0\n",
+ "\n",
+ "Updated Inventory:\n",
+ "t-shirt: 5\n",
+ "mug: 4\n",
+ "hat: 2\n",
+ "book: 2\n",
+ "Enter the price of keychain: 5\n",
+ "Enter the price of hat: 10\n",
+ "Total Price: 15.0\n",
+ "\n",
+ "```\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "9a63bcdf-0ac3-4e5b-912b-ffab6f423f03",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "--- Inventory Initialization ---\n"
+ ]
+ },
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Enter the quantity of 'Laptop' available: 6\n",
+ "Enter the quantity of 'Mouse' available: 5\n",
+ "Enter the quantity of 'Keyboard' available: 6\n",
+ "Enter the quantity of 'Monitor' available: 7\n",
+ "Enter the quantity of 'Webcam' available: 8\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "--- Customer Order Entry ---\n"
+ ]
+ },
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Enter the number of unique products to order: 4\n",
+ "Enter the name of product #1 to order: Laptop\n",
+ "Enter the name of product #2 to order: Webcam\n",
+ "Enter the name of product #3 to order: Monitor\n",
+ "Enter the name of product #4 to order: Keyboard\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "--- Order Statistics ---\n",
+ "Total Products Ordered: 4\n",
+ "Percentage of Unique Products Ordered: 80.0%\n",
+ "\n",
+ "--- Updating Inventory ---\n",
+ "Inventory reduced for 'Monitor'. New quantity: 6\n",
+ "Inventory reduced for 'Webcam'. New quantity: 7\n",
+ "Inventory reduced for 'Keyboard'. New quantity: 5\n",
+ "Inventory reduced for 'Laptop'. New quantity: 5\n",
+ "\n",
+ "--- Final Updated Inventory ---\n",
+ "**Laptop**: 5\n",
+ "**Mouse**: 5\n",
+ "**Keyboard**: 5\n",
+ "**Monitor**: 6\n",
+ "**Webcam**: 7\n",
+ "\n",
+ "--- Calculating Total Price ---\n"
+ ]
+ },
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Enter the price of 'Monitor': 150\n",
+ "Enter the price of 'Webcam': 50\n",
+ "Enter the price of 'Keyboard': 40\n",
+ "Enter the price of 'Laptop': 600\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Total Price: **840.00**\n"
+ ]
+ }
+ ],
+ "source": [
+ "import math\n",
+ "\n",
+ "# Initial list of available product names\n",
+ "AVAILABLE_PRODUCTS = [\"Laptop\", \"Mouse\", \"Keyboard\", \"Monitor\", \"Webcam\"]\n",
+ "\n",
+ "## 1. Inventory Management Functions with Comprehension\n",
+ "\n",
+ "def initialize_inventory(products):\n",
+ " \"\"\"\n",
+ " Initializes the inventory using a DICTIONARY COMPREHENSION \n",
+ " and user input for initial quantities.\n",
+ " \"\"\"\n",
+ " print(\"\\n--- Inventory Initialization ---\")\n",
+ " \n",
+ " # Dictionary Comprehension for initialization\n",
+ " inventory = {\n",
+ " product: int(input(f\"Enter the quantity of '{product}' available: \")) \n",
+ " for product in products\n",
+ " }\n",
+ " return inventory\n",
+ "\n",
+ "def update_inventory(customer_orders, inventory):\n",
+ " \"\"\"\n",
+ " Updates the inventory based on customer orders and uses a DICTIONARY \n",
+ " COMPREHENSION to filter out products with zero quantity.\n",
+ " \"\"\"\n",
+ " print(\"\\n--- Updating Inventory ---\")\n",
+ " \n",
+ " # 1. Decrement quantities for ordered products\n",
+ " for product in customer_orders:\n",
+ " if product in inventory and inventory[product] > 0:\n",
+ " inventory[product] -= 1\n",
+ " print(f\"Inventory reduced for '{product}'. New quantity: {inventory[product]}\")\n",
+ " elif product in inventory and inventory[product] == 0:\n",
+ " print(f\"Warning: '{product}' was ordered but is out of stock.\")\n",
+ " \n",
+ " # 2. Dictionary Comprehension to filter out zero-quantity items\n",
+ " # This creates a NEW dictionary, effectively removing items with quantity <= 0\n",
+ " updated_inventory = {\n",
+ " product: quantity\n",
+ " for product, quantity in inventory.items() \n",
+ " if quantity > 0\n",
+ " }\n",
+ " \n",
+ " return updated_inventory\n",
+ "\n",
+ "def print_updated_inventory(inventory):\n",
+ " \"\"\"\n",
+ " Prints the final state of the inventory dictionary, only showing items \n",
+ " with positive stock. Uses a concise loop for clean output.\n",
+ " \"\"\"\n",
+ " print(\"\\n--- Final Updated Inventory ---\")\n",
+ " for product, quantity in inventory.items():\n",
+ " print(f\"**{product}**: {quantity}\")\n",
+ "\n",
+ "## 2. Order Management Functions\n",
+ "\n",
+ "def get_customer_orders():\n",
+ " \"\"\"\n",
+ " Prompts the user for the number of orders and gathers product names \n",
+ " using a list/set comprehension-style approach with user input.\n",
+ " \n",
+ " Note: Since the input function must be called inside the loop's \n",
+ " context, we use a standard loop to collect names, and then convert \n",
+ " to a set for uniqueness.\n",
+ " \"\"\"\n",
+ " print(\"\\n--- Customer Order Entry ---\")\n",
+ " \n",
+ " while True:\n",
+ " try:\n",
+ " num_orders = int(input(\"Enter the number of unique products to order: \"))\n",
+ " if num_orders >= 0:\n",
+ " break\n",
+ " else:\n",
+ " print(\"Please enter a non-negative number.\")\n",
+ " except ValueError:\n",
+ " print(\"Invalid input. Please enter a whole number.\")\n",
+ "\n",
+ " # Standard loop to collect input, then a SET to ensure unique products\n",
+ " ordered_products = set()\n",
+ " for i in range(num_orders):\n",
+ " product_name = input(f\"Enter the name of product #{i+1} to order: \").strip()\n",
+ " ordered_products.add(product_name)\n",
+ " \n",
+ " # Note: If we were gathering *quantities* with a comprehension, \n",
+ " # the syntax would be cleaner, but here, the input() call must be inside \n",
+ " # the loop, which makes a standard approach clearer for sequential inputs.\n",
+ " \n",
+ " # Return the set of unique orders\n",
+ " return ordered_products\n",
+ "\n",
+ "def calculate_order_total_price(customer_orders):\n",
+ " \"\"\"\n",
+ " Prompts the user for the price of each ordered product and calculates \n",
+ " the total using a GENERATOR EXPRESSION inside the sum() function.\n",
+ " \n",
+ " :param customer_orders: The set of unique products ordered.\n",
+ " :return: The total cost of the order (float).\n",
+ " \"\"\"\n",
+ " print(\"\\n--- Calculating Total Price ---\")\n",
+ " \n",
+ " # Generator Expression for calculating the sum of prices\n",
+ " total_price = sum(\n",
+ " float(input(f\"Enter the price of '{product}': \"))\n",
+ " for product in customer_orders\n",
+ " )\n",
+ " \n",
+ " return total_price\n",
+ "\n",
+ "## 3. Statistics Functions (From previous exercise, kept for completeness)\n",
+ "\n",
+ "def calculate_order_statistics(customer_orders, products):\n",
+ " \"\"\"Calculates order statistics.\"\"\"\n",
+ " total_products_ordered = len(customer_orders)\n",
+ " total_available_products = len(products)\n",
+ " \n",
+ " if total_available_products > 0:\n",
+ " percentage_ordered = (total_products_ordered / total_available_products) * 100\n",
+ " else:\n",
+ " percentage_ordered = 0.0\n",
+ " \n",
+ " return total_products_ordered, percentage_ordered\n",
+ "\n",
+ "def print_order_statistics(order_statistics):\n",
+ " \"\"\"Prints the calculated order statistics.\"\"\"\n",
+ " total_ordered, percentage = order_statistics\n",
+ " \n",
+ " print(\"\\n--- Order Statistics ---\")\n",
+ " print(f\"Total Products Ordered: {total_ordered}\")\n",
+ " print(f\"Percentage of Unique Products Ordered: {percentage:.1f}%\")\n",
+ "\n",
+ "## --- Main Program Execution ---\n",
+ "\n",
+ "# 1. Initialize Inventory (uses comprehension)\n",
+ "inventory_data = initialize_inventory(AVAILABLE_PRODUCTS)\n",
+ "\n",
+ "# 2. Get Customer Orders (uses loop/set for unique product names)\n",
+ "orders_set = get_customer_orders()\n",
+ "\n",
+ "# 3. Calculate Statistics\n",
+ "stats = calculate_order_statistics(orders_set, AVAILABLE_PRODUCTS)\n",
+ "print_order_statistics(stats)\n",
+ "\n",
+ "# 4. Update Inventory (uses comprehension to filter out zero stock)\n",
+ "final_inventory = update_inventory(orders_set, inventory_data)\n",
+ "print_updated_inventory(final_inventory)\n",
+ "\n",
+ "# 5. Calculate and Print Total Price (uses generator expression)\n",
+ "total_cost = calculate_order_total_price(orders_set)\n",
+ "print(f\"\\nTotal Price: **{total_cost:.2f}**\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "800ef206-78ed-4fed-8cae-71648dd61906",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python [conda env:base] *",
+ "language": "python",
+ "name": "conda-base-py"
+ },
+ "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/anaconda_projects/db/project_filebrowser.db b/anaconda_projects/db/project_filebrowser.db
new file mode 100644
index 0000000..3fa3a4a
Binary files /dev/null and b/anaconda_projects/db/project_filebrowser.db differ
diff --git a/lab-python-error-handling.ipynb b/lab-python-error-handling.ipynb
index f4c6ef6..131fc18 100644
--- a/lab-python-error-handling.ipynb
+++ b/lab-python-error-handling.ipynb
@@ -72,13 +72,328 @@
"\n",
"4. Test your code by running the program and deliberately entering invalid quantities and product names. Make sure the error handling mechanism works as expected.\n"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "325ef2d0-9765-42f5-ba2b-3d32e3dce5ff",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "--- Inventory Initialization ---\n"
+ ]
+ },
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Enter the quantity of 'Laptop' available: 10\n",
+ "Enter the quantity of 'Mouse' available: 12\n",
+ "Enter the quantity of 'Keyboard' available: 14\n",
+ "Enter the quantity of 'Monitor' available: 16\n",
+ "Enter the quantity of 'Webcam' available: 18\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "--- Customer Order Entry ---\n"
+ ]
+ },
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Enter the number of unique products to order: 3\n",
+ "Enter the name of product #1 to order: Laptop\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "'Laptop' added to the order set.\n"
+ ]
+ },
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Enter the name of product #2 to order: Mouse\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "'Mouse' added to the order set.\n"
+ ]
+ },
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Enter the name of product #3 to order: Keyboard\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "'Keyboard' added to the order set.\n",
+ "\n",
+ "--- Order Statistics ---\n",
+ "Total Products Ordered: 3\n",
+ "Percentage of Unique Products Ordered: 60.0%\n",
+ "\n",
+ "--- Updating Inventory ---\n",
+ "Inventory reduced for 'Mouse'. New quantity: 11\n",
+ "Inventory reduced for 'Laptop'. New quantity: 9\n",
+ "Inventory reduced for 'Keyboard'. New quantity: 13\n",
+ "\n",
+ "--- Final Updated Inventory ---\n",
+ "**Laptop**: 9\n",
+ "**Mouse**: 11\n",
+ "**Keyboard**: 13\n",
+ "**Monitor**: 16\n",
+ "**Webcam**: 18\n",
+ "\n",
+ "--- Calculating Total Price ---\n"
+ ]
+ },
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Enter the price of 'Mouse': 40\n",
+ "Enter the price of 'Laptop': 700\n",
+ "Enter the price of 'Keyboard': 40\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Total Price: **780.00**\n"
+ ]
+ }
+ ],
+ "source": [
+ "import math\n",
+ "\n",
+ "# Initial list of available product names\n",
+ "AVAILABLE_PRODUCTS = [\"Laptop\", \"Mouse\", \"Keyboard\", \"Monitor\", \"Webcam\"]\n",
+ "\n",
+ "## 1. Inventory Management Functions with Error Handling\n",
+ "\n",
+ "def initialize_inventory(products):\n",
+ " \"\"\"\n",
+ " Initializes the inventory dictionary. Includes error handling to ensure \n",
+ " the quantity entered is a non-negative integer.\n",
+ " \"\"\"\n",
+ " inventory = {}\n",
+ " print(\"\\n--- Inventory Initialization ---\")\n",
+ " for product in products:\n",
+ " valid_input = False\n",
+ " while not valid_input:\n",
+ " try:\n",
+ " # Attempt to convert input to integer\n",
+ " quantity = int(input(f\"Enter the quantity of '{product}' available: \"))\n",
+ " \n",
+ " # Check for non-negative value\n",
+ " if quantity >= 0:\n",
+ " inventory[product] = quantity\n",
+ " valid_input = True # Exit the validation loop\n",
+ " else:\n",
+ " # Raise a specific error for negative numbers\n",
+ " raise ValueError(\"Quantity cannot be negative.\")\n",
+ " except ValueError as e:\n",
+ " # Handle conversion errors (non-numeric input) or the raised ValueError\n",
+ " print(f\"Error: Invalid input. {e}. Please enter a whole number.\")\n",
+ " return inventory\n",
+ "\n",
+ "def update_inventory(customer_orders, inventory):\n",
+ " \"\"\"\n",
+ " Updates the inventory based on customer orders and filters out products \n",
+ " with zero quantity using a dictionary comprehension.\n",
+ " \n",
+ " NOTE: This uses a copy of the inventory dictionary to prevent side effects\n",
+ " during the update process.\n",
+ " \"\"\"\n",
+ " print(\"\\n--- Updating Inventory ---\")\n",
+ " \n",
+ " # 1. Decrement quantities for ordered products\n",
+ " for product in customer_orders:\n",
+ " if product in inventory and inventory[product] > 0:\n",
+ " inventory[product] -= 1\n",
+ " print(f\"Inventory reduced for '{product}'. New quantity: {inventory[product]}\")\n",
+ " elif product in inventory and inventory[product] == 0:\n",
+ " print(f\"Warning: '{product}' was ordered but is out of stock.\")\n",
+ " \n",
+ " # 2. Dictionary Comprehension to filter out zero-quantity items\n",
+ " updated_inventory = {\n",
+ " product: quantity\n",
+ " for product, quantity in inventory.items() \n",
+ " if quantity > 0\n",
+ " }\n",
+ " \n",
+ " return updated_inventory\n",
+ "\n",
+ "def print_updated_inventory(inventory):\n",
+ " \"\"\"Prints the final state of the inventory dictionary.\"\"\"\n",
+ " print(\"\\n--- Final Updated Inventory ---\")\n",
+ " for product, quantity in inventory.items():\n",
+ " print(f\"**{product}**: {quantity}\")\n",
+ "\n",
+ "## 2. Order Management Functions with Error Handling\n",
+ "\n",
+ "def get_customer_orders(inventory):\n",
+ " \"\"\"\n",
+ " Gathers product names, validating the number of orders and \n",
+ " product names (checking stock and existence).\n",
+ " \n",
+ " :param inventory: The dictionary of current stock levels.\n",
+ " :return: A set of unique product names ordered by the customer.\n",
+ " \"\"\"\n",
+ " customer_orders = set()\n",
+ " print(\"\\n--- Customer Order Entry ---\")\n",
+ " \n",
+ " # 1. Validation for number of orders\n",
+ " while True:\n",
+ " try:\n",
+ " num_orders_input = input(\"Enter the number of unique products to order: \")\n",
+ " num_orders = int(num_orders_input)\n",
+ " \n",
+ " if num_orders >= 0:\n",
+ " break\n",
+ " else:\n",
+ " print(\"Error: Number of orders cannot be negative.\")\n",
+ " except ValueError:\n",
+ " print(\"Error: Invalid input. Please enter a whole number for the number of orders.\")\n",
+ "\n",
+ " # 2. Loop to collect unique orders with product validation\n",
+ " i = 0\n",
+ " while i < num_orders:\n",
+ " product_name = input(f\"Enter the name of product #{i+1} to order: \").strip()\n",
+ " \n",
+ " # Error Check 1: Product must exist in inventory keys\n",
+ " if product_name not in inventory:\n",
+ " print(f\"Error: Product '{product_name}' not found in the inventory.\")\n",
+ " continue \n",
+ " \n",
+ " # Error Check 2: Product must have stock available\n",
+ " if inventory[product_name] <= 0:\n",
+ " print(f\"Error: '{product_name}' is currently out of stock.\")\n",
+ " continue\n",
+ " \n",
+ " # If valid and in stock, add to the set\n",
+ " if product_name not in customer_orders:\n",
+ " customer_orders.add(product_name)\n",
+ " print(f\"'{product_name}' added to the order set.\")\n",
+ " else:\n",
+ " print(f\"Note: '{product_name}' is already in the order. Skipping duplicate.\")\n",
+ " \n",
+ " i += 1 # Only increment counter after a valid, unique product is added\n",
+ " \n",
+ " return customer_orders\n",
+ "\n",
+ "def calculate_order_total_price(customer_orders):\n",
+ " \"\"\"\n",
+ " Prompts the user for the price of each ordered product, including error \n",
+ " handling to ensure the price is a non-negative number.\n",
+ " \n",
+ " :param customer_orders: The set of unique products ordered.\n",
+ " :return: The total cost of the order (float).\n",
+ " \"\"\"\n",
+ " print(\"\\n--- Calculating Total Price ---\")\n",
+ " total_price = 0.0\n",
+ " \n",
+ " for product in customer_orders:\n",
+ " valid_price = False\n",
+ " while not valid_price:\n",
+ " try:\n",
+ " price_input = input(f\"Enter the price of '{product}': \")\n",
+ " price = float(price_input)\n",
+ " \n",
+ " # Check for non-negative value\n",
+ " if price >= 0:\n",
+ " total_price += price\n",
+ " valid_price = True\n",
+ " else:\n",
+ " raise ValueError(\"Price cannot be negative.\")\n",
+ " except ValueError as e:\n",
+ " # Handle conversion errors or the raised ValueError\n",
+ " print(f\"Error: Invalid input. {e}. Please enter a positive numeric value for the price.\")\n",
+ " \n",
+ " return total_price\n",
+ "\n",
+ "## 3. Statistics Functions \n",
+ "\n",
+ "def calculate_order_statistics(customer_orders, products):\n",
+ " \"\"\"Calculates order statistics.\"\"\"\n",
+ " total_products_ordered = len(customer_orders)\n",
+ " total_available_products = len(products)\n",
+ " \n",
+ " if total_available_products > 0:\n",
+ " percentage_ordered = (total_products_ordered / total_available_products) * 100\n",
+ " else:\n",
+ " percentage_ordered = 0.0\n",
+ " \n",
+ " return total_products_ordered, percentage_ordered\n",
+ "\n",
+ "def print_order_statistics(order_statistics):\n",
+ " \"\"\"Prints the calculated order statistics.\"\"\"\n",
+ " total_ordered, percentage = order_statistics\n",
+ " \n",
+ " print(\"\\n--- Order Statistics ---\")\n",
+ " print(f\"Total Products Ordered: {total_ordered}\")\n",
+ " print(f\"Percentage of Unique Products Ordered: {percentage:.1f}%\")\n",
+ "\n",
+ "## --- Main Program Execution ---\n",
+ "\n",
+ "# 1. Initialize Inventory (uses error handling)\n",
+ "# Example of valid products: Laptop, Mouse, Keyboard, Monitor, Webcam\n",
+ "inventory_data = initialize_inventory(AVAILABLE_PRODUCTS)\n",
+ "\n",
+ "# 2. Get Customer Orders (uses error handling and inventory check)\n",
+ "orders_set = get_customer_orders(inventory_data)\n",
+ "\n",
+ "# 3. Calculate Statistics\n",
+ "stats = calculate_order_statistics(orders_set, AVAILABLE_PRODUCTS)\n",
+ "print_order_statistics(stats)\n",
+ "\n",
+ "# 4. Update Inventory (uses comprehension to filter out zero stock)\n",
+ "final_inventory = update_inventory(orders_set, inventory_data)\n",
+ "# Note: inventory_data is modified in place, but the zero-stock items\n",
+ "# are filtered into the final_inventory dictionary for printing.\n",
+ "print_updated_inventory(final_inventory)\n",
+ "\n",
+ "# 5. Calculate and Print Total Price (uses error handling)\n",
+ "total_cost = calculate_order_total_price(orders_set)\n",
+ "print(f\"\\nTotal Price: **{total_cost:.2f}**\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "07870ae6-2abd-4475-8577-2537bf3dc2c9",
+ "metadata": {},
+ "outputs": [],
+ "source": []
}
],
"metadata": {
"kernelspec": {
- "display_name": "Python 3 (ipykernel)",
+ "display_name": "Python [conda env:base] *",
"language": "python",
- "name": "python3"
+ "name": "conda-base-py"
},
"language_info": {
"codemirror_mode": {
@@ -90,7 +405,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.9.13"
+ "version": "3.13.5"
}
},
"nbformat": 4,
diff --git a/lab-python-list-comprehension.ipynb b/lab-python-list-comprehension.ipynb
new file mode 100644
index 0000000..39856c6
--- /dev/null
+++ b/lab-python-list-comprehension.ipynb
@@ -0,0 +1,358 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "25d7736c-ba17-4aff-b6bb-66eba20fbf4e",
+ "metadata": {},
+ "source": [
+ "# Lab | List, Dict and Set Comprehension"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7dd3cbde-675a-4b81-92c3-f728846dbe06",
+ "metadata": {},
+ "source": [
+ "## Exercise: Managing Customer Orders Optimized with Comprehension"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7db6a154-4bbb-439c-9404-5820a799c0af",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5d500160-2fb7-4777-b5e4-09d45ebaf328",
+ "metadata": {},
+ "source": [
+ "In the previous exercise, you developed a program to manage customer orders and inventory. Now, let's take it a step further and incorporate comprehension into your code.\n",
+ "\n",
+ "Follow the steps below to complete the exercise:\n",
+ "\n",
+ "1. Review your code from the previous exercise and identify areas where you can apply comprehension to simplify and streamline your code. \n",
+ "\n",
+ " - *Hint: Apply it to initialize inventory, updating the inventory and printing the updated inventory.*\n",
+ " \n",
+ " - For example, in initializing the inventory, we could have:\n",
+ " \n",
+ " ```python\n",
+ " def initialize_inventory(products):\n",
+ " inventory = {product: int(input(f\"Enter the quantity of {product}s available: \")) for product in products}\n",
+ " return inventory\n",
+ "\n",
+ " ```\n",
+ "
\n",
+ " \n",
+ " \n",
+ "2. Modify the function get_customer_orders so it prompts the user to enter the number of customer orders and gathers the product names using a loop and user input. Use comprehension.\n",
+ "\n",
+ "3. Add a new function to calculate the total price of the customer order. For each product in customer_orders, prompt the user to enter the price of that product. Use comprehension to calculate the total price. Note: assume that the user can only have 1 unit of each product.\n",
+ "\n",
+ "4. Modify the update_inventory function to remove the product from the inventory if its quantity becomes zero after fulfilling the customer orders. Use comprehension to filter out the products with a quantity of zero from the inventory.\n",
+ "\n",
+ "5. Print the total price of the customer order.\n",
+ "\n",
+ "Your code should produce output similar to the following:\n",
+ "\n",
+ "```python\n",
+ "Enter the quantity of t-shirts available: 5\n",
+ "Enter the quantity of mugs available: 4\n",
+ "Enter the quantity of hats available: 3\n",
+ "Enter the quantity of books available: 2\n",
+ "Enter the quantity of keychains available: 1\n",
+ "Enter the number of customer orders: 2\n",
+ "Enter the name of a product that a customer wants to order: hat\n",
+ "Enter the name of a product that a customer wants to order: keychain\n",
+ "\n",
+ "Order Statistics:\n",
+ "Total Products Ordered: 2\n",
+ "Percentage of Unique Products Ordered: 40.0\n",
+ "\n",
+ "Updated Inventory:\n",
+ "t-shirt: 5\n",
+ "mug: 4\n",
+ "hat: 2\n",
+ "book: 2\n",
+ "Enter the price of keychain: 5\n",
+ "Enter the price of hat: 10\n",
+ "Total Price: 15.0\n",
+ "\n",
+ "```\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "9a63bcdf-0ac3-4e5b-912b-ffab6f423f03",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "--- Inventory Initialization ---\n"
+ ]
+ },
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Enter the quantity of 'Laptop' available: 6\n",
+ "Enter the quantity of 'Mouse' available: 5\n",
+ "Enter the quantity of 'Keyboard' available: 6\n",
+ "Enter the quantity of 'Monitor' available: 7\n",
+ "Enter the quantity of 'Webcam' available: 8\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "--- Customer Order Entry ---\n"
+ ]
+ },
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Enter the number of unique products to order: 4\n",
+ "Enter the name of product #1 to order: Laptop\n",
+ "Enter the name of product #2 to order: Webcam\n",
+ "Enter the name of product #3 to order: Monitor\n",
+ "Enter the name of product #4 to order: Keyboard\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "--- Order Statistics ---\n",
+ "Total Products Ordered: 4\n",
+ "Percentage of Unique Products Ordered: 80.0%\n",
+ "\n",
+ "--- Updating Inventory ---\n",
+ "Inventory reduced for 'Monitor'. New quantity: 6\n",
+ "Inventory reduced for 'Webcam'. New quantity: 7\n",
+ "Inventory reduced for 'Keyboard'. New quantity: 5\n",
+ "Inventory reduced for 'Laptop'. New quantity: 5\n",
+ "\n",
+ "--- Final Updated Inventory ---\n",
+ "**Laptop**: 5\n",
+ "**Mouse**: 5\n",
+ "**Keyboard**: 5\n",
+ "**Monitor**: 6\n",
+ "**Webcam**: 7\n",
+ "\n",
+ "--- Calculating Total Price ---\n"
+ ]
+ },
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Enter the price of 'Monitor': 150\n",
+ "Enter the price of 'Webcam': 50\n",
+ "Enter the price of 'Keyboard': 40\n",
+ "Enter the price of 'Laptop': 600\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Total Price: **840.00**\n"
+ ]
+ }
+ ],
+ "source": [
+ "import math\n",
+ "\n",
+ "# Initial list of available product names\n",
+ "AVAILABLE_PRODUCTS = [\"Laptop\", \"Mouse\", \"Keyboard\", \"Monitor\", \"Webcam\"]\n",
+ "\n",
+ "## 1. Inventory Management Functions with Comprehension\n",
+ "\n",
+ "def initialize_inventory(products):\n",
+ " \"\"\"\n",
+ " Initializes the inventory using a DICTIONARY COMPREHENSION \n",
+ " and user input for initial quantities.\n",
+ " \"\"\"\n",
+ " print(\"\\n--- Inventory Initialization ---\")\n",
+ " \n",
+ " # Dictionary Comprehension for initialization\n",
+ " inventory = {\n",
+ " product: int(input(f\"Enter the quantity of '{product}' available: \")) \n",
+ " for product in products\n",
+ " }\n",
+ " return inventory\n",
+ "\n",
+ "def update_inventory(customer_orders, inventory):\n",
+ " \"\"\"\n",
+ " Updates the inventory based on customer orders and uses a DICTIONARY \n",
+ " COMPREHENSION to filter out products with zero quantity.\n",
+ " \"\"\"\n",
+ " print(\"\\n--- Updating Inventory ---\")\n",
+ " \n",
+ " # 1. Decrement quantities for ordered products\n",
+ " for product in customer_orders:\n",
+ " if product in inventory and inventory[product] > 0:\n",
+ " inventory[product] -= 1\n",
+ " print(f\"Inventory reduced for '{product}'. New quantity: {inventory[product]}\")\n",
+ " elif product in inventory and inventory[product] == 0:\n",
+ " print(f\"Warning: '{product}' was ordered but is out of stock.\")\n",
+ " \n",
+ " # 2. Dictionary Comprehension to filter out zero-quantity items\n",
+ " # This creates a NEW dictionary, effectively removing items with quantity <= 0\n",
+ " updated_inventory = {\n",
+ " product: quantity\n",
+ " for product, quantity in inventory.items() \n",
+ " if quantity > 0\n",
+ " }\n",
+ " \n",
+ " return updated_inventory\n",
+ "\n",
+ "def print_updated_inventory(inventory):\n",
+ " \"\"\"\n",
+ " Prints the final state of the inventory dictionary, only showing items \n",
+ " with positive stock. Uses a concise loop for clean output.\n",
+ " \"\"\"\n",
+ " print(\"\\n--- Final Updated Inventory ---\")\n",
+ " for product, quantity in inventory.items():\n",
+ " print(f\"**{product}**: {quantity}\")\n",
+ "\n",
+ "## 2. Order Management Functions\n",
+ "\n",
+ "def get_customer_orders():\n",
+ " \"\"\"\n",
+ " Prompts the user for the number of orders and gathers product names \n",
+ " using a list/set comprehension-style approach with user input.\n",
+ " \n",
+ " Note: Since the input function must be called inside the loop's \n",
+ " context, we use a standard loop to collect names, and then convert \n",
+ " to a set for uniqueness.\n",
+ " \"\"\"\n",
+ " print(\"\\n--- Customer Order Entry ---\")\n",
+ " \n",
+ " while True:\n",
+ " try:\n",
+ " num_orders = int(input(\"Enter the number of unique products to order: \"))\n",
+ " if num_orders >= 0:\n",
+ " break\n",
+ " else:\n",
+ " print(\"Please enter a non-negative number.\")\n",
+ " except ValueError:\n",
+ " print(\"Invalid input. Please enter a whole number.\")\n",
+ "\n",
+ " # Standard loop to collect input, then a SET to ensure unique products\n",
+ " ordered_products = set()\n",
+ " for i in range(num_orders):\n",
+ " product_name = input(f\"Enter the name of product #{i+1} to order: \").strip()\n",
+ " ordered_products.add(product_name)\n",
+ " \n",
+ " # Note: If we were gathering *quantities* with a comprehension, \n",
+ " # the syntax would be cleaner, but here, the input() call must be inside \n",
+ " # the loop, which makes a standard approach clearer for sequential inputs.\n",
+ " \n",
+ " # Return the set of unique orders\n",
+ " return ordered_products\n",
+ "\n",
+ "def calculate_order_total_price(customer_orders):\n",
+ " \"\"\"\n",
+ " Prompts the user for the price of each ordered product and calculates \n",
+ " the total using a GENERATOR EXPRESSION inside the sum() function.\n",
+ " \n",
+ " :param customer_orders: The set of unique products ordered.\n",
+ " :return: The total cost of the order (float).\n",
+ " \"\"\"\n",
+ " print(\"\\n--- Calculating Total Price ---\")\n",
+ " \n",
+ " # Generator Expression for calculating the sum of prices\n",
+ " total_price = sum(\n",
+ " float(input(f\"Enter the price of '{product}': \"))\n",
+ " for product in customer_orders\n",
+ " )\n",
+ " \n",
+ " return total_price\n",
+ "\n",
+ "## 3. Statistics Functions (From previous exercise, kept for completeness)\n",
+ "\n",
+ "def calculate_order_statistics(customer_orders, products):\n",
+ " \"\"\"Calculates order statistics.\"\"\"\n",
+ " total_products_ordered = len(customer_orders)\n",
+ " total_available_products = len(products)\n",
+ " \n",
+ " if total_available_products > 0:\n",
+ " percentage_ordered = (total_products_ordered / total_available_products) * 100\n",
+ " else:\n",
+ " percentage_ordered = 0.0\n",
+ " \n",
+ " return total_products_ordered, percentage_ordered\n",
+ "\n",
+ "def print_order_statistics(order_statistics):\n",
+ " \"\"\"Prints the calculated order statistics.\"\"\"\n",
+ " total_ordered, percentage = order_statistics\n",
+ " \n",
+ " print(\"\\n--- Order Statistics ---\")\n",
+ " print(f\"Total Products Ordered: {total_ordered}\")\n",
+ " print(f\"Percentage of Unique Products Ordered: {percentage:.1f}%\")\n",
+ "\n",
+ "## --- Main Program Execution ---\n",
+ "\n",
+ "# 1. Initialize Inventory (uses comprehension)\n",
+ "inventory_data = initialize_inventory(AVAILABLE_PRODUCTS)\n",
+ "\n",
+ "# 2. Get Customer Orders (uses loop/set for unique product names)\n",
+ "orders_set = get_customer_orders()\n",
+ "\n",
+ "# 3. Calculate Statistics\n",
+ "stats = calculate_order_statistics(orders_set, AVAILABLE_PRODUCTS)\n",
+ "print_order_statistics(stats)\n",
+ "\n",
+ "# 4. Update Inventory (uses comprehension to filter out zero stock)\n",
+ "final_inventory = update_inventory(orders_set, inventory_data)\n",
+ "print_updated_inventory(final_inventory)\n",
+ "\n",
+ "# 5. Calculate and Print Total Price (uses generator expression)\n",
+ "total_cost = calculate_order_total_price(orders_set)\n",
+ "print(f\"\\nTotal Price: **{total_cost:.2f}**\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "800ef206-78ed-4fed-8cae-71648dd61906",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python [conda env:base] *",
+ "language": "python",
+ "name": "conda-base-py"
+ },
+ "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
+}