Skip to content

Commit 745b082

Browse files
committed
add handle exceptions exercises
1 parent b5c5589 commit 745b082

File tree

14 files changed

+351
-0
lines changed

14 files changed

+351
-0
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
### [Iterative statements 🔃](https://colab.research.google.com/github/armincano/fullstack-python-web-dev/blob/main/m3-python-101/iterative_statements_notebook.ipynb)
2424

25+
### [Handling exceptions 💥🤯](https://colab.research.google.com/github/armincano/fullstack-python-web-dev/blob/main/m3-python-101/handling_exceptions.ipynb)
26+
2527
### [Libraries 📚](https://colab.research.google.com/github/armincano/fullstack-python-web-dev/blob/main/m3-python-101/libraries_notebook.ipynb)
2628

2729
## Module 02: Front-end 101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
with open('file.txt', 'w') as file:
2+
file.write('Hello, World!')
+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"## Handling exceptions 💥🤯"
8+
]
9+
},
10+
{
11+
"cell_type": "markdown",
12+
"metadata": {},
13+
"source": [
14+
"### Custom exception, and `ValueError` for an input\n",
15+
"1. Design a new user-defined exception class.\n",
16+
"\n",
17+
"2. This class should handle the input value of a variable called salary.\n",
18+
"\n",
19+
"3. Ensure that the salary value is between 1000 and 2000.\n",
20+
"\n",
21+
"4. If the salary value is not within this range, raise an exception.\n",
22+
"\n",
23+
"5. The exception should indicate that the salary is not within the range of 1000 to 2000."
24+
]
25+
},
26+
{
27+
"cell_type": "code",
28+
"execution_count": 1,
29+
"metadata": {},
30+
"outputs": [
31+
{
32+
"name": "stdout",
33+
"output_type": "stream",
34+
"text": [
35+
"The salary is 1000\n"
36+
]
37+
}
38+
],
39+
"source": [
40+
"class SalaryNotInRange(Exception):\n",
41+
" def __init__(self, message=\"The salary must be between 1000 and 2000\"):\n",
42+
" self.__message = message\n",
43+
" super().__init__(self.__message)\n",
44+
" \n",
45+
"salary = None\n",
46+
"while True:\n",
47+
" try:\n",
48+
" input_salary = int(input(\"Enter a salary: \"))\n",
49+
" if input_salary not in range(1000,2001):\n",
50+
" raise SalaryNotInRange\n",
51+
" salary = input_salary\n",
52+
" break\n",
53+
" except SalaryNotInRange as e:\n",
54+
" print(e)\n",
55+
" except ValueError:\n",
56+
" print(\"The input salary must be an integer.\")\n",
57+
"print(f\"The salary is {salary}\")"
58+
]
59+
},
60+
{
61+
"cell_type": "markdown",
62+
"metadata": {},
63+
"source": [
64+
"### A virtual cart"
65+
]
66+
},
67+
{
68+
"cell_type": "markdown",
69+
"metadata": {},
70+
"source": []
71+
}
72+
],
73+
"metadata": {
74+
"kernelspec": {
75+
"display_name": "Python 3",
76+
"language": "python",
77+
"name": "python3"
78+
},
79+
"language_info": {
80+
"codemirror_mode": {
81+
"name": "ipython",
82+
"version": 3
83+
},
84+
"file_extension": ".py",
85+
"mimetype": "text/x-python",
86+
"name": "python",
87+
"nbconvert_exporter": "python",
88+
"pygments_lexer": "ipython3",
89+
"version": "3.9.6"
90+
}
91+
},
92+
"nbformat": 4,
93+
"nbformat_minor": 2
94+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
"""
2+
1. Design a new user-defined exception class.
3+
2. This class should handle the input value of a variable called salary.
4+
3. Ensure that the salary value is between 1000 and 2000.
5+
4. If the salary value is not within this range, raise an exception.
6+
5. The exception should indicate that the salary is not within the range of 1000 to 2000.
7+
"""
8+
class SalaryNotInRange(Exception):
9+
def __init__(self, message="The salary must be between 1000 and 2000"):
10+
self.__message = message
11+
super().__init__(self.__message)
12+
13+
salary = None
14+
while True:
15+
try:
16+
input_salary = int(input("Enter a salary: "))
17+
if input_salary not in range(1000,2001):
18+
raise SalaryNotInRange
19+
salary = input_salary
20+
break
21+
except SalaryNotInRange as e:
22+
print(e)
23+
except ValueError:
24+
print("The input salary must be an integer.")
25+
print(f"The salary is {salary}")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
usuarios = {'001': 'Marca', '002': 'Mónica', '003': 'Jacob'}
2+
id_usuario = '004'
3+
try:
4+
print(usuarios[id_usuario])
5+
except KeyError as e:
6+
print(f"La clave {id_usuario} no está en el diccionario. Añadiendo clave...")
7+
usuarios[id_usuario] = "Ninguno"
8+
print(usuarios)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
user_age = None
2+
while True:
3+
input_age = input("Write your age: ")
4+
try:
5+
user_age = int(input_age)
6+
break
7+
except ValueError:
8+
print("The input age must be a number. Please try again.")
9+
10+
is_adult = "You are an Adult" if user_age >= 18 else "You are not an Adult."
11+
print(is_adult)
12+
"""
13+
1. Design a Python program that asks the user for their age via the console.
14+
2. The user must enter an integer; otherwise, the program will throw an exception and ask the user to enter their age again.
15+
3. Next, the program should print "Adult" if the age is 18 or older; otherwise, it should print "Not an adult."
16+
"""
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
suma = 3000
2+
contador = 0
3+
try:
4+
if contador == 0:
5+
raise ZeroDivisionError("División por cero.")
6+
division = suma / contador
7+
print(division)
8+
except ZeroDivisionError as e:
9+
print(e)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from product import Product
2+
3+
zara_for_him_100ml= Product("for him",25990,12)
4+
zara_for_him_black_edition_100ml= Product("for him black edition",25990,7)
5+
zara_for_him_red_edition_100ml= Product("for him red edition",25990,1)
6+
db={}
7+
db.update({zara_for_him_100ml.name:zara_for_him_100ml})
8+
db.update({zara_for_him_black_edition_100ml.name:zara_for_him_black_edition_100ml})
9+
db.update({zara_for_him_red_edition_100ml.name:zara_for_him_red_edition_100ml})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from virtualcart import VirtualCart
2+
from db import db
3+
4+
def main():
5+
cart = VirtualCart()
6+
cart.add_product("FOR HiiiM", 1)
7+
cart.add_product("FOR HiM", 101)
8+
cart.add_product("for him", -1)
9+
# print(db["for him"].stock)
10+
print("\nadd a 'for him' to the cart with quantity of 1 ↓")
11+
cart.add_product("for him", 1)
12+
print("show the products from the cart ↓")
13+
cart.show_cart()
14+
# print(db["for him"].stock)
15+
print("\nadd a 'for him' to the cart with quantity of 1 ↓")
16+
cart.add_product("for him", 1)
17+
print("add a 'for him red edition' to the cart with quantity of 1 ↓")
18+
cart.add_product("for him red edition", 1)
19+
print("show the products from the cart ↓")
20+
cart.show_cart()
21+
print("\ncalculate total of the cart ↓")
22+
print(cart.calculate_total())
23+
print("\ndelete 'for him red edition' from the cart ↓")
24+
cart.delete_product("for him red edition")
25+
print("show the products from the cart ↓")
26+
cart.show_cart()
27+
print("\ncalculate total of the cart ↓")
28+
print(cart.calculate_total())
29+
30+
if __name__ == "__main__":
31+
main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
class Product:
2+
def __init__(self, name:str, price:int, stock:int):
3+
self.__name = name
4+
self.__price = price
5+
self.__stock = stock
6+
7+
@property
8+
def name(self):
9+
return self.__name
10+
@name.setter
11+
def name(self, value):
12+
self.__name = value
13+
14+
@property
15+
def price(self):
16+
return self.__price
17+
@price.setter
18+
def price(self, value):
19+
try:
20+
if value < 0:
21+
raise ValueError(f"You entered {value}, but Price cannot be negative")
22+
self.__price = value
23+
except ValueError as error:
24+
print(error)
25+
26+
@property
27+
def stock(self):
28+
return self.__stock
29+
@stock.setter
30+
def stock(self, value):
31+
try:
32+
if value < 0:
33+
raise ValueError(f"You entered {value}, but Stock cannot be negative")
34+
self.__stock = value
35+
except ValueError as error:
36+
print(error)
37+
38+
""" product_1=Product("Laptop", 1000, 10)
39+
product_1.price = -1
40+
product_1.price = 500
41+
print(product_1.price) """

m3-python-101/virtual-cart-handle-exceptions/utils/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class StockInsufficientError(Exception):
2+
def __init__(self, message="There is no enough stock of"):
3+
self.message = message
4+
super().__init__(message)
5+
6+
class ProductNotFound(Exception):
7+
def __init__(self, message="was not found in the DB."):
8+
self.message = message
9+
super().__init__(message)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import re
2+
def format_currency(amount):
3+
return re.sub(r'(?<!^)(?=(\d{3})+$)', r'.', f"${amount}")
4+
"""
5+
r'(?<!^)(?=(\d{3})+$)'
6+
1. (?<!^)
7+
This is a negative lookbehind assertion.
8+
It ensures that the position is not at the start of the string.
9+
This prevents the regex from matching at the beginning of the string.
10+
11+
2. (?=(\d{3})+$)
12+
This is a positive lookahead assertion.
13+
It checks that the position is followed by one or more groups
14+
of exactly three digits until the end of the string.
15+
16+
3. \d{3}
17+
Matches exactly three digits.
18+
19+
3.1 (\d{3})+
20+
Matches one or more groups of three digits.
21+
22+
4. $
23+
Asserts the position at the end of the string.
24+
25+
In summary, this regex matches positions in the string
26+
where there are groups of three digits to the right,
27+
but not at the start of the string. This is used to insert a period .
28+
as a thousands separator in the currency format.
29+
"""
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
"""
2+
Challenge: Shopping Cart Implementation
3+
Instructions
4+
1. Create a Base Class Product:
5+
1.1 It should have private attributes __name, __price, and __stock_quantity.
6+
1.2 It should have properties name, price, and stock_quantity to get and set the values of these attributes.
7+
1.3 The price property should ensure that the price is not negative.
8+
1.4 The stock_quantity property should ensure that the stock quantity is not negative.
9+
10+
2. Create a Class VirtualCart:
11+
2.1 It should have a private attribute __products which is a dictionary where the key is the product name and the value is an instance of Product.
12+
2.2 It should have a method add_product(product, quantity) that adds a product to the cart.
13+
- If the requested quantity exceeds the stock quantity, it should raise a custom exception InsufficientStockError.
14+
2.3 It should have a method remove_product(product_name) that removes a product from the cart.
15+
2.4 It should have a method calculate_total() that calculates and returns the total cost of the products in the cart.
16+
2.5 It should have a method show_cart() that prints the products in the cart with their quantities and prices.
17+
18+
3. Testing and Verification:
19+
3.1 Create several products, add them to the cart, handle exceptions if you try to add more than what is in stock, calculate the total of the cart, and remove a product."""
20+
from product import Product
21+
from db import db
22+
from utils.customexceptions import StockInsufficientError, ProductNotFound
23+
from utils.integertolocalechile import format_currency
24+
25+
class VirtualCart:
26+
def __init__(self, products={}):
27+
self.__products = products
28+
29+
@property
30+
def products(self):
31+
return self.__products
32+
33+
def add_product(self, raw_product_name: str, quantity: int):
34+
product_name = raw_product_name.lower()
35+
try:
36+
if quantity <= 0:
37+
raise ValueError
38+
if product_name not in db:
39+
raise ProductNotFound
40+
if db[product_name].stock < quantity:
41+
raise StockInsufficientError
42+
43+
if product_name in self.__products:
44+
self.__products[product_name].stock += quantity
45+
else:
46+
product_to_add = {product_name: Product(db[product_name].name, db[product_name].price, quantity)}
47+
self.__products.update(product_to_add)
48+
except ValueError:
49+
print(f"Invalid quantity '{quantity}' for '{product_name}'.")
50+
except ProductNotFound as e:
51+
print(f"'{product_name}' {e}")
52+
except StockInsufficientError as e:
53+
print(f"{e} '{product_name}'.")
54+
55+
def delete_product(self, raw_product_name: str):
56+
product_name = raw_product_name.lower()
57+
if product_name in self.__products:
58+
self.__products.pop(product_name)
59+
print("🗑 Product was deleted from your cart.")
60+
else:
61+
print("There is no product to delete")
62+
63+
def calculate_total(self):
64+
total = 0
65+
for product in self.__products.values():
66+
total += product.price * product.stock
67+
return f"The total of your cart is {format_currency(total)}"
68+
69+
def show_cart(self):
70+
divider_1 = ">>>--->>----------------------------------------"
71+
divider_2 = "----------------------------------------<<---<<<"
72+
if self.__products:
73+
for product in self.__products.values():
74+
print(f"{divider_1}\nName: {product.name}\nPrice: {format_currency(product.price)}\nQuantity: {product.stock}\n{divider_2}")
75+
else:
76+
print("There are no products in your cart")

0 commit comments

Comments
 (0)