├── .gitignore
├── 06_chai_business
├── recipes
│ ├── __init__.py
│ └── flavors.py
├── utils
│ └── discounts.py
└── main.py
├── 11_exceptions
├── order.txt
├── 01_basic.py
├── 02_try_except.py
├── 05_custom_exceptions.py
├── 08_file_handling.py
├── 06_custom_except_two.py
├── 04_multiple_exception.py
├── 03_complex_try.py
└── 07_complete_order.py
├── 01_virtual
└── requirements.txt
├── challenges
├── 02_data_handling
│ ├── command.txt
│ ├── vault.key
│ ├── contacts.csv
│ ├── vault.txt
│ ├── raw_data.csv
│ ├── converted_data.csv
│ ├── flattened_data.json
│ ├── weather_logs.csv
│ ├── nested_data.json
│ ├── movies.json
│ ├── api_data.json
│ ├── converted_data.json
│ ├── notes_vault.json
│ ├── requirements.txt
│ ├── day_7.py
│ ├── day_5.py
│ ├── day_6.py
│ ├── day_8.py
│ ├── day_2.py
│ ├── day_9.py
│ ├── day_4.py
│ ├── day_3.py
│ ├── day_1.py
│ └── day_10.py
├── .DS_Store
├── 01_utilities
│ ├── hitesh_bio.txt
│ ├── tasks.txt
│ ├── learning_journal.txt
│ ├── day_9.py
│ ├── day_11.py
│ ├── day_5.py
│ ├── day_3.py
│ ├── day_6.py
│ ├── day_1.py
│ ├── day_4.py
│ ├── day_8.py
│ ├── day_10.py
│ ├── day_2.py
│ └── day_7.py
├── 04_automation
│ ├── .DS_Store
│ ├── trip_1.jpg
│ ├── trip_2.jpg
│ ├── trip_3.jpg
│ ├── day_04.py
│ ├── day_03.py
│ ├── day_01.py
│ └── day_02.py
├── 03_web_scraping
│ ├── crypto.db
│ ├── test.pdf
│ ├── quotes
│ │ ├── quote_1.png
│ │ ├── quote_2.png
│ │ ├── quote_3.png
│ │ ├── quote_4.png
│ │ └── quote_5.png
│ ├── images
│ │ ├── Soumission.jpg
│ │ ├── Sharp_Objects.jpg
│ │ ├── The_Black_Maria.jpg
│ │ ├── The_Requiem_Red.jpg
│ │ ├── Tipping_the_Velvet.jpg
│ │ ├── A_Light_in_the_Attic.jpg
│ │ ├── Sapiens_A_Brief_History_of_Humankind.jpg
│ │ ├── The_Dirty_Little_Secrets_of_Getting_Your_Dream_Job.jpg
│ │ ├── The_Coming_Woman_A_Novel_Based_on_the_Life_of_the_Infamous_Feminist_Victoria_Woodhull.jpg
│ │ └── The_Boys_in_the_Boat_Nine_Americans_and_Their_Epic_Quest_for_Gold_at_the_1936_Berlin_Olympics.jpg
│ ├── crypto_prices.csv
│ ├── day_10.py
│ ├── day_01.py
│ ├── day_08.py
│ ├── day_02.py
│ ├── day_06.py
│ ├── day_05.py
│ ├── day_04.py
│ ├── day_03.py
│ ├── hn_top20.csv
│ ├── day_07.py
│ ├── day_09.py
│ └── books_data.json
├── 05_data_science
│ ├── .DS_Store
│ ├── day_02.py
│ ├── day_06.py
│ ├── day_09.py
│ ├── day_03.py
│ ├── day_05.py
│ ├── day_07.py
│ ├── day_04.py
│ ├── books.csv
│ ├── day_10.py
│ ├── day_01.ipynb
│ ├── experience_salary.csv
│ ├── day_08.py
│ └── youtube_comments.csv
└── 06_url_shortner
│ ├── .DS_Store
│ ├── database.db
│ ├── __pycache__
│ ├── app.cpython-313.pyc
│ └── models.cpython-313.pyc
│ ├── requirements.txt
│ ├── templates
│ ├── 404.html
│ └── index.html
│ ├── app.py
│ └── models.py
├── .DS_Store
├── 04_loops
├── 02_batch_chai.py
├── 01_token_dispneser.py
├── 03_tea_orders.py
├── 04_tea_menu.py
├── 05_order_summary.py
├── 06_tea-temperature.py
├── 08_for_else.py
├── 07_put_of_order.py
├── 10_dictionary_case.py
└── 09_walrus.py
├── 13_async_python
├── .DS_Store
├── 01_async_one.py
├── 08_non_daemon.py
├── 07_daemon.py
├── 09_race_condition.py
├── 02_async_two.py
├── 06_bgworker.py
├── 05_process_async.py
├── 04_thread_async.py
├── 03_async_three.py
└── 10_deadlock.py
├── 03_conditionals
├── mini_story_1.py
├── delivery_fees_waiver.py
├── snak_suggestion.py
├── smart_thermostat.py
├── chai_price_calculator.py
└── train_seat.py
├── 12_threads_concurrency
├── .DS_Store
├── 11_process_queue.py
├── 08_thread_lock.py
├── 06_thread_two.py
├── 09_process_one.py
├── 12_process_value.py
├── 10_process_two.py
├── 05_thread_one.py
├── 02_multiprocessing.py
├── 03_gil_threading.py
├── 04_gil_multiprocessing.py
├── 01_threading.py
└── 07_thread_download.py
├── 07_comprehensions
├── 04_genrator_compre.py
├── 03_dict_compre.py
├── 01_list_compre.py
└── 02_set_compre.py
├── 02_datatypes
├── chapter_11.py
├── chapter_1.py
├── chapter_2.py
├── chapter_5.py
├── chapter_4.py
├── chapter_7.py
├── chapter_9.py
├── chapter_6.py
├── chapter_3.py
├── chapter_10.py
└── chapter_8.py
├── 05_functions
├── 04_readability.py
├── 01_duplication.py
├── 08_global_scope.py
├── 05_trace.py
├── 07_nonlocal.py
├── 03_hiding.py
├── 02_complex.py
├── 06_scopes.py
├── 11_types_of_functions.py
├── 12_built_in.py
├── 10_return.py
└── 09_input_params.py
├── 10_oop
├── 01_simple_class.py
├── 08_mro.py
├── 09_static_methods.py
├── 04_self_args.py
├── 05_init_objects.py
├── 02_namespace.py
├── 03_attribute_shadowing.py
├── 11_propert_decorators.py
├── 07_base_class.py
├── 06_inheritance_composition.py
└── 10_classmethod.py
├── 14_pydantic
├── 01_basics
│ ├── first_model.py
│ ├── product_model.py
│ ├── field_example.py
│ ├── self_reference.py
│ ├── field_validation.py
│ ├── nested_model.py
│ ├── computed_property.py
│ ├── employee_model.py
│ ├── advance_nested_model.py
│ └── advance_validators.py
└── 02_serialization
│ └── serial.py
├── 08_generators
├── 02_infinite_generators.py
├── 03_send_generators.py
├── 01_basics.py
└── 04_close_generator.py
├── 00_python
├── non_python_code.py
└── non_python_shop.py
├── 09_decorators
├── 01_basics.py
├── 02_logging_decorator.py
└── 03_auth_decorator.py
└── readme.md
/.gitignore:
--------------------------------------------------------------------------------
1 | venv/
--------------------------------------------------------------------------------
/06_chai_business/recipes/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/06_chai_business/utils/discounts.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/11_exceptions/order.txt:
--------------------------------------------------------------------------------
1 | ginger tea - 4 cups
--------------------------------------------------------------------------------
/01_virtual/requirements.txt:
--------------------------------------------------------------------------------
1 | requests==2.31.0
2 | flask==3.0.0
--------------------------------------------------------------------------------
/challenges/02_data_handling/command.txt:
--------------------------------------------------------------------------------
1 | source venv/bin/activate
--------------------------------------------------------------------------------
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/.DS_Store
--------------------------------------------------------------------------------
/11_exceptions/01_basic.py:
--------------------------------------------------------------------------------
1 | orders = ["masala", "ginger"]
2 |
3 | print(orders[2])
--------------------------------------------------------------------------------
/challenges/02_data_handling/vault.key:
--------------------------------------------------------------------------------
1 | ZTJ9c_nzh17_OqktDTukqpSabQOUD4VMsG1e5bAuZ3U=
--------------------------------------------------------------------------------
/04_loops/02_batch_chai.py:
--------------------------------------------------------------------------------
1 | for batch in range(1, 5):
2 | print(f"Preparing chai for batch #{batch}")
--------------------------------------------------------------------------------
/04_loops/01_token_dispneser.py:
--------------------------------------------------------------------------------
1 | for token in range(1, 11):
2 | print(f"Serving chai to Token #{token}")
--------------------------------------------------------------------------------
/challenges/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/.DS_Store
--------------------------------------------------------------------------------
/challenges/01_utilities/hitesh_bio.txt:
--------------------------------------------------------------------------------
1 | ✅ hitesh
2 | youtuber🔥
3 | I love to make videos
4 | hitesh.ai🔥
--------------------------------------------------------------------------------
/13_async_python/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/13_async_python/.DS_Store
--------------------------------------------------------------------------------
/03_conditionals/mini_story_1.py:
--------------------------------------------------------------------------------
1 | kettle_boiled = False
2 |
3 | if kettle_boiled:
4 | print("Kellle Done! time to make Chai")
--------------------------------------------------------------------------------
/12_threads_concurrency/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/12_threads_concurrency/.DS_Store
--------------------------------------------------------------------------------
/challenges/04_automation/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/04_automation/.DS_Store
--------------------------------------------------------------------------------
/challenges/03_web_scraping/crypto.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/03_web_scraping/crypto.db
--------------------------------------------------------------------------------
/challenges/03_web_scraping/test.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/03_web_scraping/test.pdf
--------------------------------------------------------------------------------
/challenges/04_automation/trip_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/04_automation/trip_1.jpg
--------------------------------------------------------------------------------
/challenges/04_automation/trip_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/04_automation/trip_2.jpg
--------------------------------------------------------------------------------
/challenges/04_automation/trip_3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/04_automation/trip_3.jpg
--------------------------------------------------------------------------------
/challenges/05_data_science/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/05_data_science/.DS_Store
--------------------------------------------------------------------------------
/challenges/06_url_shortner/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/06_url_shortner/.DS_Store
--------------------------------------------------------------------------------
/04_loops/03_tea_orders.py:
--------------------------------------------------------------------------------
1 | orders = ["hitesh", "Aman", "Becky", "Carlos"]
2 |
3 | for name in orders:
4 | print(f"Order ready for {name}")
--------------------------------------------------------------------------------
/challenges/02_data_handling/contacts.csv:
--------------------------------------------------------------------------------
1 | Name,Phone,Email
2 | hitesh,9898989898,hitesh@tesla.com
3 | rohit,9999888899,rohit@chaicode.com
4 |
--------------------------------------------------------------------------------
/challenges/06_url_shortner/database.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/06_url_shortner/database.db
--------------------------------------------------------------------------------
/challenges/01_utilities/tasks.txt:
--------------------------------------------------------------------------------
1 | learn python.||done
2 | take challenges in python||not_done
3 | learn file || handling in python||not_done
4 |
--------------------------------------------------------------------------------
/04_loops/04_tea_menu.py:
--------------------------------------------------------------------------------
1 | menu = ["Green", "Lemon", "Spiced", "Mint"]
2 |
3 | for idx, item in enumerate(menu, start=1):
4 | print(f"{idx} : {item} chai")
--------------------------------------------------------------------------------
/challenges/02_data_handling/vault.txt:
--------------------------------------------------------------------------------
1 | Z29vZ2xlLmNvbXx8aGl0ZXNoQGdvb2dsZS5jb218fDExMjJ3d3FxZWU=
2 | ZmFjZWJvb2suY29tfHxoaXRlc2hAZmIuY29tfHwzMzIyd3d0dA==
3 |
--------------------------------------------------------------------------------
/challenges/03_web_scraping/quotes/quote_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/03_web_scraping/quotes/quote_1.png
--------------------------------------------------------------------------------
/challenges/03_web_scraping/quotes/quote_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/03_web_scraping/quotes/quote_2.png
--------------------------------------------------------------------------------
/challenges/03_web_scraping/quotes/quote_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/03_web_scraping/quotes/quote_3.png
--------------------------------------------------------------------------------
/challenges/03_web_scraping/quotes/quote_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/03_web_scraping/quotes/quote_4.png
--------------------------------------------------------------------------------
/challenges/03_web_scraping/quotes/quote_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/03_web_scraping/quotes/quote_5.png
--------------------------------------------------------------------------------
/06_chai_business/recipes/flavors.py:
--------------------------------------------------------------------------------
1 | def elachai_chai():
2 | return "Elachai chai is ready"
3 |
4 | def ginger_chai():
5 | return "Ginger chai is ready"
--------------------------------------------------------------------------------
/challenges/03_web_scraping/images/Soumission.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/03_web_scraping/images/Soumission.jpg
--------------------------------------------------------------------------------
/challenges/03_web_scraping/images/Sharp_Objects.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/03_web_scraping/images/Sharp_Objects.jpg
--------------------------------------------------------------------------------
/challenges/03_web_scraping/images/The_Black_Maria.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/03_web_scraping/images/The_Black_Maria.jpg
--------------------------------------------------------------------------------
/challenges/03_web_scraping/images/The_Requiem_Red.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/03_web_scraping/images/The_Requiem_Red.jpg
--------------------------------------------------------------------------------
/07_comprehensions/04_genrator_compre.py:
--------------------------------------------------------------------------------
1 | daily_sales = [5, 10, 12, 7, 3, 8, 9, 15]
2 |
3 | total_cups = sum(sale for sale in daily_sales if sale > 5)
4 |
5 | print(total_cups)
--------------------------------------------------------------------------------
/challenges/03_web_scraping/images/Tipping_the_Velvet.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/03_web_scraping/images/Tipping_the_Velvet.jpg
--------------------------------------------------------------------------------
/challenges/03_web_scraping/images/A_Light_in_the_Attic.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/03_web_scraping/images/A_Light_in_the_Attic.jpg
--------------------------------------------------------------------------------
/challenges/06_url_shortner/__pycache__/app.cpython-313.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/06_url_shortner/__pycache__/app.cpython-313.pyc
--------------------------------------------------------------------------------
/challenges/06_url_shortner/requirements.txt:
--------------------------------------------------------------------------------
1 | blinker==1.9.0
2 | click==8.2.1
3 | Flask==3.1.1
4 | itsdangerous==2.2.0
5 | Jinja2==3.1.6
6 | MarkupSafe==3.0.2
7 | Werkzeug==3.1.3
8 |
--------------------------------------------------------------------------------
/challenges/06_url_shortner/__pycache__/models.cpython-313.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/06_url_shortner/__pycache__/models.cpython-313.pyc
--------------------------------------------------------------------------------
/04_loops/05_order_summary.py:
--------------------------------------------------------------------------------
1 | names = ["Hitesh", "Meera", "Sam", "Ali"]
2 | bills = [50, 70, 100, 55]
3 |
4 | for name, amount in zip(names, bills):
5 | print(f"{name} paid {amount} rupees")
--------------------------------------------------------------------------------
/03_conditionals/delivery_fees_waiver.py:
--------------------------------------------------------------------------------
1 | order_amount = int(input("Enter the order amount: "))
2 |
3 | delivery_fees = 0 if order_amount > 300 else 30
4 |
5 | print(f"Delivery fees is : {delivery_fees}")
--------------------------------------------------------------------------------
/13_async_python/01_async_one.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 |
3 | async def brew_chai():
4 | print("Brwing chai...")
5 | await asyncio.sleep(2)
6 | print("Chai is ready")
7 |
8 | asyncio.run(brew_chai())
--------------------------------------------------------------------------------
/challenges/02_data_handling/raw_data.csv:
--------------------------------------------------------------------------------
1 | id,name,email,location,is_active
2 | 201,Meena,meena@example.com,Pune,True
3 | 202,Rahul,rahul@example.com,Chennai,False
4 | 203,Anu,anu@example.com,Hyderabad,True
5 |
--------------------------------------------------------------------------------
/challenges/03_web_scraping/images/Sapiens_A_Brief_History_of_Humankind.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/03_web_scraping/images/Sapiens_A_Brief_History_of_Humankind.jpg
--------------------------------------------------------------------------------
/06_chai_business/main.py:
--------------------------------------------------------------------------------
1 | # import recipes.flavors
2 |
3 | # print(recipes.flavors.ginger_chai())
4 |
5 |
6 | # from recipes.flavors import elachai_chai, ginger_chai
7 |
8 | # print(ginger_chai())
9 |
10 |
--------------------------------------------------------------------------------
/challenges/02_data_handling/converted_data.csv:
--------------------------------------------------------------------------------
1 | id,name,email,location,is_active
2 | 101,Riya,riya@example.com,Delhi,True
3 | 102,Aman,aman@example.com,Mumbai,False
4 | 103,Neha,neha@example.com,Bangalore,True
5 |
--------------------------------------------------------------------------------
/02_datatypes/chapter_11.py:
--------------------------------------------------------------------------------
1 | import arrow
2 |
3 | brewing_time = arrow.utcnow()
4 | brewing_time.to("Europe/Rome")
5 |
6 | from collections import namedtuple
7 | chaiProfile = namedtuple("chaiProfile", ["flavor", "aroma"])
--------------------------------------------------------------------------------
/02_datatypes/chapter_1.py:
--------------------------------------------------------------------------------
1 | sugar_amount = 2
2 | print(f"Initial sugar: {sugar_amount}")
3 |
4 | sugar_amount = 12
5 | print(f"Second Initial sugar: {sugar_amount}")
6 |
7 | print(f"ID of 2: {id(2)}")
8 | print(f"ID of 12: {id(12)}")
--------------------------------------------------------------------------------
/05_functions/04_readability.py:
--------------------------------------------------------------------------------
1 | def calculate_bill(cups, price_per_cup):
2 | return cups * price_per_cup
3 |
4 |
5 | my_bill = calculate_bill(3, 15)
6 | print(my_bill)
7 |
8 | print("Order for table 2: ", calculate_bill(2, 50))
--------------------------------------------------------------------------------
/05_functions/01_duplication.py:
--------------------------------------------------------------------------------
1 | def print_order(name, chai_type):
2 | print(f"{name} orderded {chai_type} chai!")
3 |
4 |
5 | print_order("Aman", "masala")
6 | print_order("Hitesh", "Ginger")
7 | print_order("Jia", "Tulsi")
8 |
9 |
--------------------------------------------------------------------------------
/04_loops/06_tea-temperature.py:
--------------------------------------------------------------------------------
1 | temperature = 40
2 |
3 | while temperature < 100:
4 | print(f"Current temperature: {temperature}")
5 | # temperature = temperature + 15
6 | temperature += 15
7 |
8 | print("Tea is ready to boil")
--------------------------------------------------------------------------------
/11_exceptions/02_try_except.py:
--------------------------------------------------------------------------------
1 | chai_menu = {"masala": 30, "ginger": 40}
2 |
3 | try:
4 | chai_menu["elaichi"]
5 | except KeyError:
6 | print("The key that you are tying to access does not exists")
7 |
8 |
9 | print("Hello chai code")
--------------------------------------------------------------------------------
/challenges/03_web_scraping/images/The_Dirty_Little_Secrets_of_Getting_Your_Dream_Job.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/03_web_scraping/images/The_Dirty_Little_Secrets_of_Getting_Your_Dream_Job.jpg
--------------------------------------------------------------------------------
/07_comprehensions/03_dict_compre.py:
--------------------------------------------------------------------------------
1 | tea_prices_inr = {
2 | "Masala Chai": 40,
3 | "Green Tea": 50,
4 | "Lemon Tea": 200
5 | }
6 |
7 | tea_prices_usd = {tea:price / 80 for tea, price in tea_prices_inr.items()}
8 | print(tea_prices_usd)
--------------------------------------------------------------------------------
/11_exceptions/05_custom_exceptions.py:
--------------------------------------------------------------------------------
1 | def brew_chai(flavor):
2 | if flavor not in ["masala", "ginger", "elaichai"]:
3 | raise ValueError("Unsupported chai flavor...")
4 | print(f"brewing {flavor} chai...")
5 |
6 |
7 | brew_chai("mint")
--------------------------------------------------------------------------------
/11_exceptions/08_file_handling.py:
--------------------------------------------------------------------------------
1 | # file = open("order.txt", "w")
2 | # try:
3 | # file.write("Masala chai - 2 cups")
4 | # finally:
5 | # file.close()
6 |
7 |
8 | with open("order.txt", "w") as file:
9 | file.write("ginger tea - 4 cups")
--------------------------------------------------------------------------------
/05_functions/08_global_scope.py:
--------------------------------------------------------------------------------
1 | chai_type = "Plain"
2 |
3 | def front_desk():
4 | def kitchen():
5 | global chai_type
6 | chai_type = "Irnai"
7 | kitchen()
8 |
9 |
10 | front_desk()
11 | print("Final global chai: ", chai_type)
--------------------------------------------------------------------------------
/10_oop/01_simple_class.py:
--------------------------------------------------------------------------------
1 | class Chai:
2 | pass
3 |
4 | class ChaiTime:
5 | pass
6 |
7 | print(type(Chai))
8 |
9 | ginger_tea = Chai()
10 | print(type(ginger_tea))
11 | print(type(ginger_tea) is Chai)
12 | print(type(ginger_tea) is ChaiTime)
--------------------------------------------------------------------------------
/03_conditionals/snak_suggestion.py:
--------------------------------------------------------------------------------
1 | snack = input("Enter your preferred snack: ").lower()
2 |
3 | if snack == "cookies" or snack == "samosa":
4 | print(f"Great Choice! We'll serve you {snack}")
5 | else:
6 | print("Sorry, we only serve cookies or samosa with tea")
--------------------------------------------------------------------------------
/04_loops/08_for_else.py:
--------------------------------------------------------------------------------
1 | staff = [("Amit", 16), ("Zara", 17), ("Raj", 15)]
2 |
3 | for name, age in staff:
4 | if age <= 18:
5 | print(f"{name} is eligible to manage the staff")
6 | break
7 | else:
8 | print(f"No one is eligible to manage the staff")
--------------------------------------------------------------------------------
/07_comprehensions/01_list_compre.py:
--------------------------------------------------------------------------------
1 | menu = [
2 | "Masala Chai",
3 | "Iced Lemon Tea",
4 | "Green Tea",
5 | "Iced Peach Tea",
6 | "Ginger chai"
7 | ]
8 |
9 | iced_tea = [my_tea for my_tea in menu if "Iced" in my_tea]
10 |
11 | print(iced_tea)
--------------------------------------------------------------------------------
/05_functions/05_trace.py:
--------------------------------------------------------------------------------
1 | def add_vat(price, vat_rate):
2 | return price * (100 + vat_rate)/100
3 |
4 |
5 | orders = [100, 150, 200]
6 |
7 | for price in orders:
8 | final_amount = add_vat(price, 10)
9 | print(f"Original: {price}, Final with VAT: {final_amount}")
--------------------------------------------------------------------------------
/10_oop/08_mro.py:
--------------------------------------------------------------------------------
1 | class A:
2 | label = "A: Base class"
3 |
4 | class B(A):
5 | label = "B: Masala blend"
6 |
7 | class C(A):
8 | label = "C: Herbal blend"
9 |
10 | class D(C, B):
11 | pass
12 |
13 | cup = D()
14 | print(cup.label)
15 | print(D.__mro__)
--------------------------------------------------------------------------------
/05_functions/07_nonlocal.py:
--------------------------------------------------------------------------------
1 |
2 | chai_type = "ginger"
3 | def update_order():
4 | chai_type = "Elaichi"
5 | def kitchen():
6 | nonlocal chai_type
7 | chai_type = "Kesar"
8 | kitchen()
9 | print("After kitchen update", chai_type)
10 |
11 | update_order()
--------------------------------------------------------------------------------
/14_pydantic/01_basics/first_model.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel
2 |
3 | class User(BaseModel):
4 | id: int
5 | name: str
6 | is_active: bool
7 |
8 | input_data = {'id': '101a', 'name': "Chaicode", 'is_active': True}
9 |
10 | user = User(**input_data)
11 | print(user)
--------------------------------------------------------------------------------
/10_oop/09_static_methods.py:
--------------------------------------------------------------------------------
1 | class ChaiUtils:
2 | @staticmethod
3 | def clean_ingredients(text):
4 | return [item.strip() for item in text.split(",")]
5 |
6 |
7 | raw = " water , milk , ginger , honey "
8 |
9 | cleaned = ChaiUtils.clean_ingredients(raw)
10 | print(cleaned)
--------------------------------------------------------------------------------
/11_exceptions/06_custom_except_two.py:
--------------------------------------------------------------------------------
1 | class OutOfIngredientsError(Exception):
2 | pass
3 |
4 | def make_chai(milk, sugar):
5 | if milk == 0 or sugar == 0:
6 | raise OutOfIngredientsError("Missing milk or sugar")
7 | print("chai is ready...")
8 |
9 |
10 | make_chai(0, 1)
--------------------------------------------------------------------------------
/challenges/02_data_handling/flattened_data.json:
--------------------------------------------------------------------------------
1 | {
2 | "user.id": 1,
3 | "user.name": "Riya",
4 | "user.email": "riya@example.com",
5 | "user.address.city": "Delhi",
6 | "user.address.pincode": 110001,
7 | "roles.0": "admin",
8 | "roles.1": "editor",
9 | "is_active": true
10 | }
--------------------------------------------------------------------------------
/03_conditionals/smart_thermostat.py:
--------------------------------------------------------------------------------
1 | device_status = "active"
2 | temperature = 38
3 |
4 | if device_status == "active":
5 | if temperature > 35:
6 | print("High temperature alert!")
7 | else:
8 | print("Temperature is normal")
9 | else:
10 | print("Device is offline")
--------------------------------------------------------------------------------
/13_async_python/08_non_daemon.py:
--------------------------------------------------------------------------------
1 | import threading
2 | import time
3 |
4 | def monitor_tea_temp():
5 | while True:
6 | print(f"Monitoring tea temperature...")
7 | time.sleep(2)
8 |
9 | t = threading.Thread(target=monitor_tea_temp)
10 | t.start()
11 |
12 | print("Main program done")
--------------------------------------------------------------------------------
/challenges/02_data_handling/weather_logs.csv:
--------------------------------------------------------------------------------
1 | Date,City,Temperature,Condition
2 | 2025-06-11,Delhi,36.5,Clear
3 | 2025-06-12,Delhi,37.8,Sunny
4 | 2025-06-13,Delhi,38.0,Sunny
5 | 2025-06-14,Delhi,34.2,Rain
6 | 2025-06-15,Delhi,35.0,Clouds
7 | 2025-06-16,Delhi,33.4,Rain
8 | 2025-06-17,Delhi,34.7,Clear
9 |
--------------------------------------------------------------------------------
/challenges/03_web_scraping/images/The_Coming_Woman_A_Novel_Based_on_the_Life_of_the_Infamous_Feminist_Victoria_Woodhull.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/03_web_scraping/images/The_Coming_Woman_A_Novel_Based_on_the_Life_of_the_Infamous_Feminist_Victoria_Woodhull.jpg
--------------------------------------------------------------------------------
/13_async_python/07_daemon.py:
--------------------------------------------------------------------------------
1 | import threading
2 | import time
3 |
4 | def monitor_tea_temp():
5 | while True:
6 | print(f"Monitoring tea temperature...")
7 | time.sleep(2)
8 |
9 | t = threading.Thread(target=monitor_tea_temp, daemon=True)
10 | t.start()
11 |
12 | print("Main program done")
--------------------------------------------------------------------------------
/challenges/02_data_handling/nested_data.json:
--------------------------------------------------------------------------------
1 | {
2 | "user": {
3 | "id": 1,
4 | "name": "Riya",
5 | "email": "riya@example.com",
6 | "address": {
7 | "city": "Delhi",
8 | "pincode": 110001
9 | }
10 | },
11 | "roles": ["admin", "editor"],
12 | "is_active": true
13 | }
14 |
--------------------------------------------------------------------------------
/02_datatypes/chapter_2.py:
--------------------------------------------------------------------------------
1 | spice_mix = set()
2 | print(f"Initial spice mix id: {id(spice_mix)}")
3 | print(f"Initial spice mix id: {spice_mix}")
4 | spice_mix.add("Ginger")
5 | spice_mix.add("cardamom")
6 | spice_mix.add("lemon")
7 | print(f"Initial spice mix id: {spice_mix}")
8 | print(f"After spice mix id: {id(spice_mix)}")
--------------------------------------------------------------------------------
/challenges/03_web_scraping/images/The_Boys_in_the_Boat_Nine_Americans_and_Their_Epic_Quest_for_Gold_at_the_1936_Berlin_Olympics.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hiteshchoudhary/python-udemy/HEAD/challenges/03_web_scraping/images/The_Boys_in_the_Boat_Nine_Americans_and_Their_Epic_Quest_for_Gold_at_the_1936_Berlin_Olympics.jpg
--------------------------------------------------------------------------------
/10_oop/04_self_args.py:
--------------------------------------------------------------------------------
1 | class Chaicup:
2 | size = 150 #ml
3 |
4 | def describe(self):
5 | return f"A {self.size}ml chai cup"
6 |
7 |
8 | cup = Chaicup()
9 | print(cup.describe())
10 | print(Chaicup.describe(cup))
11 |
12 | cup_two = Chaicup()
13 | cup_two.size = 100
14 | print(Chaicup.describe(cup_two))
--------------------------------------------------------------------------------
/02_datatypes/chapter_5.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from fractions import Fraction
3 | from decimal import Decimal
4 |
5 | ideal_temp = 95.5
6 | current_temp = 95.49
7 |
8 | print(f"Ideal temp { ideal_temp }")
9 | print(f"Current temp { current_temp }")
10 | print(f"Difference temp { ideal_temp - current_temp }")
11 | print(sys.float_info)
--------------------------------------------------------------------------------
/08_generators/02_infinite_generators.py:
--------------------------------------------------------------------------------
1 | def infinite_chai():
2 | count = 1
3 | while True:
4 | yield f"Refil #{count}"
5 | count += 1
6 |
7 | refill = infinite_chai()
8 | user2 = infinite_chai()
9 |
10 | for _ in range(5):
11 | print(next(refill))
12 |
13 | for _ in range(6):
14 | print(next(user2))
--------------------------------------------------------------------------------
/03_conditionals/chai_price_calculator.py:
--------------------------------------------------------------------------------
1 | cup = input("Choose your cup size (small/medium/large): ").lower()
2 |
3 | if cup == "small":
4 | print("Price is 10 rupees")
5 | elif cup == "medium":
6 | print("Price is 15 rupees")
7 | elif cup == "large":
8 | print("price is 20 rupees")
9 | else:
10 | print("Unknown cup size")
--------------------------------------------------------------------------------
/challenges/02_data_handling/movies.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "title": "hera pheri",
4 | "genre": "comedy",
5 | "rating": 10.0
6 | },
7 | {
8 | "title": "hera phere 2",
9 | "genre": "comedy",
10 | "rating": 10.0
11 | },
12 | {
13 | "title": "toy story",
14 | "genre": "animation",
15 | "rating": 9.0
16 | }
17 | ]
--------------------------------------------------------------------------------
/challenges/06_url_shortner/templates/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Page not found
7 |
8 |
9 | Page not found - Chaicode
10 |
11 |
12 |
--------------------------------------------------------------------------------
/08_generators/03_send_generators.py:
--------------------------------------------------------------------------------
1 | def chai_customer():
2 | print("Welcome ! What chai would you like ?")
3 | order = yield
4 | while True:
5 | print(f"Preparing: {order}")
6 | order = yield
7 |
8 | stall = chai_customer()
9 | next(stall) # start the generator
10 |
11 | stall.send("Masala Chai")
12 | stall.send("Lemon Chai")
--------------------------------------------------------------------------------
/12_threads_concurrency/11_process_queue.py:
--------------------------------------------------------------------------------
1 | from multiprocessing import Process, Queue
2 |
3 | def prepare_chai(queue):
4 | queue.put("Masala chai is ready")
5 |
6 |
7 |
8 | if __name__ == '__main__':
9 | queue = Queue()
10 |
11 | p = Process(target=prepare_chai, args=(queue,))
12 | p.start()
13 | p.join()
14 | print(queue.get())
--------------------------------------------------------------------------------
/00_python/non_python_code.py:
--------------------------------------------------------------------------------
1 | def make_chai():
2 | if not kettle_has_water():
3 | fill_kettle()
4 | plug_in_kettle()
5 | boil_water()
6 | if not is_cup_clean():
7 | wash_cup()
8 | add_to_cup("tea_leaves")
9 | add_to_cup("sugar")
10 | pour("boiled water")
11 | stie("cup")
12 | serve("chai")
13 |
14 |
15 | make_chai()
--------------------------------------------------------------------------------
/challenges/01_utilities/learning_journal.txt:
--------------------------------------------------------------------------------
1 |
2 | 🗓️ 2025-06-16 - 03:52 AM
3 | I studies about datetime in python
4 | Productivity Rating: 5
5 |
6 | --------------------------------------------------
7 | 🗓️ 2025-06-16 - 03:53 AM
8 | I also went through with files in python
9 | Productivity Rating: 5
10 |
11 | --------------------------------------------------
--------------------------------------------------------------------------------
/04_loops/07_put_of_order.py:
--------------------------------------------------------------------------------
1 | flavours = ["Ginger", "Out of Stock", "Lemon", "Discontinued", "Tulsi"]
2 |
3 |
4 | for flavour in flavours:
5 | if flavour == "Out of Stock":
6 | continue
7 | if flavour == "Discontinued":
8 | print(f"{flavour} item found")
9 | break
10 | print(f"{flavour} item found")
11 |
12 | print(f"Out side of loop")
--------------------------------------------------------------------------------
/13_async_python/09_race_condition.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | chai_stock = 0
4 |
5 | def restock():
6 | global chai_stock
7 | for _ in range(100000):
8 | chai_stock += 1
9 |
10 | threads = [ threading.Thread(target=restock) for _ in range(2)]
11 |
12 | for t in threads: t.start()
13 | for t in threads: t.join()
14 |
15 | print("Chai stock: ", chai_stock)
--------------------------------------------------------------------------------
/02_datatypes/chapter_4.py:
--------------------------------------------------------------------------------
1 | is_boiling = True
2 | stri_count = 5
3 | total_actions = stri_count + is_boiling # upcasting
4 | print(f"Total actions: {total_actions}")
5 |
6 | milk_present = 0 # no milk
7 | print(f"Is there milk? {bool(milk_present)}")
8 |
9 | water_hot = True
10 | tea_added = True
11 |
12 | can_server = water_hot and tea_added
13 | print(f"Can serve chai? {can_server}")
--------------------------------------------------------------------------------
/05_functions/03_hiding.py:
--------------------------------------------------------------------------------
1 | def get_input():
2 | print("Getting user input")
3 |
4 | def validate_input():
5 | print("Validating the user info")
6 |
7 | def save_to_db():
8 | print("saving to database")
9 |
10 | def register_user():
11 | get_input()
12 | validate_input()
13 | save_to_db()
14 | print("User registration complete")
15 |
16 |
17 | register_user()
--------------------------------------------------------------------------------
/10_oop/05_init_objects.py:
--------------------------------------------------------------------------------
1 | class ChaiOrder:
2 |
3 | def __init__(self, type_, size):
4 | self.type = type_
5 | self.size = size
6 |
7 | def summary(self):
8 | return f"{self.size}ml of {self.type} chai"
9 |
10 | order = ChaiOrder("Masala", 200)
11 | print(order.summary())
12 |
13 | order_two = ChaiOrder("Ginger", 220)
14 | print(order_two.summary())
--------------------------------------------------------------------------------
/14_pydantic/01_basics/product_model.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel
2 |
3 | class Product(BaseModel):
4 | id: int
5 | name: str
6 | price: float
7 | in_stock: bool = True
8 |
9 |
10 | product_one = Product(id=1, name="Laptop", price=999.99, in_stock=True)
11 |
12 | product_two = Product(id=2, name="Mouse", price=24.33)
13 |
14 | product_three = Product(name="keyboard")
--------------------------------------------------------------------------------
/00_python/non_python_shop.py:
--------------------------------------------------------------------------------
1 | class Chai:
2 | def __init__(self, sweetness, milk_level):
3 | self.sweetness = sweetness
4 | self.milk_level = milk_level
5 |
6 | def sip(self):
7 | print("Sipping chai")
8 |
9 | def add_sugar(self, amount):
10 | print("added the sugar")
11 |
12 | my_chai = Chai(sweetness=3, milk_level=2)
13 |
14 | my_chai.add_sugar(3)
--------------------------------------------------------------------------------
/09_decorators/01_basics.py:
--------------------------------------------------------------------------------
1 | from functools import wraps
2 | def my_decorator(func):
3 | @wraps(func)
4 | def wrapper():
5 | print("Before function runs")
6 | func()
7 | print("After function runs")
8 | return wrapper
9 |
10 | @my_decorator
11 | def greet():
12 | print("Hello from decorators class from chaicode")
13 |
14 |
15 | greet()
16 | print(greet.__name__)
--------------------------------------------------------------------------------
/13_async_python/02_async_two.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import time
3 | async def brew(name):
4 | print(f"Brewing {name}...")
5 | await asyncio.sleep(3)
6 | # time.sleep(3)
7 | print(f" {name} is ready...")
8 |
9 |
10 | async def main():
11 | await asyncio.gather(
12 | brew("Masala chai"),
13 | brew("Green chai"),
14 | brew("Ginger chai"),
15 | )
16 |
17 | asyncio.run(main())
--------------------------------------------------------------------------------
/05_functions/02_complex.py:
--------------------------------------------------------------------------------
1 | def fetch_sales():
2 | print("Fetching the sales data")
3 |
4 |
5 | def filter_valid_sales():
6 | print("Filtering valid sales data")
7 |
8 | def summarize_data():
9 | print("Summarizing sales data")
10 |
11 |
12 | def generate_report():
13 | fetch_sales()
14 | filter_valid_sales()
15 | summarize_data()
16 | print("Report is ready")
17 |
18 |
19 | generate_report()
--------------------------------------------------------------------------------
/11_exceptions/04_multiple_exception.py:
--------------------------------------------------------------------------------
1 | def process_order(item, quantity):
2 | try:
3 | price = {"masala": 20}[item]
4 | cost = price * quantity
5 | print(f"total cost is {cost}")
6 | except KeyError:
7 | print("Sorry that chai is not on menu")
8 | except TypeError:
9 | print("Quantity must be in number")
10 |
11 | process_order("ginger", 2)
12 | process_order("masala", "two")
--------------------------------------------------------------------------------
/12_threads_concurrency/08_thread_lock.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | counter = 0
4 | lock = threading.Lock()
5 |
6 | def increament():
7 | global counter
8 | for _ in range(100000):
9 | with lock:
10 | counter += 1
11 |
12 | threads = [threading.Thread(target=increament) for _ in range(10)]
13 | [t.start() for t in threads]
14 | [t.join() for t in threads]
15 |
16 | print(f"Final counter: {counter}")
--------------------------------------------------------------------------------
/13_async_python/06_bgworker.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import threading
3 | import time
4 |
5 | def background_worker():
6 | while True:
7 | time.sleep(1)
8 | print(f"Logging the system health 🕰️")
9 |
10 | async def fetch_orders():
11 | await asyncio.sleep(3)
12 | print("🎁 order fetched")
13 |
14 |
15 | threading.Thread(target=background_worker, daemon=True).start()
16 |
17 | asyncio.run(fetch_orders())
--------------------------------------------------------------------------------
/challenges/05_data_science/day_02.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pandas as pd
3 |
4 | np.random.seed(42)
5 |
6 | years = np.random.uniform(0.5, 10, 100).round(2)
7 |
8 | salaries = (30000 + years * 6000 + np.random.normal(0, 4000, size=100) ).round(2)
9 |
10 | df = pd.DataFrame({
11 | "YearsExperience": years,
12 | "Salary": salaries
13 | })
14 | df.to_csv("experience_salary.csv", index=False)
15 | print("Data saved in file ✅")
--------------------------------------------------------------------------------
/10_oop/02_namespace.py:
--------------------------------------------------------------------------------
1 | class Chai:
2 | origin = "India"
3 |
4 | print(Chai.origin)
5 |
6 | Chai.is_hot = True
7 | print(Chai.is_hot)
8 |
9 | # creating objects from class Chai
10 |
11 | masala = Chai()
12 | print(f"Masala {masala.origin}")
13 | print(f"Masala {masala.is_hot}")
14 | masala.is_hot = False
15 |
16 | print("Class: ", Chai.is_hot)
17 | print(f"Masala {masala.is_hot}")
18 | masala.flavor = "Masala"
19 | print(masala.flavor)
--------------------------------------------------------------------------------
/11_exceptions/03_complex_try.py:
--------------------------------------------------------------------------------
1 | def serve_chai(flavor):
2 | try:
3 | print(f"Preparing {flavor} chai...")
4 | if flavor == "unknown":
5 | raise ValueError("We don't know that flavor")
6 | except ValueError as e:
7 | print("Error: ", e)
8 | else:
9 | print(f"{flavor} chai is served")
10 | finally:
11 | print("Next customer please")
12 |
13 | serve_chai("masala")
14 | serve_chai("unknown")
--------------------------------------------------------------------------------
/12_threads_concurrency/06_thread_two.py:
--------------------------------------------------------------------------------
1 | import threading
2 | import time
3 |
4 | def prepare_chai(type_, wait_time ):
5 | print(f"{type_} chai: brewing...")
6 | time.sleep(wait_time)
7 | print(f"{type_} chai: Ready.")
8 |
9 |
10 | t1 = threading.Thread(target=prepare_chai, args=("Masala", 2))
11 | t2 = threading.Thread(target=prepare_chai, args=("Ginger", 3))
12 |
13 | t1.start()
14 | t2.start()
15 | t1.join()
16 | t2.join()
17 |
18 |
19 |
--------------------------------------------------------------------------------
/13_async_python/05_process_async.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | from concurrent.futures import ProcessPoolExecutor
3 |
4 | def encrypt(data):
5 | return f"🔒 {data[::-1]}"
6 |
7 | async def main():
8 | loop = asyncio.get_running_loop()
9 | with ProcessPoolExecutor() as pool:
10 | result = await loop.run_in_executor(pool, encrypt, "credit_card_1234")
11 | print(f"{result}")
12 |
13 | if __name__ == "__main__":
14 | asyncio.run(main())
--------------------------------------------------------------------------------
/12_threads_concurrency/09_process_one.py:
--------------------------------------------------------------------------------
1 | import threading
2 | import time
3 |
4 | def cpu_heavy():
5 | print(f"Crunching some numbers...")
6 | total = 0
7 | for i in range(10**7):
8 | total += i
9 | print("DONE ✅")
10 |
11 | start = time.time()
12 | threads = [threading.Thread(target=cpu_heavy) for _ in range(2)]
13 | [t.start() for t in threads]
14 | [t.join() for t in threads]
15 |
16 | print(f"Time taken: {time.time() - start:.2f} seconds")
--------------------------------------------------------------------------------
/challenges/03_web_scraping/crypto_prices.csv:
--------------------------------------------------------------------------------
1 | timestamp,coin,price
2 | 2025-06-20 01-36-17,bitcoin,104297
3 | 2025-06-20 01-36-17,ethereum,2506.33
4 | 2025-06-20 01-36-17,tether,1.0
5 | 2025-06-20 01-36-17,ripple,2.17
6 | 2025-06-20 01-36-17,binancecoin,642.64
7 | 2025-06-20 01-36-17,solana,145.56
8 | 2025-06-20 01-36-17,usd-coin,0.999827
9 | 2025-06-20 01-36-17,tron,0.274694
10 | 2025-06-20 01-36-17,dogecoin,0.16991
11 | 2025-06-20 01-36-17,staked-ether,2505.81
12 |
--------------------------------------------------------------------------------
/10_oop/03_attribute_shadowing.py:
--------------------------------------------------------------------------------
1 | class Chai:
2 | temperature = "hot"
3 | strength = "Strong"
4 |
5 |
6 | cutting = Chai()
7 | print(cutting.temperature)
8 |
9 | cutting.temperature = "Mild"
10 | cutting.cup = "small"
11 | print("After changing ",cutting.temperature)
12 | print("cup size is ",cutting.cup)
13 | print("Direct look into the class ", Chai.temperature)
14 |
15 | del cutting.temperature
16 | del cutting.cup
17 | print(cutting.temperature)
18 | print(cutting.cup)
--------------------------------------------------------------------------------
/09_decorators/02_logging_decorator.py:
--------------------------------------------------------------------------------
1 | from functools import wraps
2 |
3 | def log_activity(func):
4 | @wraps(func)
5 | def wrapper(*args, **kwargs):
6 | print(f"🚀 Calling: {func.__name__}")
7 | result = func(*args, **kwargs)
8 | print(f"✅ Finished: {func.__name__}")
9 | return result
10 | return wrapper
11 |
12 | @log_activity
13 | def brew_chai(type, milk="no"):
14 | print(f"Brewing {type} chai and milk status {milk}")
15 |
16 | brew_chai("Masala")
--------------------------------------------------------------------------------
/03_conditionals/train_seat.py:
--------------------------------------------------------------------------------
1 | seat_type = input("Enter seat type (sleeper/AC/general/luxury)").lower()
2 |
3 |
4 | match seat_type:
5 | case "sleeper":
6 | print("Sleeper - No AC, beds available")
7 | case "ac":
8 | print("AC - Air conditioned, comfy ride")
9 | case "general":
10 | print("General - Cheapest option, no reservation")
11 | case "luxury":
12 | print("Luxury - Premium seats with meals")
13 | case _:
14 | print("Invalid seat type")
--------------------------------------------------------------------------------
/10_oop/11_propert_decorators.py:
--------------------------------------------------------------------------------
1 | class TeaLeaf:
2 | def __init__(self, age):
3 | self._age = age
4 |
5 | @property
6 | def age(self):
7 | return self._age + 2
8 |
9 | @age.setter
10 | def age(self, age):
11 | if 1 <= age <= 5:
12 | self._age = age
13 | else:
14 | raise ValueError("Tea leaf age must be between 1 and 5 years")
15 |
16 | leaf = TeaLeaf(2)
17 | print(leaf.age)
18 | leaf.age = 6
19 | print(leaf.age)
20 |
--------------------------------------------------------------------------------
/12_threads_concurrency/12_process_value.py:
--------------------------------------------------------------------------------
1 | from multiprocessing import Process, Value
2 |
3 | def increment(counter):
4 | for _ in range(100000):
5 | with counter.get_lock():
6 | counter.value += 1
7 |
8 |
9 | if __name__ == "__main__":
10 | counter = Value('i', 0)
11 | processes = [Process(target=increment, args=(counter, )) for _ in range(4)]
12 | [p.start() for p in processes]
13 | [p.join() for p in processes]
14 |
15 | print("Final counter value: ",counter.value )
--------------------------------------------------------------------------------
/challenges/02_data_handling/api_data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 101,
4 | "name": "Riya",
5 | "email": "riya@example.com",
6 | "location": "Delhi",
7 | "is_active": true
8 | },
9 | {
10 | "id": 102,
11 | "name": "Aman",
12 | "email": "aman@example.com",
13 | "location": "Mumbai",
14 | "is_active": false
15 | },
16 | {
17 | "id": 103,
18 | "name": "Neha",
19 | "email": "neha@example.com",
20 | "location": "Bangalore",
21 | "is_active": true
22 | }
23 | ]
24 |
--------------------------------------------------------------------------------
/09_decorators/03_auth_decorator.py:
--------------------------------------------------------------------------------
1 | from functools import wraps
2 |
3 | def require_admin(func):
4 | @wraps(func)
5 | def wrapper(user_role):
6 | if user_role != "admin":
7 | print("Access denied: Admins only")
8 | return None
9 | else:
10 | return func(user_role)
11 | return wrapper
12 |
13 | @require_admin
14 | def acess_tea_inventory(role):
15 | print("Access granted to tea inventory")
16 |
17 | acess_tea_inventory("user")
18 | acess_tea_inventory("admin")
--------------------------------------------------------------------------------
/13_async_python/04_thread_async.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import time
3 | from concurrent.futures import ThreadPoolExecutor
4 |
5 | def check_stock(item):
6 | print(f"Checking {item} in store...")
7 | time.sleep(3) # Blocking operation
8 | return f"{item} stock: 42"
9 |
10 | async def main():
11 | loop = asyncio.get_running_loop()
12 | with ThreadPoolExecutor() as pool:
13 | result = await loop.run_in_executor(pool, check_stock, "Masala chai")
14 | print(result)
15 |
16 | asyncio.run(main())
--------------------------------------------------------------------------------
/12_threads_concurrency/10_process_two.py:
--------------------------------------------------------------------------------
1 | from multiprocessing import Process
2 | import time
3 |
4 | def cpu_heavy():
5 | print(f"Crunching some numbers...")
6 | total = 0
7 | for i in range(10**9):
8 | total += i
9 | print("DONE ✅")
10 |
11 | if __name__ == "__main__":
12 | start = time.time()
13 | processes = [Process(target=cpu_heavy) for _ in range(2)]
14 | [t.start() for t in processes]
15 | [t.join() for t in processes]
16 |
17 | print(f"Time taken: {time.time() - start:.2f} seconds")
--------------------------------------------------------------------------------
/challenges/02_data_handling/converted_data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "201",
4 | "name": "Meena",
5 | "email": "meena@example.com",
6 | "location": "Pune",
7 | "is_active": "True"
8 | },
9 | {
10 | "id": "202",
11 | "name": "Rahul",
12 | "email": "rahul@example.com",
13 | "location": "Chennai",
14 | "is_active": "False"
15 | },
16 | {
17 | "id": "203",
18 | "name": "Anu",
19 | "email": "anu@example.com",
20 | "location": "Hyderabad",
21 | "is_active": "True"
22 | }
23 | ]
--------------------------------------------------------------------------------
/02_datatypes/chapter_7.py:
--------------------------------------------------------------------------------
1 | masala_spices = ("cardamom", "cloves", "cinnamon")
2 |
3 | (spice1, spice2, spice3) = masala_spices
4 |
5 | print(f"Main masala spices: {spice1}, {spice2}, {spice3}")
6 |
7 | ginger_ratio, cadramom_ratio = 2, 1
8 | print(f"Ratio is G :{ginger_ratio} and C: {cadramom_ratio}")
9 | ginger_ratio, cadramom_ratio = cadramom_ratio, ginger_ratio
10 | print(f"Ratio is G :{ginger_ratio} and C: {cadramom_ratio}")
11 |
12 | # membership testing
13 |
14 | print(f"Is cinnamon in masala spices ? {'cinnamon' in masala_spices}")
--------------------------------------------------------------------------------
/13_async_python/03_async_three.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import aiohttp
3 |
4 | async def fetch_url(session, url):
5 | async with session.get(url) as response:
6 | print(f"Fetched {url} with status {response.status}")
7 |
8 | async def main():
9 | urls = ["https://httpbin.org/delay/2"] * 3
10 | async with aiohttp.ClientSession() as session:
11 | tasks = [fetch_url(session, url) for url in urls]
12 | # tasks = [t1, t2, t3]
13 | await asyncio.gather(*tasks)
14 |
15 |
16 | asyncio.run(main())
--------------------------------------------------------------------------------
/04_loops/10_dictionary_case.py:
--------------------------------------------------------------------------------
1 | users = [
2 | {"id": 1, "total": 100, "coupon": "P20"},
3 | {"id": 2, "total": 150, "coupon": "F10"},
4 | {"id": 3, "total": 80, "coupon": "P50"},
5 | ]
6 |
7 | discounts = {
8 | "P20": (0.2, 0),
9 | "F10": (0.5, 0),
10 | "P50": (0, 10),
11 | }
12 |
13 | for user in users:
14 | percent, fixed = discounts.get(user["coupon"], (0, 0))
15 | discount = user["total"] * percent + fixed
16 | print(f"{user["id"]} paid {user["total"]} and got discount for next visit of rupees {discount}")
--------------------------------------------------------------------------------
/challenges/02_data_handling/notes_vault.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "title": "record udemy",
4 | "content": "gAAAAABoUxoJvsw6ktnaUzGASLZpGMdpm1povoP9a6nX92tmL4GUMc22QEFA1Su3FRwYGOZzRulWigxo859mJItZmZjoTHdSSdc_76lwKY7eXK2mAw1WW_aqwByKptfBrwNj9dfotpT0",
5 | "timestamp": "2025-06-19 01:26:57"
6 | },
7 | {
8 | "title": "youtube video idea",
9 | "content": "gAAAAABoUxpGoh5Z56_IvAVQFEKI28Zg3tF3-eYj-c9wWguXRCELih-91qExYGEu79u6F7sOfbqni7pAdhboOCXfcygtexyhizIygnVMb-QuODzbv97FBg0=",
10 | "timestamp": "2025-06-19 01:27:58"
11 | }
12 | ]
--------------------------------------------------------------------------------
/02_datatypes/chapter_9.py:
--------------------------------------------------------------------------------
1 | essential_spices = {"cardamom", "ginger", "cinnamon"}
2 | optional_spices = {"cloves", "ginger", "black pepper"}
3 |
4 | all_spices = essential_spices | optional_spices
5 | print(f"All spices: {all_spices}")
6 |
7 | common_spices = essential_spices & optional_spices
8 | print(f"common spices: {common_spices}")
9 |
10 | only_in_essential = essential_spices - optional_spices
11 | print(f"Only in essential spices: {only_in_essential}")
12 |
13 | print(f"Is 'cloves' in optional spices? {'cloves' in optional_spices}")
14 |
15 |
--------------------------------------------------------------------------------
/14_pydantic/01_basics/field_example.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel
2 | from typing import List, Dict, Optional
3 |
4 | class Cart(BaseModel):
5 | user_id: int
6 | items: List[str]
7 | quantities: Dict[str, int]
8 |
9 | class BlogPost(BaseModel):
10 | title: str
11 | content: str
12 | image_url: Optional[str] = None
13 |
14 |
15 | cart_data = {
16 | "user_id": 123,
17 | "items": ["Laptop", "Mouse", "Keyboard"],
18 | "quantities": {"laptop": 1, "mouse": 2, "keyboard": 3}
19 | }
20 |
21 | cart = Cart(**cart_data)
--------------------------------------------------------------------------------
/14_pydantic/01_basics/self_reference.py:
--------------------------------------------------------------------------------
1 | from typing import List, Optional
2 | from pydantic import BaseModel
3 |
4 | class Comment(BaseModel):
5 | id: int
6 | content: str
7 | replies: Optional[List['Comment']] = None
8 |
9 | Comment.model_rebuild()
10 |
11 |
12 | comment = Comment(
13 | id= 1,
14 | content="First comment",
15 | replies=[
16 | Comment(id=2, content="reply 1"),
17 | Comment(id=3, content="reply 2", replies=[
18 | Comment(id=4, content="nested reply")
19 | ])
20 | ]
21 | )
--------------------------------------------------------------------------------
/07_comprehensions/02_set_compre.py:
--------------------------------------------------------------------------------
1 | favourite_chais = [
2 | "Masala Chai", "Green Tea", "Masala Chai",
3 | "Lemon Tea", "Green Tea", "Elaichi Chai"
4 | ]
5 |
6 | unique_chai = {chai for chai in favourite_chais }
7 | print(unique_chai)
8 |
9 |
10 | recipes = {
11 | "Masala Chai": ["ginger", "cardamom", "clove"],
12 | "Elaichi Chai": ["cardamom", "milk"],
13 | "Spicy Chai": ["ginger", "black pepper", "clove"],
14 | }
15 |
16 | unique_spices = {spice for ingredients in recipes.values() for spice in ingredients}
17 |
18 | print(unique_spices)
--------------------------------------------------------------------------------
/05_functions/06_scopes.py:
--------------------------------------------------------------------------------
1 | def serve_chai():
2 | chai_type = "Masala" # local scope
3 | print(f"Inside function {chai_type}")
4 |
5 |
6 | chai_type = "Lemon"
7 | serve_chai()
8 | print(f"Outside function: {chai_type}")
9 |
10 |
11 | def chai_counter():
12 | chai_order = "lemon" # Enclosing scope
13 | def print_order():
14 | chai_order = "Ginger"
15 | print("Inner:", chai_order)
16 | print_order()
17 | print("Outer: ", chai_order)
18 |
19 | chai_order = "Tulsi" # Global
20 | chai_counter()
21 | print("Global :", chai_order)
--------------------------------------------------------------------------------
/05_functions/11_types_of_functions.py:
--------------------------------------------------------------------------------
1 | def pure_chai(cups):
2 | return cups * 10
3 |
4 | total_chai = 0
5 |
6 | # not recommended
7 | def impure_chai(cups):
8 | global total_chai
9 | total_chai += cups
10 |
11 |
12 | def pour_chai(n):
13 | print(n)
14 | if n == 0:
15 | return "All cups poured"
16 | return pour_chai(n-1)
17 |
18 | print(pour_chai(3))
19 |
20 |
21 |
22 | chai_types = ["light", "kadak", "ginger", "kadak"]
23 |
24 |
25 | strong_chai = list(filter(lambda chai: chai!="kadak", chai_types))
26 |
27 | print(strong_chai)
--------------------------------------------------------------------------------
/08_generators/01_basics.py:
--------------------------------------------------------------------------------
1 | def serve_chai():
2 | yield "Cup 1: Masala Chai"
3 | yield "Cup 2: Ginger Chai"
4 | yield "Cup 3: Elaichi Chai"
5 |
6 | stall = serve_chai()
7 |
8 | # for cup in stall:
9 | # print(cup)
10 |
11 | def get_chai_list():
12 | return ["Cup 1", "Cup 2", "Cup 3"]
13 |
14 | # generator function
15 | def get_chai_gen():
16 | yield "Cup 1"
17 | yield "Cup 2"
18 | yield "Cup 3"
19 |
20 | chai = get_chai_gen()
21 | print(next(chai))
22 | print(next(chai))
23 | print(next(chai))
24 | # print(next(chai)) # gives error
--------------------------------------------------------------------------------
/13_async_python/10_deadlock.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 | lock_a = threading.Lock()
4 | lock_b = threading.Lock()
5 |
6 |
7 | def task1():
8 | with lock_a:
9 | print("Task 1 acquired lock a")
10 | with lock_b:
11 | print("Task 1 acquired lock b")
12 |
13 | def task2():
14 | with lock_b:
15 | print("Task 2 acquired lock b")
16 | with lock_a:
17 | print("Task 2 acquired lock a")
18 |
19 | t1 = threading.Thread(target=task1)
20 | t2 = threading.Thread(target=task2)
21 |
22 | t1.start()
23 | t2.start()
--------------------------------------------------------------------------------
/challenges/02_data_handling/requirements.txt:
--------------------------------------------------------------------------------
1 | blinker==1.9.0
2 | certifi==2025.6.15
3 | cffi==1.17.1
4 | charset-normalizer==3.4.2
5 | click==8.2.1
6 | contourpy==1.3.2
7 | cryptography==45.0.4
8 | cycler==0.12.1
9 | fonttools==4.58.4
10 | idna==3.10
11 | itsdangerous==2.2.0
12 | Jinja2==3.1.6
13 | kiwisolver==1.4.8
14 | MarkupSafe==3.0.2
15 | matplotlib==3.10.3
16 | numpy==2.3.0
17 | packaging==25.0
18 | pillow==11.2.1
19 | pycparser==2.22
20 | pyparsing==3.2.3
21 | python-dateutil==2.9.0.post0
22 | requests==2.32.4
23 | six==1.17.0
24 | urllib3==2.4.0
25 | Werkzeug==3.1.3
26 |
--------------------------------------------------------------------------------
/12_threads_concurrency/05_thread_one.py:
--------------------------------------------------------------------------------
1 | import threading
2 | import time
3 |
4 | def boil_milk():
5 | print(f"Boiling milk...")
6 | time.sleep(2)
7 | print(f"Milk Boiled...")
8 |
9 | def toast_bun():
10 | print(f"Toasting bun...")
11 | time.sleep(3)
12 | print(f"Done with bun toast...")
13 |
14 | start = time.time()
15 |
16 | t1 = threading.Thread(target=boil_milk)
17 | t2 = threading.Thread(target=toast_bun)
18 |
19 | t1.start()
20 | t2.start()
21 | t1.join()
22 | t2.join()
23 |
24 | end = time.time()
25 |
26 | print(f"Breakfast is ready in {end - start:.2f} seconds")
--------------------------------------------------------------------------------
/challenges/03_web_scraping/day_10.py:
--------------------------------------------------------------------------------
1 | import fitz
2 |
3 | def read_pdf(file_path):
4 | doc = fitz.open(file_path)
5 | all_text = ""
6 |
7 | for page_num in range(len(doc)):
8 | page = doc[page_num]
9 | all_text += page.get_text()
10 |
11 | doc.close()
12 | return all_text
13 |
14 | if __name__ == "__main__":
15 | file_path = "test.pdf"
16 | try:
17 | content =read_pdf(file_path)
18 | print("-" * 30)
19 | print(content)
20 | print("-" * 30)
21 | except Exception as e:
22 | print("Failed to read pdf, change that method")
--------------------------------------------------------------------------------
/02_datatypes/chapter_6.py:
--------------------------------------------------------------------------------
1 | chai_type = "Ginger chai"
2 | customer_name = "Priya"
3 |
4 | print(f"Order for {customer_name} : {chai_type} please !")
5 |
6 | chai_description = "Aromatic and Bold"
7 | print(f"First word: {chai_description[:8]}")
8 | print(f"Last word: {chai_description[12:]}")
9 | print(f"Last word: {chai_description[::-1]}")
10 |
11 | label_text = "Chai Spécial"
12 | ecoded_label = label_text.encode("utf-8")
13 | print(f"Non Encoded label: {label_text}")
14 | print(f"Encoded label: {ecoded_label}")
15 | decoded_label = ecoded_label.decode("utf-8")
16 | print(f"Decoded label: {decoded_label}")
--------------------------------------------------------------------------------
/08_generators/04_close_generator.py:
--------------------------------------------------------------------------------
1 | def local_chai():
2 | yield "Masala Chai"
3 | yield "Ginger Chai"
4 |
5 | def imported_chai():
6 | yield "Matcha"
7 | yield "Oolong"
8 |
9 | def full_menu():
10 | yield from local_chai()
11 | yield from imported_chai()
12 |
13 | for chai in full_menu():
14 | print(chai)
15 |
16 |
17 | def chai_stall():
18 | try:
19 | while True:
20 | order = yield "Waiting for chai order"
21 | except:
22 | print("Stall closed, No more chai")
23 |
24 |
25 | stall = chai_stall()
26 | print(next(stall))
27 | stall.close() #cleanup
--------------------------------------------------------------------------------
/12_threads_concurrency/02_multiprocessing.py:
--------------------------------------------------------------------------------
1 | from multiprocessing import Process
2 | import time
3 |
4 | def brew_chai(name):
5 | print(f"Start of {name} chai brewing")
6 | time.sleep(3)
7 | print(f"End of {name} chai brewing")
8 |
9 | if __name__ == "__main__":
10 | chai_makers = [
11 | Process(target=brew_chai, args=(f"Chai Maker #{i+1}", ))
12 | for i in range(3)
13 | ]
14 |
15 | # Start all process
16 | for p in chai_makers:
17 | p.start()
18 |
19 | # wait for all to complete
20 | for p in chai_makers:
21 | p.join()
22 |
23 | print("All chai served")
--------------------------------------------------------------------------------
/05_functions/12_built_in.py:
--------------------------------------------------------------------------------
1 | def chai_flavor(flavor="masala"):
2 | """Return the flavor of chai."""
3 | chai="ginger"
4 | return flavor
5 |
6 |
7 | print(chai_flavor.__doc__)
8 | print(chai_flavor.__name__)
9 |
10 | help(len)
11 |
12 | def generate_bill(chai=0, samosa=0):
13 | """
14 | Calculate the total bill for chai and samosa
15 |
16 | :param chai: Number of chai cups (10 rupees each)
17 | :param samosa: NUmber of samosa (15 rupees each)
18 | : return: (total amount, thank you message as string)
19 | """
20 | total = chai*10 + samosa*15
21 | return total, "Thank you for visiting chaicode.com"
--------------------------------------------------------------------------------
/12_threads_concurrency/03_gil_threading.py:
--------------------------------------------------------------------------------
1 | import threading
2 | import time
3 |
4 | def brew_chai():
5 | print(f"{threading.current_thread().name} started brewing...")
6 | count = 0
7 | for _ in range(100_000_000):
8 | count += 1
9 | print(f"{threading.current_thread().name} finished brewing...")
10 |
11 | thread1 =threading.Thread(target=brew_chai, name="Barista-1")
12 | thread2 = threading.Thread(target=brew_chai, name="Barista-2")
13 |
14 | start = time.time()
15 | thread1.start()
16 | thread2.start()
17 | thread1.join()
18 | thread2.join()
19 | end = time.time()
20 |
21 | print(f"total time taken: {end - start:.2f} seconds")
--------------------------------------------------------------------------------
/12_threads_concurrency/04_gil_multiprocessing.py:
--------------------------------------------------------------------------------
1 | from multiprocessing import Process
2 | import time
3 |
4 | def crunch_number():
5 | print(f"Started the count process...")
6 | count = 0
7 | for _ in range(100_000_000):
8 | count += 1
9 | print(f"Ended the count process...")
10 |
11 | if __name__ == "__main__":
12 | start = time.time()
13 |
14 | p1 = Process(target=crunch_number)
15 | p2= Process(target=crunch_number)
16 |
17 | p1.start()
18 | p2.start()
19 | p1.join()
20 | p2.join()
21 |
22 | end = time.time()
23 |
24 | print(f"Total time with multi-processing is {end - start:.2f} seconds")
25 |
--------------------------------------------------------------------------------
/12_threads_concurrency/01_threading.py:
--------------------------------------------------------------------------------
1 | import threading
2 | import time
3 |
4 | def take_orders():
5 | for i in range(1, 4):
6 | print(f"Taking order for #{i}")
7 | time.sleep(2)
8 |
9 | def brew_chai():
10 | for i in range(1, 4):
11 | print(f"Brewing chai for #{i}")
12 | time.sleep(3)
13 |
14 | # create threads
15 | order_thread = threading.Thread(target=take_orders)
16 | brew_thread = threading.Thread(target=brew_chai)
17 |
18 | order_thread.start()
19 | brew_thread.start()
20 |
21 | # wait for both to finish
22 | order_thread.join()
23 | brew_thread.join()
24 |
25 | print(f"All orders taken and chai brewed")
--------------------------------------------------------------------------------
/14_pydantic/01_basics/field_validation.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel, field_validator, model_validator
2 |
3 |
4 | class User(BaseModel):
5 | username: str
6 |
7 | @field_validator('username')
8 | def username_length(cls, v):
9 | if len(v) < 4:
10 | raise ValueError("Username must be at least 4 characters")
11 | return v
12 |
13 |
14 | class SignupData(BaseModel):
15 | password: str
16 | confirm_password: str
17 |
18 | @model_validator(mode='after')
19 | def password_match(cls, values):
20 | if values.password != values.confirm_password:
21 | raise ValueError("Password do not match")
22 | return values
--------------------------------------------------------------------------------
/challenges/05_data_science/day_06.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 | from sklearn.pipeline import Pipeline
3 | from sklearn.linear_model import LogisticRegression
4 | from sklearn.feature_extraction.text import TfidfVectorizer
5 | from sklearn.model_selection import train_test_split
6 |
7 |
8 | df = pd.read_csv("youtube_comments.csv")
9 |
10 | X_train, X_test, y_train, y_test = train_test_split(df['comment'], df['label'], test_size=0.2, random_state=42)
11 |
12 | model = Pipeline([
13 | ('tfidf', TfidfVectorizer()),
14 | ('clf', LogisticRegression())
15 | ])
16 |
17 | model.fit(X_train, y_train)
18 |
19 | acc = model.score(X_test, y_test)
20 | print(f"Model tained. Accuracy: {round(acc * 100, 2)}%")
--------------------------------------------------------------------------------
/11_exceptions/07_complete_order.py:
--------------------------------------------------------------------------------
1 | class InvalidChaiError(Exception): pass
2 |
3 | def bill(flavor, cups):
4 | menu = {"masala": 20, "ginger": 40}
5 | try:
6 | if flavor not in menu:
7 | raise InvalidChaiError("that chai is not available")
8 | if not isinstance(cups, int):
9 | raise TypeError("Number of cups must be an integer")
10 | total = menu[flavor] * cups
11 | print(f"Your bill for {cups} cups of {flavor} chai: rupees {total}")
12 | except Exception as e:
13 | print("Error: ", e)
14 | finally:
15 | print("Thank you for visiting chaicode!")
16 |
17 |
18 | bill("mint", 2)
19 | bill("masala", "three")
20 | bill("ginger", 3)
--------------------------------------------------------------------------------
/10_oop/07_base_class.py:
--------------------------------------------------------------------------------
1 | class Chai:
2 | def __init__(self, type_, strength):
3 | self.type = type_
4 | self.strength = strength
5 |
6 |
7 | # class GingerChai(Chai):
8 | # def __init__(self, type_, strength, spice_level):
9 | # self.type = type_
10 | # self.strength = strength
11 | # self.spice_level = spice_level
12 |
13 |
14 | # class GingerChai(Chai):
15 | # def __init__(self, type_, strength, spice_level):
16 | # Chai.__init__(self, type_, strength)
17 | # self.spice_level = spice_level
18 |
19 |
20 | class GingerChai(Chai):
21 | def __init__(self, type_, strength, spice_level):
22 | super().__init__(type_, strength)
23 | self.spice_level = spice_level
--------------------------------------------------------------------------------
/12_threads_concurrency/07_thread_download.py:
--------------------------------------------------------------------------------
1 | import threading
2 | import requests
3 | import time
4 |
5 | def download(url):
6 | print(f"Starting download from {url}")
7 | resp = requests.get(url)
8 | print(f"Finished downloading from {url}, size: {len(resp.content)} bytes")
9 |
10 | urls = [
11 | "https://httpbin.org/image/jpeg",
12 | "https://httpbin.org/image/png",
13 | "https://httpbin.org/image/svg",
14 | ]
15 |
16 | start = time.time()
17 | threads = []
18 |
19 | for url in urls:
20 | t = threading.Thread(target=download, args=(url, ))
21 | t.start()
22 | threads.append(t)
23 |
24 | for t in threads:
25 | t.join()
26 |
27 | end = time.time()
28 |
29 | print(f"All downloads done in {end - start:.2f} seconds")
--------------------------------------------------------------------------------
/05_functions/10_return.py:
--------------------------------------------------------------------------------
1 | # def make_chai():
2 | # # return "Here is your masal chai"
3 | # print("Here is your masala chai")
4 |
5 | # return_value = make_chai()
6 |
7 | # print(return_value)
8 |
9 | def idle_chaiwala():
10 | pass
11 |
12 | print(idle_chaiwala())
13 |
14 | def sold_cups():
15 | return 120
16 |
17 | total = sold_cups()
18 | print(total)
19 |
20 | def chai_status(cups_left):
21 | if cups_left == 0:
22 | return "Sorry, chai over"
23 | return "Chai is ready"
24 | print("chai")
25 |
26 | print(chai_status(0))
27 | print(chai_status(5))
28 |
29 |
30 | def chai_report():
31 | return 100, 20, 10 # sold, remaining
32 |
33 | sold, remaining, not_paid = chai_report()
34 | print("Sold: ", sold)
35 | print("Remaining: ", remaining)
--------------------------------------------------------------------------------
/10_oop/06_inheritance_composition.py:
--------------------------------------------------------------------------------
1 | class BaseChai:
2 | def __init__(self, type_):
3 | self.type = type_
4 |
5 | def prepare(self):
6 | print(f"Preparing {self.type} chai....")
7 |
8 | class MasalaChai(BaseChai):
9 | def add_spices(self):
10 | print("Adding cardamom, ginger, cloves.")
11 |
12 |
13 | class ChaiShop:
14 | chai_cls = BaseChai
15 |
16 | def __init__(self):
17 | self.chai = self.chai_cls("Regular")
18 |
19 | def serve(self):
20 | print(f"Serving {self.chai.type} chai in the shop")
21 | self.chai.prepare()
22 |
23 | class FancyChaiShop(ChaiShop):
24 | chai_cls = MasalaChai
25 |
26 |
27 | shop = ChaiShop()
28 | fancy = FancyChaiShop()
29 | shop.serve()
30 | fancy.serve()
31 | fancy.chai.add_spices()
--------------------------------------------------------------------------------
/14_pydantic/01_basics/nested_model.py:
--------------------------------------------------------------------------------
1 | from typing import List, Optional
2 | from pydantic import BaseModel
3 |
4 |
5 | class Address(BaseModel):
6 | street: str
7 | city: str
8 | postal_code: str
9 |
10 | class User(BaseModel):
11 | id: int
12 | name: str
13 | address: Address
14 |
15 |
16 | address = Address(
17 | street="123 something",
18 | city="Jaipur",
19 | postal_code="100001"
20 | )
21 |
22 | user = User(
23 | id=1,
24 | name="Hitesh",
25 | address=address,
26 | )
27 |
28 |
29 | user_data = {
30 | "id": 1,
31 | "name": "Hitesh",
32 | "address": {
33 | "street": "321 something",
34 | "city": "Paris",
35 | "postal_code": "20002"
36 | }
37 | }
38 |
39 | user = User(**user_data)
40 | print(user)
--------------------------------------------------------------------------------
/challenges/05_data_science/day_09.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 | from sklearn.feature_extraction.text import TfidfVectorizer
3 | from sklearn.metrics.pairwise import cosine_similarity
4 |
5 |
6 | df = pd.read_csv("books.csv")
7 |
8 | vectorizer = TfidfVectorizer(stop_words='english')
9 | tfidf_matrix = vectorizer.fit_transform(df['description'])
10 | cosine_sim = cosine_similarity(tfidf_matrix, tfidf_matrix)
11 | indices = pd.Series(df.index, index=df['title'])
12 |
13 |
14 | def get_recommendations(title, cosine_sim=cosine_sim):
15 | idx = indices[title]
16 | sim_scores = list(enumerate(cosine_sim[idx]))
17 | sim_scores = sorted(sim_scores, key=lambda x: x[1], reverse=True)[1:6]
18 | book_indices = [i[0] for i in sim_scores]
19 | return df[['title', 'author']].iloc[book_indices]
--------------------------------------------------------------------------------
/14_pydantic/01_basics/computed_property.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel, computed_field, Field
2 |
3 |
4 | class Product(BaseModel):
5 | price: float
6 | quantity: int
7 |
8 | @computed_field
9 | @property
10 | def total_price(self) -> float:
11 | return self.price * self.quantity
12 |
13 |
14 | class Booking(BaseModel):
15 | user_id: int
16 | room_id: int
17 | nights: int = Field(..., ge=1)
18 | rate_per_night: float
19 |
20 | @computed_field
21 | @property
22 | def total_amount(self) -> float:
23 | return self.nights * self.rate_per_night
24 |
25 | booking = Booking(
26 | user_id=123,
27 | room_id=456,
28 | nights=3,
29 | rate_per_night=100.0
30 | )
31 |
32 | print(booking.total_amount)
33 | print(booking.model_dump())
--------------------------------------------------------------------------------
/04_loops/09_walrus.py:
--------------------------------------------------------------------------------
1 | # value = 13
2 | # remainder = value % 5
3 |
4 | # if remainder:
5 | # print(f"Not divisible, remainder is {remainder}")
6 |
7 |
8 | value = 13
9 |
10 | if remainder := value % 5:
11 | print(f"Not divisible, remainder is {remainder}")
12 |
13 |
14 | # available_sizes = ["small", "medium", "large"]
15 |
16 | # if (requested_size := input("Enter your chai cup size: ")) in available_sizes:
17 | # print(f"Serving {requested_size} chai")
18 | # else:
19 | # print(f"Size is unavailable - {requested_size}")
20 |
21 |
22 |
23 | flavors = ["masala", "ginger", "lemon", "mint"]
24 |
25 | print("Available flavors: ", flavors)
26 |
27 | while (flavor := input("Choose your flavor: ")) not in flavors:
28 | print(f"Sorry, {flavor} is not available")
29 |
30 | print(f"You choose {flavor} chai")
--------------------------------------------------------------------------------
/challenges/05_data_science/day_03.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 | import matplotlib.pyplot as plt
3 | from sklearn.linear_model import LinearRegression
4 |
5 | # load data set
6 | data = pd.read_csv("experience_salary.csv")
7 |
8 | X = data[["YearsExperience"]]
9 | y = data[["Salary"]]
10 |
11 | model = LinearRegression()
12 | model.fit(X, y)
13 |
14 | data["PredictedSalary"] = model.predict(X)
15 |
16 | print("Model Coefficient (slope)", round(float(model.coef_[0]), 2))
17 | print("Model INtercept (base salary)", round(float(model.intercept_), 2))
18 |
19 | plt.scatter(X, y, color="blue", label="Actual Data")
20 | plt.plot(X, data["PredictedSalary"], color="red", label="Regression line")
21 | plt.xlabel("Years of experience")
22 | plt.ylabel("Salary")
23 | plt.title("Salary vs Experience")
24 | plt.legend()
25 | plt.grid(True)
26 | plt.tight_layout()
27 | plt.show()
--------------------------------------------------------------------------------
/14_pydantic/01_basics/employee_model.py:
--------------------------------------------------------------------------------
1 | from typing import Optional
2 | from pydantic import BaseModel, Field
3 | import re
4 |
5 | class Employee(BaseModel):
6 | id: int
7 | name: str = Field(
8 | ...,
9 | min_length=3,
10 | max_length=50,
11 | description="Employee Name",
12 | examples="Hitesh Choudhary"
13 | )
14 | department: Optional[str] = 'General'
15 | salary: float = Field(
16 | ...,
17 | ge=10000
18 | )
19 |
20 |
21 | class User(BaseModel):
22 | email: str = Field(...,regex=r'')
23 | phone: str = Field(..., regex=r'')
24 | age: int = Field(
25 | ...,
26 | ge=0,
27 | le=150,
28 | description="Age in years",
29 | )
30 | discount: float = Field(
31 | ...,
32 | ge=0,
33 | le=100,
34 | description="Discount percentage"
35 | )
36 |
--------------------------------------------------------------------------------
/05_functions/09_input_params.py:
--------------------------------------------------------------------------------
1 | # chai = "Ginger chai"
2 |
3 | # def prepare_chai(order):
4 | # print("Preparing ", order)
5 |
6 |
7 | # prepare_chai(chai)
8 | # print(chai)
9 |
10 |
11 | chai = [1, 2, 3]
12 |
13 | def edit_chai(cup):
14 | cup[1] = 42
15 |
16 | edit_chai(chai)
17 | print(chai)
18 |
19 |
20 | def make_chai(tea, milk, sugar):
21 | print(tea, milk, sugar)
22 |
23 | make_chai("Darjeeling", "Yes", "Low") #positional
24 | make_chai(tea="Green", sugar="Medium", milk="No") #keywords
25 |
26 |
27 | def special_chai(*ingredients, **extras):
28 | print("Ingredients", ingredients)
29 | print("Extras", extras)
30 |
31 | special_chai("Cinnamon", "Cardmom", sweetener="Honey", foam="yes")
32 |
33 | # def chai_order(order=[]):
34 | # order.append("Masala")
35 | # print(order)
36 |
37 | def chai_order(order=None):
38 | if order is None:
39 | order = []
40 | print(order)
41 |
42 | chai_order()
43 | chai_order()
--------------------------------------------------------------------------------
/challenges/05_data_science/day_05.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 | import numpy as np
3 | import random
4 |
5 | toxic_comments = [
6 | "You're so dumb", "This is trash", "Worst video ever", "Stop making content", "You sound horrible",
7 | "Clickbait title", "Can't believe people like this", "Waste of time", "Cringe content", "You're such a loser"
8 | ]
9 |
10 | supportive_comments = [
11 | "This helped me a lot!", "You're amazing!", "Best tutorial I've seen", "Thanks for the content!",
12 | "Keep up the great work", "So clear and helpful", "Awesome explanation", "I learned a lot!", "Much appreciated!", "Legend!"
13 | ]
14 |
15 | data = []
16 |
17 | for i in range(50):
18 | data.append({"comment": random.choice(toxic_comments), "label": "toxic"})
19 | data.append({"comment": random.choice(supportive_comments), "label": "support"})
20 |
21 | df = pd.DataFrame(data)
22 | df.to_csv("youtube_comments.csv", index=False)
23 | print("✅ Data saved successfully")
--------------------------------------------------------------------------------
/challenges/05_data_science/day_07.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 | from sklearn.pipeline import Pipeline
3 | from sklearn.linear_model import LogisticRegression
4 | from sklearn.feature_extraction.text import TfidfVectorizer
5 | from sklearn.model_selection import train_test_split
6 | import streamlit as st
7 |
8 | @st.cache_resource
9 | def load_model():
10 | df = pd.read_csv("youtube_comments.csv")
11 | model = Pipeline([
12 | ('tfidf', TfidfVectorizer()),
13 | ('clf', LogisticRegression())
14 | ])
15 | model.fit(df['comment'], df['label'])
16 | return model
17 |
18 | model = load_model()
19 |
20 | st.title("Youtube comment classifier")
21 | st.write("Classify your comment as Toxic or supportive")
22 | user_input = st.text_area("Enter a youtube comment")
23 |
24 | if user_input:
25 | prediction = model.predict([user_input])[0]
26 | if prediction == "toxic":
27 | st.error("This comment is likely **Toxic**")
28 | else:
29 | st.success("This comment is **Supportive**")
30 |
31 |
--------------------------------------------------------------------------------
/02_datatypes/chapter_3.py:
--------------------------------------------------------------------------------
1 | # Interger
2 |
3 | black_tea_grams = 14
4 | ginger_grams = 3
5 |
6 | total_grams = black_tea_grams + ginger_grams
7 | print(f"Total grams of base tea is {total_grams}")
8 |
9 | remaing_tea = black_tea_grams - ginger_grams
10 | print(f"Total grams of remaining tea is {remaing_tea}")
11 |
12 | milk_litres = 7
13 | servings = 4
14 | milk_per_serving = milk_litres / servings
15 | print(f"Milk per serving is {milk_per_serving}")
16 |
17 | total_tea_bags = 7
18 | pots = 4
19 | bags_per_pot = total_tea_bags // pots
20 | print(f"While tea bags per pot: {bags_per_pot}")
21 |
22 | total_cadamom_pods = 10
23 | pods_per_cup = 3
24 | leftover_pods = total_cadamom_pods % pods_per_cup
25 | print(f"Leftover C pods {leftover_pods}")
26 |
27 | base_flavor_strength = 2
28 | scale_factor = 3
29 | powerful_falvour = base_flavor_strength ** scale_factor
30 | print(f"Scaled flavour strenght {powerful_falvour}")
31 | # 2 * 2 * 2
32 |
33 | total_tea_leaves_harvested = 1_000_000_000
34 | print(f"tea leaves: {total_tea_leaves_harvested}")
--------------------------------------------------------------------------------
/02_datatypes/chapter_10.py:
--------------------------------------------------------------------------------
1 | chai_order = dict(type="Masala Chai", size="Large", sugar=2)
2 | print(f"Chai order: {chai_order}")
3 |
4 | chai_recipe = {}
5 | chai_recipe["base"] = "black tea"
6 | chai_recipe["liquid"] = "milk"
7 |
8 | print(f"Recipe base: {chai_recipe['base']}")
9 | print(f"Recipe: {chai_recipe}")
10 | del chai_recipe["liquid"]
11 | print(f"Recipe: {chai_recipe}")
12 |
13 | print(f"Is sugar in the order? {'sugar' in chai_order}")
14 |
15 | chai_order = {"type": "Ginger Chai", "size": "Medium", "sugar": 1}
16 |
17 | # print(f"Order details (keys): {chai_order.keys()}")
18 | # print(f"Order details (values): {chai_order.values()}")
19 | # print(f"Order details (items): {chai_order.items()}")
20 |
21 | last_item = chai_order.popitem()
22 | print(f"Removed last item: {last_item}")
23 |
24 | extra_spices = {"cardamom": "crushed", "ginger": "sliced"}
25 | chai_recipe.update(extra_spices)
26 |
27 | print(f"Updated chai recipe: {chai_recipe}")
28 |
29 | customer_note = chai_order.get("size", "NO Note")
30 | print(f"customer_note is: {customer_note}")
--------------------------------------------------------------------------------
/14_pydantic/02_serialization/serial.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel, ConfigDict
2 | from typing import List
3 | from datetime import datetime
4 |
5 |
6 | class Address(BaseModel):
7 | street: str
8 | city: str
9 | zip_code: str
10 |
11 | class User(BaseModel):
12 | id: int
13 | name: str
14 | email: str
15 | is_active: bool = True
16 | createdAt: datetime
17 | address: Address
18 | tags: List[str] = []
19 |
20 | model_config = ConfigDict(
21 | json_encoders={datetime: lambda v: v.strftime('%d-%m-%Y %H:%M:%S')}
22 | )
23 |
24 |
25 | user = User(
26 | id=1,
27 | name="Hitesh",
28 | email="h@hitesh.ai",
29 | createdAt=datetime(2024, 3, 15, 14, 30,),
30 | address=Address(
31 | street="Something",
32 | city="Jaipur",
33 | zip_code="009988"
34 | ),
35 | is_active=False,
36 | tags=["premium", "subscriber"]
37 | )
38 |
39 | python_dict = user.model_dump()
40 | print(user)
41 | print("="*30)
42 | print(python_dict)
43 |
44 | json_str = user.model_dump_json()
45 | print("="*30)
46 | print(json_str)
--------------------------------------------------------------------------------
/10_oop/10_classmethod.py:
--------------------------------------------------------------------------------
1 | class ChaiOrder:
2 | def __init__(self, tea_type, sweetness, size):
3 | self.tea_type = tea_type
4 | self.sweetness = sweetness
5 | self.size = size
6 |
7 | @classmethod
8 | def from_dict(cls, order_data):
9 | return cls(
10 | order_data["tea_type"],
11 | order_data["sweetness"],
12 | order_data["size"],
13 | )
14 |
15 | @classmethod
16 | def from_string(cls, order_string):
17 | tea_type, sweetness, size = order_string.split("-")
18 | return cls(tea_type, sweetness, size)
19 |
20 | class ChaiUtils:
21 | @staticmethod
22 | def is_valid_size(size):
23 | return size in ["Small", "Medium", "Large"]
24 |
25 |
26 | print(ChaiUtils.is_valid_size("Medium"))
27 |
28 | order1 = ChaiOrder.from_dict({"tea_type": "masala", "sweetness": "medium", "size":"Large"})
29 |
30 | order2 = ChaiOrder.from_string("Ginger-Low-Small")
31 |
32 | order3 = ChaiOrder("Large", "Low", "Large")
33 |
34 | print(order1.__dict__)
35 | print(order2.__dict__)
36 | print(order3.__dict__)
--------------------------------------------------------------------------------
/challenges/05_data_science/day_04.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 | import matplotlib.pyplot as plt
3 | from sklearn.linear_model import LinearRegression
4 | import streamlit as st
5 |
6 | data = pd.read_csv("experience_salary.csv")
7 |
8 | X = data[["YearsExperience"]]
9 | y = data[["Salary"]]
10 |
11 | model = LinearRegression()
12 | model.fit(X, y)
13 |
14 | st.title("Salary Predictor based on experience")
15 | st.write("Enter your years of experience to predict your salary:")
16 |
17 | years_input = st.number_input("Years of experience", min_value=0.0, max_value=50.0, step=0.1)
18 |
19 | if years_input:
20 | print(years_input)
21 |
22 | predicted_salary = model.predict([[years_input]])[0]
23 | st.success(f"Estimated Salary: {predicted_salary}")
24 |
25 | st.subheader("Regression Line")
26 |
27 | fig, ax = plt.subplots()
28 | ax.scatter(X, y, color="blue", label="Actual Data")
29 | ax.plot(X, model.predict(X), color="red", label="Regression line")
30 | ax.set_xlabel("Years of experience")
31 | ax.set_ylabel("Salary")
32 | ax.set_title("Salary vs Experience")
33 | ax.legend()
34 |
35 | st.pyplot(fig)
--------------------------------------------------------------------------------
/challenges/02_data_handling/day_7.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: CSV-TO-JSON Converter Tool
3 |
4 | """
5 |
6 | import os
7 | import json
8 | import csv
9 |
10 | INPUT_FILE = "raw_data.csv"
11 | OUTPUT_FILE = "converted_data.json"
12 |
13 | def load_csv_data(filename):
14 | if not os.path.exists(filename):
15 | print("CSV file not found")
16 | return []
17 |
18 | with open(filename, 'r', encoding="utf-8") as f:
19 | reader = csv.DictReader(f)
20 | data = list(reader)
21 | print(data)
22 | return data
23 |
24 | def save_as_json(data, filename):
25 | with open(filename, "w", encoding="utf-8") as f:
26 | json.dump(data, f, indent=2)
27 | print(f"✅ Converted {len(data)} records to {filename}")
28 |
29 | def preview_data(data, count=3):
30 | for row in data[:count]:
31 | print(json.dumps(row, indent=2))
32 | print(".......")
33 |
34 |
35 | def main():
36 |
37 | data = load_csv_data(INPUT_FILE)
38 | if not data:
39 | return
40 | save_as_json(data, OUTPUT_FILE)
41 | preview_data(data)
42 |
43 | if __name__ == "__main__":
44 | main()
45 |
--------------------------------------------------------------------------------
/14_pydantic/01_basics/advance_nested_model.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel
2 | from typing import Optional, List, Union
3 |
4 |
5 | class Address(BaseModel):
6 | street: str
7 | city: str
8 | postal_code: str
9 |
10 | class Company(BaseModel):
11 | name: str
12 | address: Optional[Address] = None
13 |
14 | class Employee(BaseModel):
15 | name: str
16 | company: Optional[Company] = None
17 |
18 |
19 | class TextConent(BaseModel):
20 | type: str = "text"
21 | content: str
22 |
23 | class ImageContent(BaseModel):
24 | type: str = "Image"
25 | url: str
26 | alt_text: str
27 |
28 | class Article(BaseModel):
29 | title: str
30 | sections: List[Union[TextConent, ImageContent]]
31 |
32 |
33 | class Country(BaseModel):
34 | name: str
35 | code: str
36 |
37 | class State(BaseModel):
38 | name: str
39 | country: Country
40 |
41 | class City(BaseModel):
42 | name: str
43 | state: State
44 |
45 | class Address(BaseModel):
46 | street: str
47 | city: City
48 | postal_code: str
49 |
50 | class Organization(BaseModel):
51 | name: str
52 | head_quarter: Address
53 | branches: List[Address]=[]
--------------------------------------------------------------------------------
/14_pydantic/01_basics/advance_validators.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel, field_validator, model_validator
2 | from datetime import datetime
3 |
4 | class Person(BaseModel):
5 | first_name: str
6 | last_name : str
7 |
8 | @field_validator('first_name', 'last_name')
9 | def names_must_be_capitalize(cls, v):
10 | if not v.istitle():
11 | raise ValueError('Names must be capitilized')
12 | return v
13 |
14 |
15 | class User(BaseModel):
16 | email: str
17 |
18 | @field_validator('email')
19 | def normalize_email(cls, v):
20 | return v.lower().strip()
21 |
22 |
23 |
24 | class Product(BaseModel):
25 | price: str # $4.44
26 |
27 | @field_validator('price', mode='before')
28 | def parse_price(cls, v):
29 | if isinstance(v, str):
30 | return float(v.replace('$', ''))
31 | return v
32 |
33 | class DateRange(BaseModel):
34 | start_date: datetime
35 | end_date: datetime
36 |
37 |
38 | @model_validator(mode="after")
39 | def validate_date_range(cls, values):
40 | if values.start_date >= values.end_date:
41 | raise ValueError('end_date must be after start_date')
42 | return values
--------------------------------------------------------------------------------
/challenges/01_utilities/day_9.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Set a Countdown Timer
3 |
4 | Create a Python script that allows the user to set a timer in seconds. The script should:
5 |
6 | 1. Ask the user for the number of seconds to set the timer.
7 | 2. Show a live countdown in the terminal.
8 | 3. Notify the user when the timer ends with a final message and sound (if possible).
9 |
10 | Bonus:
11 | - Format the remaining time as MM:SS
12 | - Use a beep sound (`\a`) at the end if the terminal supports it
13 | - Prevent negative or non-integer inputs
14 | """
15 |
16 | import time
17 |
18 | while True:
19 | try:
20 | seconds = int(input("⏰ Enter the time in seconds: "))
21 | if seconds < 1:
22 | print("Please enter a number greater than 0")
23 | continue
24 | break
25 | except ValueError:
26 | print("Invalid input, please enter a whole number")
27 |
28 |
29 | print("\n 🔔 Timer started...")
30 | for remaining in range(seconds, 0, -1):
31 | mins, secs = divmod(remaining, 60)
32 | time_format = f"{mins:02}:{secs:02}"
33 | print(f"🕰️ Time left: {time_format} ", end="\r")
34 | time.sleep(1)
35 |
36 | print("\n Time's up! Take a break or move on to next task.")
37 | #print("\a") # optional; makes a beep sound
--------------------------------------------------------------------------------
/challenges/05_data_science/books.csv:
--------------------------------------------------------------------------------
1 | title,author,genre,description
2 | The Silent Forest,Jane Hill,Mystery,A detective uncovers secrets hidden deep in the woods while chasing a serial killer.
3 | Spacebound,Rico Vega,Science Fiction,An astronaut embarks on a mission to Mars but discovers an ancient alien presence.
4 | Love in Paris,Emily Rose,Romance,A love story between a local baker and a traveler unfolds in the heart of Paris.
5 | Quantum Heist,Leo Hunt,Thriller,A group of hackers plans a digital heist targeting the world's most secure quantum server.
6 | Mystic Academy,Lara Moon,Fantasy,A young girl discovers she has magical powers and is taken to an academy for gifted spellcasters.
7 | The Digital Mind,Alan Neural,Science Fiction,An AI begins to question its creators and the meaning of consciousness.
8 | Fog Over London,Claire Black,Mystery,"Set in Victorian London, a private investigator unravels political conspiracies amid murders."
9 | Beneath the Waves,Diana Coast,Adventure,An underwater archaeologist discovers an ancient city lost in the ocean.
10 | Heart Strings,Ella Harmony,Romance,Two musicians from rival bands fall in love during a national tour.
11 | Dark Code,Nick Cipher,Thriller,A cybersecurity expert is drawn into a global web of espionage and hidden messages.
12 |
--------------------------------------------------------------------------------
/02_datatypes/chapter_8.py:
--------------------------------------------------------------------------------
1 | ingredients = ["water", "milk", "black tea"]
2 | ingredients.append("sugar")
3 | print(f"Ingredients are: {ingredients}")
4 | ingredients.remove("water")
5 | print(f"Ingredients are: {ingredients}")
6 |
7 | spice_options = ["ginger", "cardamom"]
8 | chai_ingredients = ["water", "milk"]
9 |
10 | chai_ingredients.extend(spice_options)
11 | print(f"chai: {chai_ingredients}")
12 | chai_ingredients.insert(2, "black tea")
13 | print(f"chai: {chai_ingredients}")
14 |
15 | last_added = chai_ingredients.pop()
16 | print(f"{last_added}")
17 | print(f"chai: {chai_ingredients}")
18 | chai_ingredients.reverse()
19 | print(f"chai: {chai_ingredients}")
20 | chai_ingredients.sort()
21 | print(f"chai: {chai_ingredients}")
22 |
23 | sugar_levels = [1, 2, 3, 4, 5]
24 | print(f"Maximum sugar level: {max(sugar_levels)}")
25 | print(f"Minimum sugar level: {min(sugar_levels)}")
26 |
27 | base_liquid = ["water", "milk"]
28 | extra_flavor = ["ginger"]
29 |
30 | full_liquid_mix = base_liquid + extra_flavor
31 | print(f"Liquid mix: {full_liquid_mix}")
32 |
33 | strong_brew = ["black tea", "water"] * 3
34 | print(f"String brew: {strong_brew}")
35 |
36 | raw_spice_data = bytearray(b"CINNAMON")
37 | raw_spice_data = raw_spice_data.replace(b"CINNA", b"CARD")
38 | print(f"Bytes: {raw_spice_data}")
--------------------------------------------------------------------------------
/challenges/04_automation/day_04.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Real-Time System Resource Monitor
3 |
4 | Goal:
5 | - Monitor your system's CPU, RAM, and Disk usage
6 | - Print updates every few seconds
7 | - Warn user if CPU or RAM usage exceeds 80%
8 | - Runs in terminal as a live dashboard
9 |
10 | Teaches: psutil, formatting, real-time monitoring, conditional logic
11 | Tools: psutil, time
12 | """
13 | import psutil
14 | import time
15 | import os
16 |
17 | def clear_screen():
18 | os.system('cls' if os.name == 'nt' else 'clear')
19 |
20 | def show_stats():
21 | print("🔥" * 30)
22 | print("⭐️ System Resource Monitor ⭐️")
23 |
24 | cpu = psutil.cpu_percent(interval=1)
25 | ram = psutil.virtual_memory()
26 | disk = psutil.disk_usage('/')
27 |
28 | print(f"CPU USAGE: {cpu}")
29 | print(f"RAM USAGE: {ram.percent}% ( {round(ram.used / 1e9, 2)} GB used of {round(ram.total / 1e9, 2)} GB)")
30 | print(f"DISK USAGE: {disk.percent}% ( {round(disk.used / 1e9, 2)} GB used of {round(disk.total / 1e9, 2)} GB)")
31 | print("🔥" * 30)
32 |
33 | if __name__ == "__main__":
34 | try:
35 | while True:
36 | clear_screen()
37 | show_stats()
38 | time.sleep(3)
39 | except KeyboardInterrupt:
40 | print("Monitoring Stopped.....")
--------------------------------------------------------------------------------
/challenges/03_web_scraping/day_01.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Scrape Wikipedia h2 Headers
3 |
4 | Use the `requests` and `BeautifulSoup` libraries to fetch the Wikipedia page on Python (programming language).
5 |
6 | Your task is to:
7 | 1. Download the HTML of the page.
8 | 2. Parse all `` section headers.
9 | 3. Store the clean header titles in a list.
10 | 4. Print the total count and display the first 10 section titles.
11 |
12 | Bonus:
13 | - Remove any trailing "[edit]" from the headers.
14 | - Handle network errors gracefully.
15 | """
16 |
17 | import requests
18 | from bs4 import BeautifulSoup
19 |
20 | URL = "https://en.wikipedia.org/wiki/Python_(programming_language)"
21 |
22 | def get_h2_headers(url):
23 | try:
24 | response = requests.get(url, timeout=10)
25 | response.raise_for_status()
26 | except requests.RequestException as e:
27 | print(f"Failed to fetch page: \n {e}")
28 | return []
29 |
30 | soup = BeautifulSoup(response.text, "html.parser")
31 | h2_tags = soup.find_all("h2")
32 | print(h2_tags)
33 | headers = []
34 | for tag in h2_tags:
35 | header_text = tag.get_text(strip=True)
36 | if header_text and header_text.lower() != "contents":
37 | headers.append(header_text)
38 | print(headers)
39 |
40 | get_h2_headers(URL)
--------------------------------------------------------------------------------
/challenges/01_utilities/day_11.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Friendship Compatibility Calculator
3 |
4 | Build a Python script that calculates a fun "compatibility score" between two friends based on their names.
5 |
6 | Your program should:
7 | 1. Ask for two names (friend A and friend B).
8 | 2. Count shared letters, vowels, and character positions to create a compatibility score (0-100).
9 | 3. Display the percentage with a themed message like:
10 | "You're like chai and samosa — made for each other!" or
11 | "Well... opposites attract, maybe?"
12 |
13 | Bonus:
14 | - Use emojis in the result
15 | - Give playful advice based on the score range
16 | - Capitalize and center the final output in a framed box
17 | """
18 |
19 | def friendship_score(name1, name2):
20 | name1, name2 = name1.lower(), name2.lower()
21 | score = 0
22 | shared_letters = set(name1) & set(name2)
23 | vowels = set('aeiou')
24 |
25 | score += len(shared_letters) * 5
26 | score += len(vowels & shared_letters) * 10
27 |
28 | return min(score, 100)
29 |
30 | def run_friendship_calculator():
31 | print("❤️ Friendship Compatibility calculator ❤️")
32 | name1 = input("Enter first name: ")
33 | name2 = input("Enter second name: ")
34 |
35 | score = friendship_score(name1, name2)
36 |
37 | print(f"\n {score}")
38 |
39 |
40 | run_friendship_calculator()
--------------------------------------------------------------------------------
/challenges/01_utilities/day_5.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Emoji Enhancer for Messages
3 |
4 | Create a Python script that takes a message and adds emojis after specific keywords to make it more expressive.
5 |
6 | Your program should:
7 | 1. Ask the user to input a message.
8 | 2. Add emojis after certain keywords (like "happy", "love", "code", "tea", etc.).
9 | 3. Print the updated message with emojis.
10 |
11 | Example:
12 | Input:
13 | I love to code and drink tea when I'm happy.
14 |
15 | Output:
16 | I love ❤️ to code 💻 and drink tea 🍵 when I'm happy 😊.
17 |
18 | Bonus:
19 | - Make it case-insensitive (match "Happy" or "happy")
20 | - Handle punctuation (like commas or periods right after keywords)
21 |
22 | """
23 | # get a dictionary
24 | emoji_map_fun = {
25 | "love": "❤️",
26 | "happy": "😊",
27 | "code": "💻",
28 | "tea": "🍵",
29 | "music": "🎵",
30 | "food": "🍕",
31 | }
32 |
33 | # get user message
34 | message = input("Enter your message: ")
35 |
36 | updated_words = []
37 | # process each word
38 | for word in message.split():
39 | cleaned = word.lower().strip(".,!?")
40 | emoji = emoji_map_fun.get(cleaned, "")
41 | if emoji:
42 | updated_words.append(f"{word} {emoji}")
43 | else:
44 | updated_words.append(word)
45 |
46 | updated_message = " ".join(updated_words)
47 | print("\n Enhanced message:\n")
48 | print(updated_message)
--------------------------------------------------------------------------------
/challenges/03_web_scraping/day_08.py:
--------------------------------------------------------------------------------
1 | """
2 | depends on:
3 | - Day 7 of web scraping
4 |
5 | Fetch crypto data every hour automatically
6 |
7 | """
8 |
9 | import os
10 | import csv
11 | from datetime import datetime
12 | import requests
13 | import schedule
14 | import time
15 |
16 | API_URL = "https://api.coingecko.com/api/v3/coins/markets"
17 |
18 | PARAMS = {
19 | 'vs_currency': 'usd',
20 | 'order': 'market_cap_desc',
21 | 'per_page':10,
22 | 'page':1,
23 | 'sparkline':False
24 | }
25 |
26 | CSV_FILE = 'crypto_prices.csv'
27 |
28 | def fetch_crypto_data():
29 | response = requests.get(API_URL, params=PARAMS)
30 | return response.json()
31 |
32 | def save_to_csv(data):
33 | file_exists = os.path.isfile(CSV_FILE)
34 |
35 | with open(CSV_FILE, 'a', newline='') as file:
36 | writer = csv.writer(file)
37 | if not file_exists:
38 | writer.writerow(["timestamp", "coin", "price"])
39 |
40 | timestamp = datetime.now().strftime("%Y-%m-%d %H-%M-%S")
41 | for coin in data:
42 | writer.writerow([timestamp, coin["id"], coin['current_price']])
43 | print("✅ data saved to csv")
44 |
45 |
46 | def job():
47 | print("Fetching data hourly...")
48 | crypto_data = fetch_crypto_data()
49 | save_to_csv(crypto_data)
50 |
51 | schedule.every().hour.at(":00").do(job)
52 |
53 | while True:
54 | schedule.run_pending()
55 | time.sleep(60)
--------------------------------------------------------------------------------
/challenges/01_utilities/day_3.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Simple Bill Splitter
3 |
4 | Write a Python script that helps split a bill evenly between friends.
5 |
6 | Your program should:
7 | 1. Ask how many people are in the group.
8 | 2. Ask for each person's name.
9 | 3. Ask for the total bill amount.
10 | 4. Calculate each person's share of the bill.
11 | 5. Display how much each person owes in a clean, readable format.
12 |
13 | Example:
14 | Total bill: ₹1200
15 | People: Aman, Neha, Ravi
16 |
17 | Each person owes: ₹400
18 |
19 | Final output:
20 | Aman owes ₹400
21 | Neha owes ₹400
22 | Ravi owes ₹400
23 |
24 | Bonus:
25 | - Round to 2 decimal places
26 | - Print a decorative summary box
27 | """
28 |
29 | def get_float(prompt):
30 | while True:
31 | try:
32 | return float(input(prompt))
33 | except ValueError:
34 | print("❌ Please enter a valid number. ")
35 |
36 | num_people = int(input("How many people are there in the group? "))
37 | names = []
38 |
39 | for i in range(num_people):
40 | name = input(f"Enter the name of persion #{i+1}").strip()
41 | names.append(name)
42 |
43 | total_bill = get_float("Enter the bill amount in number only")
44 |
45 | share = round(total_bill / num_people, 2)
46 |
47 | print("\n" + "*" * 40)
48 | print(f"Total bill: {total_bill}")
49 | print(f"Each person owes {share}")
50 |
51 | for name in names:
52 | print(f"{name} owes {share} rupees")
53 |
54 | print("\n" + "*" * 40)
--------------------------------------------------------------------------------
/challenges/01_utilities/day_6.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Daily Learning Journal Logger
3 |
4 | Build a Python script that allows you to maintain a daily learning journal. Each entry will be saved into a `.txt` file along with a timestamp.
5 |
6 | Your program should:
7 | 1. Ask the user what they learned today.
8 | 2. Add the entry to a file called `learning_journal.txt`.
9 | 3. Each entry should include the date and time it was written.
10 | 4. The journal should **append** new entries rather than overwrite.
11 |
12 | Bonus:
13 | - Add an optional rating (1-5) for how productive the day was.
14 | - Show a confirmation message after saving the entry.
15 | - Make sure the format is clean and easy to read when opening the file.
16 |
17 | Example:
18 | 📅 2025-06-14 — 10:45 AM
19 | Today I learned about how list comprehensions work in Python!
20 | Productivity Rating: 4/5
21 | """
22 |
23 | import datetime
24 |
25 | entry = input("What did you learn today ? ").strip()
26 | rating = input("⭐️ rate your productivity today (1-5, optional)").strip()
27 |
28 | now = datetime.datetime.now()
29 | date_str = now.strftime("%Y-%m-%d - %I:%M %p")
30 |
31 | journal_entry = f"\n 🗓️ {date_str}\n{entry}"
32 | if rating:
33 | journal_entry += f"\n Productivity Rating: {rating}\n"
34 | journal_entry += "\n" + "-" * 50
35 |
36 | with open("learning_journal.txt", "a", encoding="utf-8") as f:
37 | f.write(journal_entry)
38 |
39 | print(f"\n your journal entry has been saved to 'learning_journal.txt' file. ")
40 |
--------------------------------------------------------------------------------
/challenges/02_data_handling/day_5.py:
--------------------------------------------------------------------------------
1 | """
2 | Sample data:
3 | Date,City,Temperature,Condition
4 | 2025-06-11,Delhi,36.5,Clear
5 | 2025-06-12,Delhi,37.8,Sunny
6 | 2025-06-13,Delhi,38.0,Sunny
7 | 2025-06-14,Delhi,34.2,Rain
8 | 2025-06-15,Delhi,35.0,Clouds
9 | 2025-06-16,Delhi,33.4,Rain
10 | 2025-06-17,Delhi,34.7,Clear
11 |
12 | Plot graphs from this data
13 |
14 |
15 | """
16 | import csv
17 | from collections import defaultdict
18 | import matplotlib.pyplot as plt
19 |
20 | FILENAME = "weather_logs.csv"
21 | def visualize_weather():
22 | dates = []
23 | temps = []
24 | conditions = defaultdict(int)
25 |
26 | with open(FILENAME, "r", encoding="utf-8") as f:
27 | reader = csv.DictReader(f)
28 | for row in reader:
29 | try:
30 | dates.append(row["Date"])
31 | temps.append(row["Temperature"])
32 | conditions[row["Condition"]] += 1
33 | except:
34 | continue
35 | if not dates:
36 | print("NO data is available")
37 | return
38 |
39 | plt.figure(figsize=(10, 7))
40 | plt.plot(dates, temps, marker='o')
41 | plt.title("Temperature over time")
42 | plt.xlabel("Date")
43 | plt.ylabel("Temperature")
44 | plt.tight_layout()
45 | plt.grid(True)
46 | plt.show()
47 |
48 | plt.figure(figsize=(7, 5))
49 | plt.bar(conditions.keys(), conditions.values(), color='skyblue')
50 | plt.xlabel("Condition")
51 | plt.ylabel("Days")
52 | plt.show()
53 |
54 |
55 |
56 | visualize_weather()
--------------------------------------------------------------------------------
/challenges/06_url_shortner/app.py:
--------------------------------------------------------------------------------
1 | from flask import Flask, request, redirect, render_template
2 | import random
3 | import string
4 |
5 | from models import (
6 | init_db,
7 | insert_url,
8 | get_url,
9 | get_all_urls,
10 | increment_visit_count,
11 | delete_url_by_code
12 | )
13 |
14 | app = Flask(__name__)
15 |
16 | init_db()
17 |
18 | def generate_short_code(length=6):
19 | return ''.join(random.choices(string.ascii_letters + string.digits, k=length))
20 |
21 | @app.route("/", methods=['GET', 'POST'])
22 | def index():
23 | if request.method == 'POST':
24 | orginal_url = request.form['url']
25 | short_code = generate_short_code()
26 | insert_url(orginal_url, short_code)
27 | return redirect("/")
28 | all_urls = get_all_urls()
29 | return render_template('index.html', all_urls=all_urls)
30 |
31 | @app.route("/about")
32 | def about():
33 | return 'this is an amazing course on python - Udemy'
34 |
35 | @app.route('/')
36 | def redirect_url(short_code):
37 | url_data = get_url(short_code)
38 | if url_data:
39 | increment_visit_count(short_code)
40 | return redirect(url_data[1])
41 | return render_template('404.html'), 404
42 |
43 | @app.route('/delete/', methods=['POST'])
44 | def delete_url(short_code):
45 | delete_url_by_code(short_code)
46 | return redirect("/")
47 |
48 |
49 | if __name__ == '__main__':
50 | app.run(
51 | debug=True,
52 | host='0.0.0.0',
53 | port=8000
54 | )
--------------------------------------------------------------------------------
/challenges/05_data_science/day_10.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 | from sklearn.feature_extraction.text import TfidfVectorizer
3 | from sklearn.metrics.pairwise import cosine_similarity
4 | import streamlit as st
5 |
6 | df = pd.read_csv("books.csv")
7 | df['title'] = df['title'].str.strip()
8 | df['description'] = df['description'].fillna("")
9 |
10 | vectorizer = TfidfVectorizer(stop_words='english')
11 | tfidf_matrix = vectorizer.fit_transform(df['description'])
12 | cosine_sim = cosine_similarity(tfidf_matrix, tfidf_matrix)
13 | indices = pd.Series(df.index, index=df['title'].str.lower()).drop_duplicates()
14 |
15 |
16 | def get_recommendations(title, df, cosine_sim, indices):
17 | title = title.strip().lower()
18 |
19 | if title not in indices.index:
20 | return f"{title} not found in dataset"
21 |
22 | idx = indices.loc[title]
23 | if isinstance(idx, pd.Series):
24 | idx = idx.iloc[0]
25 |
26 |
27 | idx = indices[title]
28 | sim_scores = list(enumerate(cosine_sim[idx]))
29 | sim_scores = sorted(sim_scores, key=lambda x: x[1], reverse=True)[1:6]
30 | book_indices = [i[0] for i in sim_scores]
31 | return df[['title', 'author']].iloc[book_indices]
32 |
33 |
34 | st.title("Book Recommendation Engine")
35 | st.write("Enter a book title and get similar recommendation")
36 |
37 | select_book = st.text_input("Book: Title")
38 |
39 | if select_book:
40 | results = get_recommendations(select_book, df, cosine_sim, indices)
41 |
42 | if isinstance(results, pd.DataFrame):
43 | st.table(results)
44 | else:
45 | st.warning(results)
--------------------------------------------------------------------------------
/challenges/06_url_shortner/models.py:
--------------------------------------------------------------------------------
1 | import sqlite3
2 |
3 |
4 | DB_NAME = 'database.db'
5 |
6 |
7 | def init_db():
8 | with sqlite3.connect(DB_NAME) as conn:
9 | conn.execute('''
10 | CREATE TABLE IF NOT EXISTS urls(
11 | id INTEGER PRIMARY KEY AUTOINCREMENT,
12 | original_url TEXT NOT NULL,
13 | short_code TEXT UNIQUE NOT NULL,
14 | visit_count INTEGER DEFAULT 0
15 | )
16 | ''')
17 |
18 | def insert_url(original_url, short_code):
19 | with sqlite3.connect(DB_NAME) as conn:
20 | conn.execute('''
21 | INSERT INTO urls (original_url, short_code)
22 | VALUES (?, ?)
23 | ''', (original_url, short_code))
24 |
25 | def get_url(short_code):
26 | with sqlite3.connect(DB_NAME) as conn:
27 | cur = conn.execute('SELECT * FROM urls WHERE short_code = ?', (short_code,))
28 | return cur.fetchone()
29 |
30 | def increment_visit_count(short_code):
31 | with sqlite3.connect(DB_NAME) as conn:
32 | conn.execute('''
33 | UPDATE urls
34 | SET visit_count = visit_count + 1
35 | WHERE short_code = ?
36 | ''', (short_code,))
37 |
38 | def get_all_urls():
39 | with sqlite3.connect(DB_NAME) as conn:
40 | cur = conn.execute('SELECT original_url, short_code, visit_count FROM urls ORDER by id DESC')
41 | return cur.fetchall()
42 |
43 | def delete_url_by_code(short_code):
44 | with sqlite3.connect(DB_NAME) as conn:
45 | conn.execute('DELETE from urls WHERE short_code = ?', (short_code,))
--------------------------------------------------------------------------------
/challenges/05_data_science/day_01.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "975e0731",
6 | "metadata": {},
7 | "source": [
8 | "### Welcome to Python notebook\n",
9 | "### Day 1\n",
10 | "\n",
11 | "This is where you can write your notes\n",
12 | "\n"
13 | ]
14 | },
15 | {
16 | "cell_type": "code",
17 | "execution_count": 1,
18 | "id": "b3fdb059",
19 | "metadata": {},
20 | "outputs": [
21 | {
22 | "name": "stdout",
23 | "output_type": "stream",
24 | "text": [
25 | "hitesh\n"
26 | ]
27 | }
28 | ],
29 | "source": [
30 | "print(\"hitesh\")"
31 | ]
32 | },
33 | {
34 | "cell_type": "code",
35 | "execution_count": 2,
36 | "id": "41302528",
37 | "metadata": {},
38 | "outputs": [
39 | {
40 | "name": "stdout",
41 | "output_type": "stream",
42 | "text": [
43 | "this value is 0\n",
44 | "this value is 1\n",
45 | "this value is 2\n",
46 | "this value is 3\n",
47 | "this value is 4\n"
48 | ]
49 | }
50 | ],
51 | "source": [
52 | "for i in range(5):\n",
53 | " print(f\"this value is {i}\")"
54 | ]
55 | }
56 | ],
57 | "metadata": {
58 | "kernelspec": {
59 | "display_name": "bin",
60 | "language": "python",
61 | "name": "python3"
62 | },
63 | "language_info": {
64 | "codemirror_mode": {
65 | "name": "ipython",
66 | "version": 3
67 | },
68 | "file_extension": ".py",
69 | "mimetype": "text/x-python",
70 | "name": "python",
71 | "nbconvert_exporter": "python",
72 | "pygments_lexer": "ipython3",
73 | "version": "3.13.2"
74 | }
75 | },
76 | "nbformat": 4,
77 | "nbformat_minor": 5
78 | }
79 |
--------------------------------------------------------------------------------
/challenges/01_utilities/day_1.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Self-Intro Script Generator
3 |
4 | Create a Python script that interacts with the user and generates a personalized self-introduction.
5 |
6 | Your program should:
7 | 1. Ask the user for their name, age, city, profession, and favorite hobby.
8 | 2. Format this data into a warm, friendly paragraph of self-introduction.
9 | 3. Print the final paragraph in a clean and readable format.
10 |
11 | Example:
12 | If the user inputs:
13 | Name: Priya
14 | Age: 22
15 | City: Jaipur
16 | Profession: Software Developer
17 | Hobby: playing guitar
18 |
19 | Your script might output:
20 | "Hello! My name is Priya. I'm 22 years old and live in Jaipur. I work as a Software Developer and I absolutely enjoy playing guitar in my free time. Nice to meet you!"
21 |
22 | Bonus:
23 | - Add the current date to the end of the paragraph like: "Logged on: 2025-06-14"
24 | - Wrap the printed message with a decorative border of stars (*)
25 | """
26 | import datetime
27 |
28 | name = input("What is your name ? ").strip()
29 | age = input("How old are you ? ").strip()
30 | city = input("Which city do you live in? ").strip()
31 | profession = input("What is your profession? ").strip()
32 | hobby = input("WHat is your favourite hobby? ").strip()
33 |
34 | intro_message = (
35 | f"Hello! my name is {name}, I'm {age} years old and live in {city}. "
36 | f"I work as a {profession} and I absolutely enjoy {hobby} in my free time. "
37 | f"Nice to meet you!\n"
38 | )
39 |
40 |
41 | current_date = datetime.date.today().isoformat()
42 | intro_message += f"\n Logged on: {current_date}"
43 |
44 |
45 | border = "*" * 80
46 | final_output = f"{border}\n{intro_message}\n{border}"
47 |
48 | print("\n" + final_output)
--------------------------------------------------------------------------------
/challenges/04_automation/day_03.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Auto File Organizer with Watchdog
3 |
4 | Goal:
5 | - Monitor a folder (e.g., Downloads/Desktop)
6 | - When a new file is added:
7 | - Move PDFs to /PDFs
8 | - Move Images to /Images
9 | - Move ZIP files to /Archives
10 | - Everything else goes to /Others
11 |
12 | Teaches: Folder monitoring, real-time automation, event-driven design
13 | Tools: watchdog, shutil, os
14 | """
15 |
16 | import os
17 | import shutil
18 | from watchdog.events import FileSystemEventHandler
19 | from watchdog.observers import Observer
20 |
21 | WATCH_FOLDER = os.path.expanduser("~/Downloads")
22 |
23 | FILE_DESTS = {
24 | '.pdf': 'PDFs',
25 | '.jpg': 'Images',
26 | '.png': 'Images',
27 | }
28 |
29 |
30 | class FileMoverHandler(FileSystemEventHandler):
31 | def on_created(self, event):
32 | if event.is_directory:
33 | return
34 |
35 | filepath = event.src_path
36 | ext = os.path.splitext(filepath)[1].lower()
37 |
38 | dest_folder = FILE_DESTS.get(ext, 'Others')
39 | full_dest = os.path.join(WATCH_FOLDER, dest_folder)
40 | os.makedirs(full_dest, exist_ok=True)
41 | move_to = os.path.join(full_dest, os.path.basename(filepath))
42 | try:
43 | shutil.move(filepath, move_to)
44 | # print message
45 | except:
46 | print("Failed to move")
47 |
48 | if __name__ == "__main__":
49 | print(f"Watching folder: {WATCH_FOLDER}")
50 | event_handler = FileMoverHandler()
51 | observer = Observer()
52 | observer.schedule(event_handler, path=WATCH_FOLDER, recursive=False)
53 | observer.start()
54 |
55 | try:
56 | while True:
57 | pass
58 | except KeyboardInterrupt:
59 | observer.stop()
60 | observer.join()
--------------------------------------------------------------------------------
/challenges/04_automation/day_01.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: File Sorter by Type
3 |
4 | Goal:
5 | - Scan the current folder (or a user-provided folder)
6 | - Move files into subfolders based on their type:
7 | - .pdf → PDFs/
8 | - .jpg, .jpeg, .png → Images/
9 | - .txt → TextFiles/
10 | - Others → Others/
11 | - Create folders if they don't exist
12 | - Ignore folders during the move
13 |
14 | Teaches: File system operations, automation, file handling with `os` and `shutil`
15 | """
16 | import os
17 | import shutil
18 |
19 | EXTENSION_MAP = {
20 | "PDFs": [".pdf"],
21 | "Images": [".png", ".jpeg", ".jpg"],
22 | "TextFiles": [".txt"]
23 | }
24 |
25 | def get_destination_folder(filename):
26 | ext = os.path.splitext(filename)[1].lower()
27 | for folder, extensions in EXTENSION_MAP.items():
28 | if ext in extensions:
29 | return folder
30 | return "Others"
31 |
32 | def sort_files(folder_path):
33 | for file in os.listdir(folder_path):
34 | full_path = os.path.join(folder_path, file)
35 |
36 | # write a check if file name is "day_01.py" then ignore this file
37 |
38 | if os.path.isfile(full_path):
39 | dest_folder = get_destination_folder(file)
40 | dest_path = os.path.join(folder_path, dest_folder)
41 |
42 | os.makedirs(dest_path, exist_ok=True)
43 |
44 | #move the file
45 | shutil.move(full_path, os.path.join(dest_path, file))
46 | print(f"Moved : {file} -> {dest_folder}/")
47 |
48 |
49 | if __name__ == "__main__":
50 | folder = input("Enter the folder path or leave blank: ").strip()
51 | folder = folder or os.getcwd()
52 |
53 | if not os.path.isdir(folder):
54 | print("Invalid directory")
55 | else:
56 | sort_files(folder)
57 | print("✅ sorting completed")
--------------------------------------------------------------------------------
/challenges/03_web_scraping/day_02.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Hacker News Top Posts Scraper
3 |
4 | Build a Python script that:
5 | 1. Fetches the HN homepage (news.ycombinator.com).
6 | 2. Extracts the top 20 post titles and URLs.
7 | 3. Saves the results into a CSV file (`hn_top20.csv`) with columns:
8 | - Title
9 | - URL
10 | 4. Handles network errors and uses a clean CSV structure.
11 | """
12 | import csv
13 | import requests
14 | from bs4 import BeautifulSoup
15 |
16 | HN_URL = "https://news.ycombinator.com/"
17 | CSV_FILE = "hn_top20.csv"
18 |
19 |
20 | def fetch_top_post():
21 | try:
22 | response = requests.get(HN_URL, timeout=10)
23 | response.raise_for_status()
24 | except requests.RequestException as e:
25 | print(f"Network error \n {e}")
26 | return []
27 |
28 | soup = BeautifulSoup(response.text, "html.parser")
29 | post_links = soup.select("span.titleline > a")
30 | # print(post_links)
31 |
32 | posts = []
33 | for link in post_links[:20]:
34 | title = link.text.strip()
35 | url = link.get("href").strip()
36 | # print(f"{title} \n {url} \n\n")
37 | posts.append({"title": title, "url": url})
38 |
39 | return posts
40 |
41 |
42 | def save_to_csv(posts):
43 | if not posts:
44 | print("Noting to save")
45 | return
46 |
47 | with open(CSV_FILE, "w", newline="", encoding="utf-8") as f:
48 | writer = csv.DictWriter(f, fieldnames=["title", "url"])
49 | writer.writeheader()
50 | writer.writerows(posts)
51 |
52 | print(f"✅ Saved Hacker News to {CSV_FILE}")
53 |
54 |
55 |
56 | def main():
57 | print("Scrapping the HN portal....")
58 | posts = fetch_top_post()
59 | print("Collected all data...")
60 | save_to_csv(posts)
61 |
62 | if __name__ == "__main__":
63 | main()
64 |
65 |
--------------------------------------------------------------------------------
/challenges/04_automation/day_02.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Batch Rename Files in a Folder
3 |
4 | Goal:
5 | - Scan all files in a selected folder
6 | - Rename them with a consistent pattern:
7 | e.g., "image_1.jpg", "image_2.jpg", ...
8 | - Ask the user for:
9 | - A base name (e.g., "image")
10 | - A file extension to filter (e.g., ".jpg")
11 | - Preview before renaming
12 | - Optional: allow undo (save original names in a file)
13 |
14 | Teaches: File iteration, string formatting, renaming, user input
15 | """
16 | import os
17 |
18 | def batch_rename(folder, base_name, extension):
19 | files = [f for f in os.listdir(folder) if f.lower().endswith(extension.lower())]
20 | files.sort() # this will not do much
21 |
22 | if not files:
23 | print("NO files found in dir")
24 | return
25 |
26 | for i, file in enumerate(files, start=1):
27 | new_name = f"{base_name}_{i}{extension}"
28 | print(f"{file} => {new_name}")
29 | confirm = input("Press (y) to confirm or (n) to reject").strip().lower()
30 |
31 | if confirm != 'y':
32 | print("Cancel")
33 | return
34 |
35 | for i, file in enumerate(files, start=1):
36 | src = os.path.join(folder, file)
37 | new_name = f"{base_name}_{i}{extension}"
38 | dest = os.path.join(folder, new_name)
39 | os.rename(src, dest)
40 | print(f"Renamed {len(files)} files successfully")
41 |
42 | if __name__ == "__main__":
43 | folder = input("Enter folder path or learn blank for current folder: ").strip() or os.getcwd()
44 |
45 | if not os.path.isdir(folder):
46 | print("Invalid folder")
47 | else:
48 | base_name = input("Enter base name for files: ").strip()
49 | extension = input("Enter extension name for files: ").strip()
50 |
51 | batch_rename(folder, base_name, extension)
52 |
--------------------------------------------------------------------------------
/challenges/01_utilities/day_4.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Minutes Alive Calculator
3 |
4 | Write a Python script that calculates approximately how many minutes old a person is, based on their age in years.
5 |
6 | Your program should:
7 | 1. Ask the user for their age in years (accept float values too).
8 | 2. Convert that age into:
9 | - Total days
10 | - Total hours
11 | - Total minutes
12 | 3. Display the result in a readable format.
13 |
14 | Assumptions:
15 | - You can use 365.25 days/year to account for leap years.
16 | - You don't need to handle time zones or exact birthdates in this version.
17 |
18 | Example:
19 | Input:
20 | Age: 25
21 |
22 | Output:
23 | You are approximately:
24 | - 9,131 days old
25 | - 219,144 hours old
26 | - 13,148,640 minutes old
27 |
28 | Bonus:
29 | - Add comma formatting for large numbers
30 | - Let the user try again without restarting the program
31 | """
32 |
33 |
34 | def calculate_minutes(age_years):
35 | DAYS_IN_YEAR = 365.25
36 | HOURS_IN_DAY = 24
37 | MINUTES_IN_HOUR = 60
38 |
39 | total_days = age_years * DAYS_IN_YEAR
40 | total_hours = total_days * HOURS_IN_DAY
41 | total_minutes = total_hours * MINUTES_IN_HOUR
42 |
43 | return round(total_days), round(total_hours), round(total_minutes)
44 |
45 |
46 | while True:
47 | try:
48 | age = float(input("Enter your age in years: "))
49 | days, hours, minutes = calculate_minutes(age)
50 |
51 | print("\n You are approx:")
52 | print(f" - {days} days old")
53 | print(f" - {hours} hours old")
54 | print(f" - {minutes} minutes old\n")
55 |
56 | again = input("Would you like to try again? (y/n)").strip().lower()
57 |
58 | if again != 'y':
59 | print("Good bye!")
60 | break
61 | except:
62 | print("Please enter a valid number for age")
--------------------------------------------------------------------------------
/challenges/02_data_handling/day_6.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: JSON-to-CSV Converter Tool
3 |
4 | Create a Python utility that reads structured data (like you'd get from an API) from a `.json` file and converts it to a CSV file that can be opened in Excel.
5 |
6 | Your program should:
7 | 1. Read from a file named `api_data.json` in the same folder.
8 | 2. Convert the JSON content (a list of dictionaries) into `converted_data.csv`.
9 | 3. Automatically extract field names as CSV headers.
10 | 4. Handle nested structures by flattening or skipping them.
11 |
12 | Bonus:
13 | - Provide feedback on how many records were converted
14 | - Allow user to define which fields to extract
15 | - Handle missing fields gracefully
16 | """
17 | import json
18 | import csv
19 | import os
20 |
21 | INPUT_FILE = "api_data.json"
22 | OUTPUT_FILE = "converted_data.csv"
23 |
24 | def load_json_data(filename):
25 | if not os.path.exists(filename):
26 | print("JSON file not found")
27 | return []
28 |
29 | with open(filename, 'r', encoding="utf-8") as f:
30 | try:
31 | return json.load(f)
32 | except:
33 | print("Invalid JSON format")
34 |
35 | def convert_to_csv(data, output_file):
36 | if not data:
37 | print("No data to convert")
38 | return
39 |
40 | fieldname = list(data[0].keys())
41 |
42 | with open(output_file, "w", newline="", encoding="utf-8") as f:
43 | writer = csv.DictWriter(f, fieldnames=fieldname)
44 | writer.writeheader()
45 | for record in data:
46 | writer.writerow(record)
47 |
48 | print(f"Converted {len(data)} records to {output_file}")
49 |
50 |
51 | def main():
52 | print("Converting JSON to CSV....")
53 | data = load_json_data(INPUT_FILE)
54 | convert_to_csv(data, OUTPUT_FILE)
55 |
56 | if __name__ == "__main__":
57 | main()
--------------------------------------------------------------------------------
/challenges/01_utilities/day_8.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Password Strength Checker & Suggestion Tool
3 |
4 | Build a Python script that checks the strength of a password based on:
5 | 1. Length (at least 8 characters)
6 | 2. At least one uppercase letter
7 | 3. At least one lowercase letter
8 | 4. At least one digit
9 | 5. At least one special character (e.g., @, #, $, etc.)
10 |
11 | Your program should:
12 | - Ask the user to input a password.
13 | - Tell them what's missing if it's weak.
14 | - If the password is strong, confirm it.
15 | - Suggest a strong random password if the input is weak.
16 |
17 | Bonus:
18 | - Hide password input using `getpass` (no echo on screen).
19 | """
20 |
21 | import string
22 | import random
23 | import getpass
24 |
25 | def check_password_strength(password):
26 | issues = []
27 | if len(password) < 8:
28 | issues.append("Too short (minimum 8 characters)")
29 | if not any(c.islower() for c in password):
30 | issues.append("Missing lower case letter")
31 | if not any(c.isupper() for c in password):
32 | issues.append("Missing upper case letter")
33 | if not any(c.isdigit() for c in password):
34 | issues.append("Missing a digit")
35 | if not any(c in string.punctuation for c in password):
36 | issues.append("Missing a special character")
37 | return issues
38 |
39 |
40 | def generate_strong_password(length=12):
41 | chars = string.ascii_letters + string.digits + string.punctuation
42 |
43 | return "".join(random.choice(chars) for _ in range(length))
44 |
45 | password = getpass.getpass("Enter a password: ")
46 | issues = check_password_strength(password)
47 |
48 | if not issues:
49 | print("Strong password! you are good to go")
50 | else:
51 | print("You got weak password")
52 | for issue in issues:
53 | print(f"- {issue}")
54 |
55 | suggestion = generate_strong_password()
56 | print("\n suggesting you a strong password")
57 | print(suggestion)
--------------------------------------------------------------------------------
/challenges/05_data_science/experience_salary.csv:
--------------------------------------------------------------------------------
1 | YearsExperience,Salary
2 | 4.06,54708.19
3 | 9.53,85983.97
4 | 7.45,75067.04
5 | 6.19,59189.72
6 | 1.98,41001.31
7 | 1.98,43308.45
8 | 1.05,42211.58
9 | 8.73,80306.92
10 | 6.21,64026.03
11 | 7.23,71372.97
12 | 0.7,37861.61
13 | 9.71,89575.0
14 | 8.41,78340.96
15 | 2.52,47173.07
16 | 2.23,43768.31
17 | 2.24,47314.58
18 | 3.39,47531.79
19 | 5.49,61629.35
20 | 4.6,56031.57
21 | 3.27,43765.94
22 | 6.31,69044.48
23 | 1.83,42024.22
24 | 3.28,49700.45
25 | 3.98,52941.65
26 | 4.83,53318.52
27 | 7.96,76077.42
28 | 2.4,43029.14
29 | 5.39,59130.89
30 | 6.13,66134.86
31 | 0.94,37256.2
32 | 6.27,75164.74
33 | 2.12,43418.31
34 | 1.12,37750.2
35 | 9.51,86762.22
36 | 9.67,80344.92
37 | 8.18,78973.94
38 | 3.39,50580.92
39 | 1.43,48432.97
40 | 7.0,71230.56
41 | 4.68,59286.19
42 | 1.66,39821.15
43 | 5.2,56525.29
44 | 0.83,39551.29
45 | 9.14,87847.73
46 | 2.96,50924.13
47 | 6.79,67102.45
48 | 3.46,56371.18
49 | 5.44,57032.6
50 | 5.69,66487.43
51 | 2.26,52321.82
52 | 9.71,84297.85
53 | 7.86,74894.81
54 | 9.43,86978.61
55 | 9.0,81986.1
56 | 6.18,60877.35
57 | 9.26,85834.25
58 | 1.34,33790.79
59 | 2.36,46054.37
60 | 0.93,31902.3
61 | 3.59,57739.74
62 | 4.19,52006.99
63 | 3.08,47191.75
64 | 8.37,83474.07
65 | 3.89,48416.54
66 | 3.17,49929.84
67 | 5.66,69188.57
68 | 1.84,34610.07
69 | 8.12,79458.54
70 | 1.21,38299.53
71 | 9.88,92407.29
72 | 7.84,72092.2
73 | 2.39,39058.17
74 | 0.55,35387.77
75 | 8.25,80687.94
76 | 7.22,74321.97
77 | 7.43,75965.79
78 | 7.83,74259.9
79 | 1.2,38129.01
80 | 3.91,54632.29
81 | 1.6,36742.59
82 | 8.7,89663.1
83 | 6.42,70415.33
84 | 3.64,47074.79
85 | 1.1,39226.21
86 | 3.45,46801.27
87 | 3.59,54688.34
88 | 7.43,79214.38
89 | 6.56,66077.27
90 | 8.93,87433.5
91 | 4.99,61591.12
92 | 1.64,43128.24
93 | 7.28,81267.17
94 | 7.73,75398.45
95 | 5.83,61965.06
96 | 7.82,73361.94
97 | 5.19,57876.76
98 | 5.47,62511.59
99 | 4.56,58724.61
100 | 0.74,35546.76
101 | 1.52,42428.73
102 |
--------------------------------------------------------------------------------
/challenges/02_data_handling/day_8.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge : JSON Flattener
3 |
4 | {
5 | "user": {
6 | "id": 1,
7 | "name": "Riya",
8 | "email": "riya@example.com",
9 | "address": {
10 | "city": "Delhi",
11 | "pincode": 110001
12 | }
13 | },
14 | "roles": ["admin", "editor"],
15 | "is_active": true
16 | }
17 |
18 | Flatten this to:
19 |
20 | {
21 | "user.id": 1,
22 | "user.name": "Riya",
23 | "user.email": "riya@example.com",
24 | "user.address.city": "Delhi",
25 | "user.address.pincode": 110001,
26 | "roles.0": "admin",
27 | "roles.1": "editor",
28 | "is_active": true
29 | }
30 |
31 |
32 | """
33 |
34 | import json
35 | import os
36 |
37 | INPUT_FILE = "nested_data.json"
38 | OUTPUT_FILE = "flattened_data.json"
39 |
40 | def flatten_json(data, parent_key='', sep='.'):
41 | items = {}
42 |
43 | if isinstance(data, dict):
44 | for k, v in data.items():
45 | full_key = f"{parent_key}{sep}{k}" if parent_key else k
46 | print(full_key)
47 | items.update(flatten_json(v, full_key, sep=sep))
48 |
49 | elif isinstance(data, list):
50 | for idx, item in enumerate(data):
51 | full_key =f"{parent_key}{sep}{idx}" if parent_key else str(idx)
52 | items.update(flatten_json(item, full_key, sep=sep))
53 | else:
54 | items[parent_key] = data
55 |
56 | return items
57 |
58 | def main():
59 | if not os.path.exists(INPUT_FILE):
60 | print("No input file found")
61 | return
62 |
63 | try:
64 | with open(INPUT_FILE, 'r', encoding="utf-8") as f:
65 | data = json.load(f)
66 |
67 | sep = input("Enter your seperator like . or -: ").strip() or '.'
68 |
69 | flattened = flatten_json(data, sep=sep)
70 | with open(OUTPUT_FILE, 'w', encoding="utf-8") as f:
71 | json.dump(flattened, f, indent=2)
72 |
73 | print(f"Flattened JSON saved to {OUTPUT_FILE}")
74 | except Exception as e:
75 | print("Failed to faltten the data", e)
76 |
77 | if __name__ == "__main__":
78 | main()
--------------------------------------------------------------------------------
/challenges/01_utilities/day_10.py:
--------------------------------------------------------------------------------
1 | """
2 | Building a Caesar Cipher
3 |
4 | Challenge: Secret Message Encryptor & Decryptor
5 |
6 | Create a Python script that helps you send secret messages to your friend using simple encryption.
7 |
8 | Your program should:
9 | 1. Ask the user if they want to (E)ncrypt or (D)ecrypt a message.
10 | 2. If encrypting:
11 | - Ask for a message and a numeric secret key.
12 | - Use a Caesar Cipher (shift letters by the key value).
13 | - Output the encrypted message.
14 | 3. If decrypting:
15 | - Ask for the encrypted message and key.
16 | - Reverse the encryption to get the original message.
17 |
18 | Rules:
19 | - Only encrypt letters; leave spaces and punctuation as-is.
20 | - Make sure the letters wrap around (e.g., 'z' + 1 → 'a').
21 |
22 | Bonus:
23 | - Allow uppercase and lowercase letter handling
24 | - Show a clean interface
25 | """
26 | def encrypt(message, key):
27 | result = ""
28 | for char in message:
29 | if char.isalpha():
30 | base = ord('A') if char.isupper() else ord('a')
31 | shifted = (ord(char) - base + key) % 26 + base
32 | result += chr(shifted)
33 | else:
34 | result += char
35 | return result
36 |
37 | def decrypt(message, key):
38 | return encrypt(message, -key)
39 |
40 |
41 | print("Secret message program")
42 | choice = input("Do you want to E or D").strip().lower()
43 |
44 | if choice == "e":
45 | text = input("Enter your message: \n")
46 | try:
47 | key = int(input("Enter a number between 1 and 25: "))
48 | encrypted = encrypt(text, key)
49 | print("Encrypted message: ")
50 | print(encrypted)
51 | except ValueError:
52 | print("Invalid key")
53 | elif choice == 'd':
54 | text = input("Enter your encrypted message: \n")
55 | try:
56 | key = int(input("Enter a number between 1 and 25: "))
57 | decrypted = decrypt(text, key)
58 | print("Decrypted message: ")
59 | print(decrypted)
60 | except ValueError:
61 | print("Invalid key")
62 | else:
63 | print("Invalid choice")
--------------------------------------------------------------------------------
/challenges/03_web_scraping/day_06.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Quote of the Day Image Maker
3 |
4 | Goal:
5 | - Scrape random quotes from https://quotes.toscrape.com/
6 | - Extract quote text and author for the first 5 quotes
7 | - Create an image for each quote using PIL
8 | - Save images in 'quotes/' directory using filenames like quote_1.png, quote_2.png, etc.
9 |
10 |
11 | """
12 | import os
13 | import requests
14 | import textwrap
15 | from bs4 import BeautifulSoup
16 | from PIL import Image, ImageDraw, ImageFont
17 |
18 | BASE_URL = "https://quotes.toscrape.com/"
19 | OUTPUT_DIR = "quotes"
20 |
21 | def fetch_quotes():
22 | response = requests.get(BASE_URL)
23 | soup = BeautifulSoup(response.text, "html.parser")
24 | quotes = soup.select("div.quote")
25 |
26 | quote_data = []
27 |
28 | for q in quotes[:5]:
29 | text = q.find("span", class_="text").text.strip("“”")
30 | author = q.find("small", class_="author").text
31 |
32 | quote_data.append((text, author))
33 |
34 | return quote_data
35 |
36 | def create_image(text, author, index):
37 | width, height = 800, 400
38 | backgroud_color = "#f8d77f"
39 | text_color = "#262626"
40 |
41 | image = Image.new("RGB", (width, height), backgroud_color)
42 | draw = ImageDraw.Draw(image)
43 |
44 | font = ImageFont.load_default()
45 | author_font = ImageFont.load_default()
46 |
47 | wrapped = textwrap.fill(text, width=60)
48 | author_text = f"- {author}"
49 |
50 | y_text = 60
51 | draw.text((40, y_text), wrapped, font=font, fill=text_color)
52 | y_text += wrapped.count('\n') * 15 + 40
53 | draw.text((500, y_text), author_text, font=font, fill=text_color)
54 |
55 | # save image
56 | if not os.path.exists(OUTPUT_DIR):
57 | os.makedirs(OUTPUT_DIR)
58 |
59 | filename = os.path.join(OUTPUT_DIR, f"quote_{index+1}.png")
60 | image.save(filename)
61 | print(f"✅ saved: {filename}")
62 |
63 |
64 | def main():
65 | quotes = fetch_quotes()
66 | for idx, (text, author) in enumerate(quotes):
67 | create_image(text, author, idx)
68 |
69 | if __name__ == "__main__":
70 | main()
--------------------------------------------------------------------------------
/challenges/03_web_scraping/day_05.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Download Cover Images Using wget
3 |
4 | Goal:
5 | - Scrape https://books.toscrape.com/
6 | - Collect the first 10 books on the homepage
7 | - Extract the title and image URL for each book
8 | - Use the `wget` library to download and save images in a folder called 'images/'
9 | - Use book titles (sanitized) as image filenames
10 |
11 | Bonus:
12 | - Add progress for each download
13 | - Ensure folder is created if it doesn't exist
14 | """
15 |
16 | import os
17 | import requests
18 | from bs4 import BeautifulSoup
19 | from urllib.parse import urljoin
20 | import re
21 | import wget
22 |
23 | BASE_URL = "https://books.toscrape.com/"
24 | IMAGE_DIR = "images"
25 |
26 | def sanitize_filename(title):
27 | return re.sub(r'[^\w\-_. ]', '', title).replace(" ", "_")
28 |
29 | def download_image(img_url, filename):
30 | try:
31 | response = requests.get(img_url, stream=True, timeout=10)
32 | response.raise_for_status()
33 | with open(filename, 'wb') as f:
34 | for chunk in response.iter_content(8192):
35 | f.write(chunk)
36 | except Exception as e:
37 | print(f"Failed to download {filename} - {e}")
38 |
39 |
40 | def scrape_and_download_images():
41 | url = BASE_URL
42 | response = requests.get(url)
43 | soup = BeautifulSoup(response.text, "html.parser")
44 | books = soup.select("article.product_pod")[:10]
45 |
46 | if not os.path.exists(IMAGE_DIR):
47 | os.makedirs(IMAGE_DIR)
48 |
49 | for book in books:
50 | title = book.h3.a['title']
51 | relative_img = book.find("img")["src"]
52 | img_url = urljoin(BASE_URL, relative_img)
53 | print(f"url - {img_url}")
54 |
55 | filename = sanitize_filename(title) + ".jpg"
56 | filepath = os.path.join(IMAGE_DIR, filename)
57 | print(f"filepath - {filepath}")
58 |
59 | print(f"Downloading: {title}")
60 | # download_image(img_url, filepath)
61 | wget.download(img_url, filepath)
62 | print("All 10 books covers downloaded to images/")
63 |
64 | if __name__ == "__main__":
65 | scrape_and_download_images()
--------------------------------------------------------------------------------
/challenges/03_web_scraping/day_04.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Download Cover Images of First 10 Books
3 |
4 | Goal:
5 | - Visit https://books.toscrape.com/
6 | - Scrape the first 10 books listed on the homepage
7 | - For each book, extract:
8 | • Title
9 | • Image URL
10 |
11 | Then:
12 | - Download each image
13 | - Save it to a local `images/` folder with the filename as the book title (sanitized)
14 |
15 | Example:
16 | Title: "A Light in the Attic"
17 | Saved as: images/A_Light_in_the_Attic.jpg
18 |
19 | Bonus:
20 | - Handle invalid filename characters
21 | - Show download progress
22 | """
23 | import os
24 | import requests
25 | from bs4 import BeautifulSoup
26 | from urllib.parse import urljoin
27 | import re
28 |
29 | BASE_URL = "https://books.toscrape.com/"
30 | IMAGE_DIR = "images"
31 |
32 | def sanitize_filename(title):
33 | return re.sub(r'[^\w\-_. ]', '', title).replace(" ", "_")
34 |
35 | def download_image(img_url, filename):
36 | try:
37 | response = requests.get(img_url, stream=True, timeout=10)
38 | response.raise_for_status()
39 | with open(filename, 'wb') as f:
40 | for chunk in response.iter_content(8192):
41 | f.write(chunk)
42 | except Exception as e:
43 | print(f"Failed to download {filename} - {e}")
44 |
45 |
46 | def scrape_and_download_images():
47 | url = BASE_URL
48 | response = requests.get(url)
49 | soup = BeautifulSoup(response.text, "html.parser")
50 | books = soup.select("article.product_pod")[:10]
51 |
52 | if not os.path.exists(IMAGE_DIR):
53 | os.makedirs(IMAGE_DIR)
54 |
55 | for book in books:
56 | title = book.h3.a['title']
57 | relative_img = book.find("img")["src"]
58 | img_url = urljoin(BASE_URL, relative_img)
59 | print(f"url - {img_url}")
60 |
61 | filename = sanitize_filename(title) + ".jpg"
62 | filepath = os.path.join(IMAGE_DIR, filename)
63 | print(f"filepath - {filepath}")
64 |
65 | print(f"Downloading: {title}")
66 | download_image(img_url, filepath)
67 | print("All 10 books covers downloaded to images/")
68 |
69 | if __name__ == "__main__":
70 | scrape_and_download_images()
--------------------------------------------------------------------------------
/challenges/03_web_scraping/day_03.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Scrape Books To Scrape (70 Books)
3 |
4 | Goal:
5 | - Visit https://books.toscrape.com/
6 | - Scrape each book's:
7 | • Title
8 | • Price
9 |
10 | You must:
11 | - Crawl through multiple pages using the "next" button until you collect 70 books.
12 | - Save the data to a JSON file: books_data.json
13 | - Handle network errors gracefully.
14 |
15 | Bonus:
16 | - Track how many books scraped
17 | - Print progress as you collect pages
18 | """
19 |
20 |
21 | import requests
22 | from bs4 import BeautifulSoup
23 | import json
24 | from urllib.parse import urljoin
25 |
26 | BASE_URL = "https://books.toscrape.com/"
27 | START_PAGE = "catalogue/page-1.html"
28 | OUTPUT_PAGE = "books_data.json"
29 | TARGET_COUNT = 70
30 |
31 | def scrape_page(url):
32 | try:
33 | response = requests.get(url, timeout=10)
34 | response.raise_for_status()
35 | except requests.RequestException as e:
36 | print("Failed to fetch url")
37 | return [], None
38 |
39 | soup = BeautifulSoup(response.text, "html.parser")
40 | books = []
41 |
42 | for article in soup.select("article.product_pod"):
43 | title_tag = article.select_one("h3 > a")
44 | title = title_tag.get("title")
45 | price = article.select_one("p.price_color").text.strip()
46 | # print(f"{title} - {price}")
47 | books.append({"title":title, "price":price})
48 |
49 | next_link = soup.select_one("li.next > a")
50 | next_url = urljoin(url, next_link.get("href")) if next_link else None
51 |
52 | return books, next_url
53 |
54 |
55 | def main():
56 | collected = []
57 | current_url = urljoin(BASE_URL, START_PAGE)
58 |
59 | while len(collected) < TARGET_COUNT and current_url:
60 | print(f"Scrapping: {current_url}")
61 | books, next_url = scrape_page(current_url)
62 | collected.extend(books)
63 | current_url = next_url
64 |
65 | collected = collected[:TARGET_COUNT]
66 | print(f"scrapped {len(collected)} books")
67 |
68 | with open(OUTPUT_PAGE, "w", encoding="utf-8") as f:
69 | json.dump(collected, f, indent=2)
70 |
71 | print(f"Data save to {OUTPUT_PAGE}")
72 |
73 |
74 | if __name__ == "__main__":
75 | main()
76 |
--------------------------------------------------------------------------------
/challenges/02_data_handling/day_2.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Student Marks Analyzer
3 |
4 | Create a Python program that allows a user to input student names along with their marks and then calculates useful statistics.
5 |
6 | Your program should:
7 | 1. Let the user input multiple students with their marks (name + integer score).
8 | 2. After input is complete, display:
9 | - Average marks
10 | - Highest marks and student(s) who scored it
11 | - Lowest marks and student(s) who scored it
12 | - Total number of students
13 |
14 | Bonus:
15 | - Allow the user to enter all data first, then view the report
16 | - Format output clearly in a report-style layout
17 | - Prevent duplicate student names
18 | """
19 |
20 | def collect_student_data():
21 | students = {}
22 |
23 | while True:
24 | name = input("Enter the student name or done to exit: ").strip()
25 |
26 | if name.lower() == "done":
27 | break
28 | if name in students:
29 | print("Student already exists")
30 | continue
31 |
32 | try:
33 | marks = float(input(f"Enter marks for {name}: "))
34 | students[name] = marks
35 | except ValueError:
36 | print("Please enter a valid number for marks")
37 |
38 | return students
39 |
40 |
41 | def display_report(students):
42 | if not students:
43 | print("No student data ❌")
44 | return
45 |
46 | marks = list(students.values())
47 | max_score = max(marks)
48 | min_score = min(marks)
49 | average = sum(marks) / len(marks)
50 |
51 | topper = [name for name, score in students.items() if score == max_score ]
52 | bottomer = [name for name, score in students.items() if score == min_score ]
53 |
54 | print("\n Students marks report 🗓️")
55 | print("-" * 30)
56 | print(f"Total students: {len(students)}")
57 | print(f"average marks for students: {average:.2f}")
58 | print(f"Highest marks : {max_score} by {', '.join(topper)}")
59 | print(f"lowest marks : {min_score} by {', '.join(bottomer)}")
60 |
61 | print("-" * 30)
62 | print("Detailed Marks 🗓️")
63 | for name, score in students.items():
64 | print(f" - {name}: {score}")
65 |
66 |
67 | students = collect_student_data()
68 | display_report(students)
--------------------------------------------------------------------------------
/challenges/01_utilities/day_2.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Stylish Bio Generator for Instagram/Twitter
3 |
4 | Create a Python utility that asks the user for a few key details and generates a short, stylish bio that could be used for social media profiles like Instagram or Twitter.
5 |
6 | Your program should:
7 | 1. Prompt the user to enter their:
8 | - Name
9 | - Profession
10 | - One-liner passion or goal
11 | - Favorite emoji (optional)
12 | - Website or handle (optional)
13 |
14 | 2. Generate a stylish 2-3 line bio using the inputs. It should feel modern, concise, and catchy.
15 |
16 | 3. Add optional hashtags or emojis for flair.
17 |
18 | Example:
19 | Input:
20 | Name: Riya
21 | Profession: Designer
22 | Passion: Making things beautiful
23 | Emoji: 🎨
24 | Website: @riya.design
25 |
26 | Output:
27 | 🎨 Riya | Designer
28 | 💡 Making things beautiful
29 | 🔗 @riya.design
30 |
31 | Bonus:
32 | - Let the user pick from 2-3 different layout styles.
33 | - Ask the user if they want to save the result into a `.txt` file.
34 | """
35 |
36 | import textwrap
37 | name = input("Enter your name: ").strip()
38 | profession = input("Enter your profession: ").strip()
39 | passion = input("Enter your passion in one line: ").strip()
40 | emoji = input("Enter your favourite emoji: ").strip()
41 | website = input("Enter your website: ").strip()
42 |
43 | print("\nChoose your style: ")
44 | print("1. Simple lines ")
45 | print("2. Vertical flair ")
46 | print("3. Emoji sandwich ")
47 |
48 | style = input("Enter 1, 2 or 3: ").strip()
49 |
50 | def generate_bio(style):
51 | if style == "1":
52 | return f"{emoji} {name} | {profession} \n💡 {passion}\n {website}"
53 | elif style == "2":
54 | return f"{emoji} {name}\n {profession}🔥\n {passion} \n {website}🔥"
55 | elif style == "3":
56 | return f"{emoji*3}\n {name} - {profession}\n {passion}\n {website} \n {emoji*3}"
57 |
58 | bio = generate_bio(style)
59 |
60 | print("\nYour stylish bio:\n")
61 | print("*" * 50)
62 | print(textwrap.dedent(bio))
63 | print("*" * 50)
64 |
65 | save = input("Do you want to save this bio to a text file? (y/n): ").lower()
66 |
67 | if save == 'y':
68 | filename = f"{name.lower().replace(' ', '_')}_bio.txt"
69 | with open(filename, "w", encoding="utf-8") as f:
70 | f.write(bio)
71 | print("file saved")
--------------------------------------------------------------------------------
/challenges/03_web_scraping/hn_top20.csv:
--------------------------------------------------------------------------------
1 | title,url
2 | Andrej Karpathy's YC AI SUS talk on the future of the industry,https://www.donnamagi.com/articles/karpathy-yc-talk
3 | The unreasonable effectiveness of fuzzing for porting programs,https://rjp.io/blog/2025-06-17-unreasonable-effectiveness-of-fuzzing
4 | Show HN: Workout.cool – Open-source fitness coaching platform,https://github.com/Snouzy/workout-cool
5 | My iPhone 8 Refuses to Die: Now It's a Solar-Powered Vision OCR Server,https://terminalbytes.com/iphone-8-solar-powered-vision-ocr-server/
6 | Writing documentation for AI: best practices,https://docs.kapa.ai/improving/writing-best-practices
7 | Show HN: I built a tensor library from scratch in C++/CUDA,https://github.com/nirw4nna/dsc
8 | Poline – An enigmatic color palette generator using polar coordinates,https://meodai.github.io/poline/
9 | Homomorphically Encrypting CRDTs,https://jakelazaroff.com/words/homomorphically-encrypted-crdts/
10 | Introduction to the A* Algorithm (2014),https://www.redblobgames.com/pathfinding/a-star/introduction.html
11 | Terpstra Keyboard,http://terpstrakeyboard.com/web-app/keys.htm
12 | "MiniMax-M1 open-weight, large-scale hybrid-attention reasoning model",https://github.com/MiniMax-AI/MiniMax-M1
13 | Is There a Half-Life for the Success Rates of AI Agents?,https://www.tobyord.com/writing/half-life
14 | Revisiting Minsky's Society of Mind in 2025,https://suthakamal.substack.com/p/revisiting-minskys-society-of-mind
15 | Framework Laptop 12 review,https://arstechnica.com/gadgets/2025/06/framework-laptop-12-review-im-excited-to-see-what-the-2nd-generation-looks-like/
16 | Attimet (YC F24) – Quant Trading Research Lab – Is Hiring Founding Engineer,https://www.ycombinator.com/companies/attimet/jobs/b1w9pjE-founding-engineer
17 | Scrappy – Make little apps for you and your friends,https://pontus.granstrom.me/scrappy/
18 | Locally hosting an internet-connected server,https://mjg59.dreamwidth.org/72095.html
19 | I counted all of the yurts in Mongolia using machine learning,https://monroeclinton.com/counting-all-yurts-in-mongolia/
20 | Spatializing 6k years of global urbanization from 3700 BC to AD 2000,https://www.nature.com/articles/sdata201634
21 | "After millions of years, why are carnivorous plants still so small?",https://www.smithsonianmag.com/articles/carnivorous-plants-have-been-trapping-animals-for-millions-of-years-so-why-have-they-never-grown-larger-180986708/
22 |
--------------------------------------------------------------------------------
/challenges/03_web_scraping/day_07.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Crypto Price Tracker with Graphs
3 |
4 | Goal:
5 | - Fetch live prices of the top 10 cryptocurrencies using CoinGecko's free public API
6 | - Store prices in a CSV file with timestamp
7 | - Generate a line graph for a selected coin over time (price vs. time)
8 | - Repeatable — user can run this multiple times to log data over time
9 |
10 | JSON handling, API usage, CSV storage, matplotlib graphing
11 | """
12 | import os
13 | import csv
14 | from datetime import datetime
15 | import requests
16 | import matplotlib.pyplot as plt
17 |
18 |
19 | API_URL = "https://api.coingecko.com/api/v3/coins/markets"
20 |
21 | PARAMS = {
22 | 'vs_currency': 'usd',
23 | 'order': 'market_cap_desc',
24 | 'per_page':10,
25 | 'page':1,
26 | 'sparkline':False
27 | }
28 |
29 | CSV_FILE = 'crypto_prices.csv'
30 |
31 | def fetch_crypto_data():
32 | response = requests.get(API_URL, params=PARAMS)
33 | return response.json()
34 |
35 | def save_to_csv(data):
36 | file_exists = os.path.isfile(CSV_FILE)
37 |
38 | with open(CSV_FILE, 'a', newline='') as file:
39 | writer = csv.writer(file)
40 | if not file_exists:
41 | writer.writerow(["timestamp", "coin", "price"])
42 |
43 | timestamp = datetime.now().strftime("%Y-%m-%d %H-%M-%S")
44 | for coin in data:
45 | writer.writerow([timestamp, coin["id"], coin['current_price']])
46 | print("✅ data saved to csv")
47 |
48 |
49 | def plot_graph(coin_id):
50 | times = []
51 | prices = []
52 |
53 | with open(CSV_FILE, newline='') as file:
54 | reader = csv.DictReader(file)
55 | for row in reader:
56 | if row["coin"] == coin_id:
57 | times.append(row['timestamp'])
58 | prices.append(float(row['price']))
59 |
60 | if not times:
61 | print(f"No data found for {coin_id}")
62 | return
63 |
64 | plt.figure(figsize=(10,5))
65 | plt.plot(times, prices, marker='o')
66 | plt.tight_layout()
67 | plt.grid()
68 | plt.show()
69 |
70 |
71 | def main():
72 | print("Fetching live crypto data....")
73 | crypto_data = fetch_crypto_data()
74 | save_to_csv(crypto_data)
75 |
76 | print("-" * 30)
77 | for coin in crypto_data:
78 | print(f"{coin['id']} - ${coin['current_price']}")
79 | print("-" * 30)
80 |
81 | choice = input("Enter the coinname to get graph: ").strip().lower()
82 |
83 | if choice:
84 | plot_graph(choice)
85 |
86 |
87 | if __name__ == "__main__":
88 | main()
--------------------------------------------------------------------------------
/challenges/05_data_science/day_08.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 |
3 | data = [
4 | {
5 | "title": "The Silent Forest",
6 | "author": "Jane Hill",
7 | "genre": "Mystery",
8 | "description": "A detective uncovers secrets hidden deep in the woods while chasing a serial killer."
9 | },
10 | {
11 | "title": "Spacebound",
12 | "author": "Rico Vega",
13 | "genre": "Science Fiction",
14 | "description": "An astronaut embarks on a mission to Mars but discovers an ancient alien presence."
15 | },
16 | {
17 | "title": "Love in Paris",
18 | "author": "Emily Rose",
19 | "genre": "Romance",
20 | "description": "A love story between a local baker and a traveler unfolds in the heart of Paris."
21 | },
22 | {
23 | "title": "Quantum Heist",
24 | "author": "Leo Hunt",
25 | "genre": "Thriller",
26 | "description": "A group of hackers plans a digital heist targeting the world's most secure quantum server."
27 | },
28 | {
29 | "title": "Mystic Academy",
30 | "author": "Lara Moon",
31 | "genre": "Fantasy",
32 | "description": "A young girl discovers she has magical powers and is taken to an academy for gifted spellcasters."
33 | },
34 | {
35 | "title": "The Digital Mind",
36 | "author": "Alan Neural",
37 | "genre": "Science Fiction",
38 | "description": "An AI begins to question its creators and the meaning of consciousness."
39 | },
40 | {
41 | "title": "Fog Over London",
42 | "author": "Claire Black",
43 | "genre": "Mystery",
44 | "description": "Set in Victorian London, a private investigator unravels political conspiracies amid murders."
45 | },
46 | {
47 | "title": "Beneath the Waves",
48 | "author": "Diana Coast",
49 | "genre": "Adventure",
50 | "description": "An underwater archaeologist discovers an ancient city lost in the ocean."
51 | },
52 | {
53 | "title": "Heart Strings",
54 | "author": "Ella Harmony",
55 | "genre": "Romance",
56 | "description": "Two musicians from rival bands fall in love during a national tour."
57 | },
58 | {
59 | "title": "Dark Code",
60 | "author": "Nick Cipher",
61 | "genre": "Thriller",
62 | "description": "A cybersecurity expert is drawn into a global web of espionage and hidden messages."
63 | }
64 | ]
65 |
66 | df = pd.DataFrame(data)
67 | df.to_csv("books.csv", index=False)
68 | print("✅ Book dataset created")
--------------------------------------------------------------------------------
/challenges/02_data_handling/day_9.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Offline Credential Manager
3 |
4 | Create a CLI tool to manage login credentials (website, username, password) in an encoded local file (`vault.txt`).
5 |
6 | Your program should:
7 | 1. Add new credentials (website, username, password)
8 | 2. Automatically rate password strength (weak/medium/strong)
9 | 3. Encode the saved content using Base64 for simple offline obfuscation
10 | 4. View all saved credentials (decoding them)
11 | 5. Update password for any existing website entry (assignment)
12 |
13 | Bonus:
14 | - Support searching for a website entry
15 | - Mask password when showing in the list
16 | """
17 |
18 | import base64
19 | import os
20 |
21 | VAULT_FILE = "vault.txt"
22 |
23 | def encode(text):
24 | return base64.b64encode(text.encode()).decode()
25 |
26 | def decode(text):
27 | return base64.b64decode(text.encode()).decode()
28 |
29 | def password_strength(password):
30 | length = len(password)
31 | has_upper = any(c.isupper() for c in password)
32 | has_digit = any(c.isdigit() for c in password)
33 | has_special = any(c in "!@#$%^&*().,<>" for c in password)
34 |
35 | score = sum([length >= 8, has_upper, has_digit, has_special])
36 | return ["Weak", "Medium", "Strong", "Very Strong"][min(score, 3)]
37 |
38 |
39 | def add_credential():
40 | website = input("Website: ").strip()
41 | username = input("Username: ").strip()
42 | password = input("Password: ").strip()
43 |
44 | strength = password_strength(password)
45 |
46 | line = f"{website}||{username}||{password}"
47 | encoded_line = encode(line)
48 |
49 | with open(VAULT_FILE, 'a', encoding="utf-8") as f:
50 | f.write(encoded_line + "\n")
51 |
52 | print("✅ Credential saved")
53 |
54 | def view_credentials():
55 | if not os.path.exists(VAULT_FILE):
56 | print("File not found")
57 | return
58 |
59 | with open(VAULT_FILE, 'r', encoding="utf-8") as f:
60 | for line in f:
61 | decoded = decode(line.strip())
62 | website, username, password = decoded.split("||")
63 | hidden_password = '*' * len(password)
64 | print(f"{website} | {username} | {password}")
65 |
66 |
67 | def main():
68 | while True:
69 | print("\n🔒 Credential Manager")
70 | print("1. Add credential")
71 | print("2. View credentials")
72 | print("3. Update password")
73 | print("4. Exit")
74 |
75 | choice = input("Enter your choice: ")
76 |
77 | match choice:
78 | case "1": add_credential()
79 | case "2": view_credentials()
80 | case "4": break
81 | case _: print("Invalid choice")
82 |
83 | if __name__ == "__main__":
84 | main()
--------------------------------------------------------------------------------
/challenges/03_web_scraping/day_09.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Store & Search Crypto Prices in SQLite
3 |
4 | Goal:
5 | - Save hourly top 10 crypto prices into a local SQLite database
6 | - Each record should include timestamp, coin ID, and price
7 | - Allow the user to search for a coin by name and return the latest price
8 |
9 | Teaches: SQLite handling in Python, data storage, search queries, API + DB integration
10 | """
11 | import os
12 | import csv
13 | from datetime import datetime
14 | import requests
15 | import schedule
16 | import time
17 | import sqlite3
18 |
19 | API_URL = "https://api.coingecko.com/api/v3/coins/markets"
20 |
21 | PARAMS = {
22 | 'vs_currency': 'usd',
23 | 'order': 'market_cap_desc',
24 | 'per_page':10,
25 | 'page':1,
26 | 'sparkline':False
27 | }
28 |
29 | DB_NAME = 'crypto.db'
30 |
31 | def fetch_crypto_data():
32 | response = requests.get(API_URL, params=PARAMS)
33 | return response.json()
34 |
35 | def create_table():
36 | conn = sqlite3.connect(DB_NAME)
37 | cursor = conn.cursor()
38 | cursor.execute('''
39 | CREATE TABLE IF NOT EXISTS crypto_prices (
40 | id INTEGER PRIMARY KEY AUTOINCREMENT,
41 | timestamp TEXT,
42 | coin TEXT,
43 | price REAL
44 | )
45 | ''')
46 | conn.commit()
47 | conn.close()
48 |
49 | def save_to_database(data):
50 | conn = sqlite3.connect(DB_NAME)
51 | cursor = conn.cursor()
52 | timestamp = datetime.now().strftime("%Y-%m-%d %H-%M-%S")
53 | for coin in data:
54 | cursor.execute('''
55 | INSERT INTO crypto_prices (timestamp, coin, price)
56 | VALUES (?, ?, ?)
57 | ''', (timestamp, coin['id'], coin['current_price']))
58 |
59 | conn.commit()
60 | conn.close()
61 | print("Price saved to database")
62 |
63 | def search_coin(coin_name):
64 | conn = sqlite3.connect(DB_NAME)
65 | cursor = conn.cursor()
66 | cursor.execute('''
67 | SELECT timestamp, price FROM crypto_prices
68 | WHERE coin = ?
69 | ORDER BY timestamp DESC
70 | LIMIT 1
71 | ''', (coin_name, ))
72 | result = cursor.fetchone()
73 | conn.close()
74 | # print("RESULT RAW", result)
75 | if result:
76 | print(f"${result[1]} - {result[0]}")
77 |
78 |
79 | def main():
80 | create_table()
81 | print("1. Fetch and store crypto data")
82 | print("2. Search latest price for a coin")
83 |
84 | choice = input("Choose an option: ").strip()
85 |
86 | if choice == "1":
87 | data = fetch_crypto_data()
88 | save_to_database(data)
89 | elif choice == "2":
90 | coin_name = input("Enter coin name: ").strip().lower()
91 | search_coin(coin_name)
92 | else:
93 | print("Invalid option")
94 |
95 |
96 | main()
--------------------------------------------------------------------------------
/challenges/06_url_shortner/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Chaicode URL shortner
7 |
8 |
9 |
10 |
11 |
12 | Python URL shortner
13 |
14 |
32 |
All shorten URLs
33 | {% if all_urls %}
34 |
35 |
36 |
37 |
38 | | Short URL |
39 | Original URL |
40 | Visits |
41 | Action |
42 |
43 |
44 |
45 | {% for url in all_urls%}
46 |
47 | |
48 |
49 | http://localhost:5000/{{url[1]}}
50 |
51 | |
52 | {{url[0]}} |
53 | {{url[2]}} |
54 |
55 |
62 | |
63 |
64 | {% endfor%}
65 |
66 |
67 |
68 | {% else %}
69 |
No Urls have been shorten
70 |
71 | {% endif%}
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/challenges/05_data_science/youtube_comments.csv:
--------------------------------------------------------------------------------
1 | comment,label
2 | Worst video ever,toxic
3 | You're amazing!,support
4 | Stop making content,toxic
5 | So clear and helpful,support
6 | Waste of time,toxic
7 | Awesome explanation,support
8 | You're so dumb,toxic
9 | You're amazing!,support
10 | Cringe content,toxic
11 | I learned a lot!,support
12 | Clickbait title,toxic
13 | Thanks for the content!,support
14 | Cringe content,toxic
15 | Keep up the great work,support
16 | Worst video ever,toxic
17 | Keep up the great work,support
18 | You're so dumb,toxic
19 | You're amazing!,support
20 | You're so dumb,toxic
21 | Best tutorial I've seen,support
22 | Waste of time,toxic
23 | I learned a lot!,support
24 | Cringe content,toxic
25 | You're amazing!,support
26 | Cringe content,toxic
27 | So clear and helpful,support
28 | Cringe content,toxic
29 | I learned a lot!,support
30 | Cringe content,toxic
31 | I learned a lot!,support
32 | You're so dumb,toxic
33 | Legend!,support
34 | Can't believe people like this,toxic
35 | Much appreciated!,support
36 | You're so dumb,toxic
37 | You're amazing!,support
38 | Stop making content,toxic
39 | Awesome explanation,support
40 | Worst video ever,toxic
41 | Legend!,support
42 | Waste of time,toxic
43 | I learned a lot!,support
44 | This is trash,toxic
45 | Best tutorial I've seen,support
46 | Stop making content,toxic
47 | This helped me a lot!,support
48 | Worst video ever,toxic
49 | Much appreciated!,support
50 | Clickbait title,toxic
51 | I learned a lot!,support
52 | Clickbait title,toxic
53 | Legend!,support
54 | You're such a loser,toxic
55 | Thanks for the content!,support
56 | Waste of time,toxic
57 | Awesome explanation,support
58 | Worst video ever,toxic
59 | Keep up the great work,support
60 | This is trash,toxic
61 | So clear and helpful,support
62 | You're so dumb,toxic
63 | Best tutorial I've seen,support
64 | Clickbait title,toxic
65 | Awesome explanation,support
66 | You're so dumb,toxic
67 | Legend!,support
68 | Stop making content,toxic
69 | Much appreciated!,support
70 | This is trash,toxic
71 | Legend!,support
72 | Clickbait title,toxic
73 | So clear and helpful,support
74 | Waste of time,toxic
75 | You're amazing!,support
76 | You're so dumb,toxic
77 | Thanks for the content!,support
78 | You're such a loser,toxic
79 | Much appreciated!,support
80 | Cringe content,toxic
81 | Best tutorial I've seen,support
82 | You sound horrible,toxic
83 | Keep up the great work,support
84 | Stop making content,toxic
85 | You're amazing!,support
86 | This is trash,toxic
87 | I learned a lot!,support
88 | Clickbait title,toxic
89 | I learned a lot!,support
90 | Stop making content,toxic
91 | I learned a lot!,support
92 | You sound horrible,toxic
93 | Legend!,support
94 | Stop making content,toxic
95 | So clear and helpful,support
96 | Clickbait title,toxic
97 | Awesome explanation,support
98 | Waste of time,toxic
99 | Much appreciated!,support
100 | You're so dumb,toxic
101 | So clear and helpful,support
102 |
--------------------------------------------------------------------------------
/challenges/02_data_handling/day_4.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Real-Time Weather Logger (API + CSV)
3 |
4 | Build a Python CLI tool that fetches real-time weather data for a given city and logs it to a CSV file for daily tracking.
5 |
6 | Your program should:
7 | 1. Ask the user for a city name.
8 | 2. Fetch weather data using the OpenWeatherMap API.
9 | 3. Store the following in a CSV file (`weather_log.csv`):
10 | - Date (auto-filled as today's date)
11 | - City
12 | - Temperature (in °C)
13 | - Weather condition (e.g., Clear, Rain)
14 | 4. Prevent duplicate entries for the same city on the same day.
15 | 5. Allow users to:
16 | - Add new weather log
17 | - View all logs
18 | - Show average, highest, lowest temperatures, and most frequent condition
19 |
20 | Bonus:
21 | - Format the output like a table
22 | - Handle API failures and invalid city names gracefully
23 | """
24 |
25 | import os
26 | import csv
27 | from datetime import datetime
28 | import requests
29 |
30 | FILENAME = "weather_logs.csv"
31 | API_KEY = "Get Your own key here"
32 | # keys are usually hidden in .env file but that is for later
33 |
34 | if not os.path.exists(FILENAME):
35 | with open(FILENAME, "w", newline='', encoding="utf-8") as f:
36 | writer = csv.writer(f)
37 | writer.writerow(["Date", "City", "Temperature", "Condition"])
38 |
39 | def log_weather():
40 | city = input("Enter your city name: ").strip()
41 | date = datetime.now().strftime("%Y-%m-%d")
42 |
43 | with open(FILENAME, "r", newline='', encoding="utf-8") as f:
44 | reader = csv.DictReader(f)
45 | for row in reader:
46 | if row["Date"] == date and row['City'].lower() == city.lower():
47 | print("Entry for this city and date exists")
48 | return
49 |
50 | try:
51 | url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={API_KEY}&units=metric"
52 | response = requests.get(url)
53 | data = response.json()
54 |
55 | if response.status_code != 200:
56 | print(f"API Error ")
57 | return
58 | temp = data["main"]["temp"]
59 | condition = data["weather"][0]["main"]
60 |
61 | with open(FILENAME, "a", newline='', encoding="utf-8") as f:
62 | writer = csv.writer(f)
63 | writer.writerow([date, city.title(), temp, condition])
64 | print(f"Logged: {temp} {condition} in {city.title()} on {date}")
65 | except Exception as e:
66 | print("Failed to make API call")
67 |
68 |
69 | def view_logs():
70 | with open(FILENAME, "r", encoding="utf-8") as f:
71 | reader = list(csv.reader(f))
72 | if len(reader) <=1:
73 | print("No Entries")
74 | return
75 | for row in reader[1:]:
76 | print(f"{row[0]} : {row[1]} : {row[2]} : {row[3]}")
77 |
78 |
79 | def main():
80 | while True:
81 | print("Real time weather logger")
82 | print("1. Add weather log")
83 | print("2. View weather log")
84 |
85 | choice = input("Choose an option: ").strip()
86 |
87 | match choice:
88 | case "1": log_weather()
89 | case "2": view_logs()
90 | case _: print("Invalid choice")
91 |
92 |
93 | if __name__ == "__main__":
94 | main()
--------------------------------------------------------------------------------
/challenges/02_data_handling/day_3.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Personal Movie Tracker with JSON
3 |
4 | Create a Python CLI tool that lets users maintain their own personal movie database, like a mini IMDb.
5 |
6 | Your program should:
7 | 1. Store all movie data in a `movies.json` file.
8 | 2. Each movie should have:
9 | - Title
10 | - Genre
11 | - Rating (out of 10)
12 | 3. Allow the user to:
13 | - Add a movie
14 | - View all movies
15 | - Search movies by title or genre
16 | - Exit the app
17 |
18 | Bonus:
19 | - Prevent duplicate titles from being added
20 | - Format output in a clean table
21 | - Use JSON for reading/writing structured data
22 | """
23 |
24 | import os
25 | import json
26 |
27 | FILENAME = "movies.json"
28 |
29 | def load_movies():
30 | if not os.path.exists(FILENAME):
31 | return []
32 | with open(FILENAME, "r", encoding="utf-8") as f:
33 | return json.load(f)
34 |
35 | def save_movies(movies):
36 | with open(FILENAME, "w", encoding="utf-8") as f:
37 | json.dump(movies, f, indent=2)
38 |
39 |
40 | def add_movies(movies):
41 | title = input("Enter the movie name: ").strip().lower()
42 |
43 | if any(movie["title"].lower() == title for movie in movies):
44 | print("Movie already exists")
45 | return
46 | genre = input("Genre: ").strip().lower()
47 | try:
48 | rating = float(input("Enter rating(0-10): "))
49 | if not (0 <= rating <= 10):
50 | raise ValueError
51 | except ValueError:
52 | print("Please enter valid number")
53 | return
54 |
55 | movies.append({"title": title, "genre": genre, "rating": rating})
56 | save_movies(movies)
57 | print("Movie added ✅")
58 |
59 |
60 | def search_movies(movies):
61 | term = input("Enter the title or genre: ").strip().lower()
62 |
63 | results = [
64 | movie for movie in movies
65 | if term in movie['title'].lower() or term in movie['genre'].lower()
66 |
67 | ]
68 | if not results:
69 | print("No matching result")
70 | return
71 | print(f" Found {len(results)} result(s)")
72 |
73 | for movie in results:
74 | print(f"{movie["title"]} -- {movie["genre"]} -- {movie["rating"]}")
75 |
76 |
77 | def view_movies(movies):
78 | if not movies:
79 | print("NO movies in DB")
80 | return
81 | print("-"*30)
82 | for movie in movies:
83 | print(f"{movie["title"]} -- {movie["genre"]} -- {movie["rating"]}")
84 | print("-"*30)
85 |
86 |
87 |
88 | def run_movie_db():
89 | movies = load_movies()
90 |
91 | while True:
92 | print("\n🍿 MyMovieDB")
93 | print("1. Add Movie")
94 | print("2. View All Movies")
95 | print("3. Search Movie")
96 | print("4. Exit")
97 |
98 | choice = input("Choose an option (1-4): ").strip()
99 | match choice:
100 | case "1": add_movies(movies)
101 | case "2": view_movies(movies)
102 | case "3": search_movies(movies)
103 | case "4": break
104 | case _: print("Enter valid choice")
105 |
106 |
107 | if __name__ == "__main__":
108 | run_movie_db()
--------------------------------------------------------------------------------
/challenges/02_data_handling/day_1.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: CLI Contact Book (CSV-Powered)
3 |
4 | Create a terminal-based contact book tool that stores and manages contacts using a CSV file.
5 |
6 | Your program should:
7 | 1. Ask the user to choose one of the following options:
8 | - Add a new contact
9 | - View all contacts
10 | - Search for a contact by name
11 | - Exit
12 | 2. Store contacts in a file called `contacts.csv` with columns:
13 | - Name
14 | - Phone
15 | - Email
16 | 3. If the file doesn't exist, create it automatically.
17 | 4. Keep the interface clean and clear.
18 |
19 | Example:
20 | Add Contact
21 | View All Contacts
22 | Search Contact
23 | Exit
24 |
25 | Bonus:
26 | - Format the contact list in a table-like view
27 | - Allow partial match search
28 | - Prevent duplicate names from being added
29 | """
30 |
31 | import csv
32 | import os
33 |
34 | FILENAME = "contacts.csv"
35 |
36 | if not os.path.exists(FILENAME):
37 | with open(FILENAME, "w", newline="", encoding="utf-8") as f:
38 | writer = csv.writer(f)
39 | writer.writerow(["Name", "Phone", "Email"])
40 |
41 | def add_contact():
42 | name = input("Name: ").strip()
43 | phone = input("Phone: ").strip()
44 | email = input("Email: ").strip()
45 |
46 | #check for duplicates
47 | with open(FILENAME, 'r', encoding="utf-8") as f:
48 | reader = csv.DictReader(f)
49 | for row in reader:
50 | if row["Name"].lower() == name.lower():
51 | print("Contact name already exists")
52 | return
53 |
54 | with open(FILENAME, 'a', encoding="utf-8") as f:
55 | writer = csv.writer(f)
56 | writer.writerow([name, phone, email])
57 | print("Contact added")
58 |
59 |
60 | def view_contacts():
61 | with open(FILENAME, 'r', encoding="utf-8") as f:
62 | reader = csv.reader(f)
63 | rows = list(reader)
64 |
65 | if len(rows) < 1:
66 | print("No contacts found")
67 | return
68 |
69 | print("\n Your contacts: \n")
70 |
71 | for row in rows[1:]:
72 | print(f"{row[0]} | {row[1]} | {row[2]}")
73 | print()
74 |
75 | def search_contact():
76 | term = input("Enter the name to search: ").strip().lower()
77 | found = False
78 |
79 | with open(FILENAME, 'r', encoding="utf-8") as f:
80 | reader = csv.DictReader(f)
81 | for row in reader:
82 | if term in row["Name"].lower():
83 | print(f"{row["Name"]} | 📞 {row["Phone"]}")
84 | found = True
85 |
86 | if not found:
87 | print("No matching contact found")
88 |
89 |
90 |
91 | def main():
92 |
93 | while True:
94 | print("\n📒 Contact Book")
95 | print("1. Add Contact")
96 | print("2. View All Contacts")
97 | print("3. Search Contact")
98 | print("4. Exit")
99 |
100 | choice = input("Choose an option (1-4)").strip()
101 |
102 | if choice == "1":
103 | add_contact()
104 | elif choice == "2":
105 | view_contacts()
106 | elif choice == "3":
107 | search_contact()
108 | elif choice == "4":
109 | print("Thanks for using our software")
110 | break
111 | else:
112 | print("Invalid choice of number")
113 |
114 |
115 | if __name__ == "__main__":
116 | main()
117 |
--------------------------------------------------------------------------------
/challenges/02_data_handling/day_10.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Offline Notes Locker
3 |
4 | Create a terminal-based app that allows users to save, view, and search personal notes securely in an encrypted file.
5 |
6 | Your program should:
7 | 1. Let users add notes with title and content.
8 | 2. Automatically encrypt each note using Fernet (AES under the hood).
9 | 3. Store all encrypted notes in a single `.vault` file (JSON format).
10 | 4. Allow listing of titles and viewing/decrypting selected notes.
11 | 5. Support searching by title or keyword.
12 |
13 | Bonus:
14 | - Add timestamps to notes.
15 | - Use a master password to unlock vault (optional).
16 | """
17 |
18 | import json
19 | import os
20 | from cryptography.fernet import Fernet
21 | from datetime import datetime
22 |
23 | VAULT_FILE = "notes_vault.json"
24 | KEY_FILE = "vault.key"
25 |
26 | def load_or_create_key():
27 | if not os.path.exists(KEY_FILE):
28 | key = Fernet.generate_key()
29 | with open(KEY_FILE, "wb") as f:
30 | f.write(key)
31 | else:
32 | with open(KEY_FILE, "rb") as f:
33 | key = f.read()
34 |
35 | return Fernet(key)
36 |
37 | fernet = load_or_create_key()
38 |
39 | def load_vault():
40 | if not os.path.exists(VAULT_FILE):
41 | return []
42 | with open(VAULT_FILE, 'r', encoding="utf-8") as f:
43 | return json.load(f)
44 |
45 | def save_vault(data):
46 | with open(VAULT_FILE, 'w', encoding="utf-8") as f:
47 | json.dump(data, f, indent=2)
48 |
49 | def add_note():
50 | title = input("Enter note title: ").strip()
51 | content = input("Enter note content: ").strip()
52 |
53 | encrypted_content = fernet.encrypt(content.encode()).decode()
54 | timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
55 |
56 | data = load_vault()
57 | data.append({
58 | "title": title,
59 | "content": encrypted_content,
60 | "timestamp": timestamp
61 | })
62 |
63 | save_vault(data)
64 | print("✅ data saved")
65 |
66 | def list_notes():
67 | data = load_vault()
68 | if not data:
69 | print("No notes yet")
70 | return
71 |
72 | for i, note in enumerate(data, 1):
73 | print(f"{i}. {note['title']} {note['timestamp']}")
74 |
75 |
76 | def view_note():
77 | list_notes()
78 | try:
79 | index = int(input("Enter note number to view: ")) - 1
80 | data = load_vault()
81 | if 0 <= index <= len(data):
82 | encrypted = data[index]["content"]
83 | decrypted = fernet.decrypt(encrypted.encode()).decode()
84 | print(f"\n 📝 {data[index]['title']} - {data[index]['timestamp']} \n\n {decrypted}")
85 | else:
86 | print("Invalid selection")
87 | except:
88 | print("Invalid input")
89 |
90 | def search_notes():
91 | keyword = input("Enter the keyword to search: ").strip().lower()
92 | data = load_vault()
93 | found = [note for note in data if keyword in note["title"].lower()]
94 | if not found:
95 | print("NO matching notes")
96 | else:
97 | for note in found:
98 | print(f"{note["title"]} {note['timestamp']}")
99 |
100 | def main():
101 | while True:
102 | print("\n🔐 Offline Notes Locker")
103 | print("1. Add Note")
104 | print("2. List Notes")
105 | print("3. View Note")
106 | print("4. Search Notes")
107 | print("5. Exit")
108 |
109 | choice = input("Enter an option: ").strip()
110 |
111 | match choice:
112 | case "1": add_note()
113 | case "2": list_notes()
114 | case "3": view_note()
115 | case "4": search_notes()
116 | case "5": break
117 | case _: print("Invalid input")
118 |
119 | if __name__ == "__main__":
120 | main()
--------------------------------------------------------------------------------
/challenges/01_utilities/day_7.py:
--------------------------------------------------------------------------------
1 | """
2 | Challenge: Terminal-Based Task List Manager
3 |
4 | Create a Python script that lets users manage a to-do list directly from the terminal.
5 |
6 | Your program should:
7 | 1. Allow users to:
8 | - Add a task
9 | - View all tasks
10 | - Mark a task as completed
11 | - Delete a task
12 | - Exit the app
13 | 2. Save all tasks in a text file named `tasks.txt` so data persists between runs.
14 | 3. Display tasks with an index number and a ✔ if completed.
15 |
16 | Example menu:
17 | 1. Add Task
18 | 2. View Tasks
19 | 3. Mark Task as Completed
20 | 4. Delete Task
21 | 5. Exit
22 |
23 | Example output:
24 | Your Tasks:
25 |
26 | Buy groceries||not_done
27 | Finish Python project||done
28 | Read a || book||not_done
29 |
30 |
31 | Bonus:
32 | - Prevent empty tasks from being added
33 | - Validate task numbers before completing/deleting
34 | """
35 |
36 | import os
37 |
38 | TASK_FILE = "tasks.txt"
39 |
40 | def load_tasks():
41 | tasks = []
42 | if(os.path.exists(TASK_FILE)):
43 | with open(TASK_FILE, 'r', encoding="utf-8") as f:
44 | for line in f:
45 | text, status = line.strip().rsplit("||", 1)
46 | tasks.append({"text": text, "done": status == "done"})
47 | return tasks
48 |
49 | def save_tasks(tasks):
50 | with open(TASK_FILE, "w", encoding="utf-8") as f:
51 | for task in tasks:
52 | status = "done" if task["done"] else "not_done"
53 | f.write(f"{task['text']}||{status}\n")
54 |
55 |
56 | def display_tasks(tasks):
57 | if not tasks:
58 | print(f"NO tasks found")
59 | else:
60 | for i, task in enumerate(tasks, 1):
61 | checkbox = "✅" if task["done"] else " "
62 | print(f"{i}. [{checkbox}] {task['text']}")
63 | print()
64 |
65 |
66 |
67 | def task_manager():
68 | tasks = load_tasks()
69 |
70 | while True:
71 | print("\n------Task List Manager -------")
72 | print("1. Add task")
73 | print("2. View Tasks")
74 | print("3. Mark Task as complete")
75 | print("4. Delete task")
76 | print("5. Exit")
77 |
78 | choice = input("Choose an option (1-5)").strip()
79 |
80 | match choice:
81 | case "1":
82 | text = input("Enter your task").strip()
83 | if text:
84 | tasks.append({"text":text, "done": False})
85 | save_tasks(tasks)
86 | else:
87 | print("Task cannot be empty")
88 |
89 | case "2":
90 | display_tasks(tasks)
91 | case "3":
92 | display_tasks(tasks)
93 | try:
94 | num = int(input("Enter task number"))
95 | if 1 <= num <= len(tasks):
96 | tasks[num-1]["done"] = True
97 | save_tasks(tasks)
98 | print("task marked as DONE")
99 | else:
100 | print("Invalid task number")
101 | except ValueError:
102 | print("Please enter a number")
103 | case "4":
104 | display_tasks(tasks)
105 | try:
106 | num = int(input("Enter task number to delete"))
107 | if 1 <= num <= len(tasks):
108 | removed = tasks.pop(num-1)
109 | save_tasks(tasks)
110 | print(f"task removed {removed['text']}")
111 | else:
112 | print("Invalid task number")
113 | except ValueError:
114 | print("Please enter a number")
115 | case "5":
116 | print("Exiting task Manager")
117 | break
118 | case _:
119 | print("Please choose a valid option")
120 |
121 | task_manager()
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # 🐍 Complete Python Programming Course
2 |
3 | **Master Python from Basics to Advanced with Real-World Projects**
4 |
5 | > **Course Link**: [hitesh.ai](https://hitesh.ai)
6 | > **Instructor**: Hitesh Choudhary
7 |
8 | ---
9 |
10 | ## 📚 Course Overview
11 |
12 | This comprehensive Python course takes you from absolute beginner to advanced Python developer through hands-on projects and practical examples. Learn Python fundamentals, advanced concepts, and build real-world applications that showcase your skills.
13 |
14 | ---
15 |
16 | ## 🎯 What You'll Learn
17 |
18 | ### **Core Python Fundamentals**
19 | - **Data Types & Variables** - Master strings, numbers, lists, tuples, dictionaries, and sets
20 | - **Control Flow** - Conditionals, loops, and program logic
21 | - **Functions** - Function definition, parameters, return values, and scope
22 | - **Object-Oriented Programming** - Classes, inheritance, methods, and properties
23 | - **Error Handling** - Try-catch blocks, custom exceptions, and robust error management
24 |
25 | ### **Advanced Python Concepts**
26 | - **Comprehensions** - List, set, and dictionary comprehensions for elegant code
27 | - **Generators** - Memory-efficient data processing with generators
28 | - **Decorators** - Function and class decorators for code enhancement
29 | - **Concurrency** - Threading, multiprocessing, and async programming
30 | - **File Handling** - Reading, writing, and managing files effectively
31 |
32 | ### **Real-World Applications**
33 | - **Web Development** - Build a URL shortener with Flask
34 | - **Data Science** - Data analysis, visualization, and machine learning basics
35 | - **Web Scraping** - Extract data from websites and APIs
36 | - **Automation** - Automate repetitive tasks and file operations
37 | - **API Development** - Create and consume REST APIs
38 |
39 | ---
40 |
41 | ## 📁 Course Structure
42 |
43 | ### **01. Python Basics** (`00_python/`, `01_virtual/`, `02_datatypes/`)
44 | - Introduction to Python syntax and environment setup
45 | - Virtual environments and package management
46 | - Comprehensive coverage of all Python data types
47 |
48 | ### **02. Control Structures** (`03_conditionals/`, `04_loops/`)
49 | - Conditional statements and decision making
50 | - Loops (for, while) with practical examples
51 | - Real-world scenarios like chai shop automation
52 |
53 | ### **03. Functions & Modularity** (`05_functions/`, `06_chai_business/`)
54 | - Function definition, parameters, and return values
55 | - Scope, global, and nonlocal keywords
56 | - Building modular applications with packages
57 |
58 | ### **04. Pythonic Programming** (`07_comprehensions/`, `08_generators/`)
59 | - List, set, and dictionary comprehensions
60 | - Generator functions and expressions
61 | - Memory-efficient data processing
62 |
63 | ### **05. Advanced Features** (`09_decorators/`, `10_oop/`, `11_exceptions/`)
64 | - Function and class decorators
65 | - Object-oriented programming principles
66 | - Exception handling and custom exceptions
67 |
68 | ### **06. Concurrency & Performance** (`12_threads_concurrency/`, `13_async_python/`)
69 | - Threading and multiprocessing
70 | - Global Interpreter Lock (GIL) understanding
71 | - Asynchronous programming with asyncio
72 |
73 | ---
74 |
75 | ## 🚀 Hands-On Projects
76 |
77 | ### **1. Utility Applications** (`challenges/01_utilities/`)
78 | - Self-introduction script generator
79 | - Personal bio and learning journal tools
80 | - Task management utilities
81 |
82 | ### **2. Data Handling** (`challenges/02_data_handling/`)
83 | - CSV and JSON data processing
84 | - API data manipulation
85 | - Contact management system
86 | - Weather data analysis
87 |
88 | ### **3. Web Scraping** (`challenges/03_web_scraping/`)
89 | - Book data extraction from websites
90 | - Cryptocurrency price tracking
91 | - Hacker News top stories scraper
92 | - Image and PDF downloading
93 |
94 | ### **4. Automation** (`challenges/04_automation/`)
95 | - File organization and management
96 | - Image processing and manipulation
97 | - Automated data collection
98 |
99 | ### **5. Data Science** (`challenges/05_data_science/`)
100 | - Data analysis with pandas
101 | - Data visualization with matplotlib/seaborn
102 | - YouTube comments analysis
103 | - Salary vs experience correlation
104 |
105 | ### **6. Web Application** (`challenges/06_url_shortner/`)
106 | - **Complete Flask Web App**
107 | - URL shortening service
108 | - Database integration (SQLite)
109 | - User interface with templates
110 | - Visit tracking and analytics
111 |
112 | ---
113 |
114 | ## 🛠️ Technologies & Tools Covered
115 |
116 | - **Python 3.x** - Core programming language
117 | - **Flask** - Web framework for building applications
118 | - **SQLite** - Database management
119 | - **Pandas** - Data manipulation and analysis
120 | - **Matplotlib/Seaborn** - Data visualization
121 | - **Requests** - HTTP library for API calls
122 | - **Beautiful Soup** - Web scraping
123 | - **Threading/Multiprocessing** - Concurrency
124 | - **Asyncio** - Asynchronous programming
125 |
126 | ---
127 |
128 | ## 📋 Prerequisites
129 |
130 | - Basic computer literacy
131 | - No prior programming experience required
132 | - Windows, macOS, or Linux operating system
133 | - Internet connection for downloading packages
134 |
135 | ---
136 |
137 | ## 🎓 Learning Outcomes
138 |
139 | By the end of this course, you will be able to:
140 |
141 | ✅ **Write clean, efficient Python code**
142 | ✅ **Build complete web applications**
143 | ✅ **Scrape and analyze data from the web**
144 | ✅ **Create automation scripts**
145 | ✅ **Work with databases and APIs**
146 | ✅ **Implement concurrent and asynchronous programs**
147 | ✅ **Apply object-oriented programming principles**
148 | ✅ **Handle errors and exceptions professionally**
149 | ✅ **Use advanced Python features effectively**
150 | ✅ **Deploy real-world Python applications**
151 |
152 | ---
153 |
154 | ## 🏆 Course Highlights
155 |
156 | - **200+ Practical Examples** - Learn by doing with real code
157 | - **6 Complete Projects** - Build portfolio-worthy applications
158 | - **Progressive Difficulty** - From beginner to advanced concepts
159 | - **Industry Best Practices** - Learn professional coding standards
160 | - **Hands-On Challenges** - Daily exercises to reinforce learning
161 | - **Real-World Applications** - Solve actual problems with Python
162 |
163 | ---
164 |
165 | ## 📖 How to Use This Repository
166 |
167 | 1. **Clone or download** this repository
168 | 2. **Follow the folder structure** in numerical order
169 | 3. **Complete exercises** in each chapter
170 | 4. **Build projects** in the challenges section
171 | 5. **Practice regularly** with the provided examples
172 |
173 | ---
174 |
175 | ## 🎯 Target Audience
176 |
177 | - **Beginners** - No prior programming experience
178 | - **Students** - Learning Python for academic purposes
179 | - **Professionals** - Wanting to add Python to their skill set
180 | - **Career Changers** - Transitioning to software development
181 | - **Hobbyists** - Interested in automation and data analysis
182 |
183 | ---
184 |
185 | ## 📞 Support & Community
186 |
187 | - **Course Platform**: [hitesh.ai](https://hitesh.ai)
188 | - **Instructor**: Hitesh Choudhary
189 | - **Community**: Join the course community for discussions and support
190 |
191 | ---
192 |
193 | ## 📄 License
194 |
195 | This course material is provided for educational purposes. Please respect the instructor's intellectual property and course terms.
196 |
197 | ---
198 |
199 | **Ready to start your Python journey?** 🚀
200 |
201 | *Begin with the basics in `00_python/` and work your way through to building complete applications!*
202 |
--------------------------------------------------------------------------------
/challenges/03_web_scraping/books_data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "title": "A Light in the Attic",
4 | "price": "\u00c2\u00a351.77"
5 | },
6 | {
7 | "title": "Tipping the Velvet",
8 | "price": "\u00c2\u00a353.74"
9 | },
10 | {
11 | "title": "Soumission",
12 | "price": "\u00c2\u00a350.10"
13 | },
14 | {
15 | "title": "Sharp Objects",
16 | "price": "\u00c2\u00a347.82"
17 | },
18 | {
19 | "title": "Sapiens: A Brief History of Humankind",
20 | "price": "\u00c2\u00a354.23"
21 | },
22 | {
23 | "title": "The Requiem Red",
24 | "price": "\u00c2\u00a322.65"
25 | },
26 | {
27 | "title": "The Dirty Little Secrets of Getting Your Dream Job",
28 | "price": "\u00c2\u00a333.34"
29 | },
30 | {
31 | "title": "The Coming Woman: A Novel Based on the Life of the Infamous Feminist, Victoria Woodhull",
32 | "price": "\u00c2\u00a317.93"
33 | },
34 | {
35 | "title": "The Boys in the Boat: Nine Americans and Their Epic Quest for Gold at the 1936 Berlin Olympics",
36 | "price": "\u00c2\u00a322.60"
37 | },
38 | {
39 | "title": "The Black Maria",
40 | "price": "\u00c2\u00a352.15"
41 | },
42 | {
43 | "title": "Starving Hearts (Triangular Trade Trilogy, #1)",
44 | "price": "\u00c2\u00a313.99"
45 | },
46 | {
47 | "title": "Shakespeare's Sonnets",
48 | "price": "\u00c2\u00a320.66"
49 | },
50 | {
51 | "title": "Set Me Free",
52 | "price": "\u00c2\u00a317.46"
53 | },
54 | {
55 | "title": "Scott Pilgrim's Precious Little Life (Scott Pilgrim #1)",
56 | "price": "\u00c2\u00a352.29"
57 | },
58 | {
59 | "title": "Rip it Up and Start Again",
60 | "price": "\u00c2\u00a335.02"
61 | },
62 | {
63 | "title": "Our Band Could Be Your Life: Scenes from the American Indie Underground, 1981-1991",
64 | "price": "\u00c2\u00a357.25"
65 | },
66 | {
67 | "title": "Olio",
68 | "price": "\u00c2\u00a323.88"
69 | },
70 | {
71 | "title": "Mesaerion: The Best Science Fiction Stories 1800-1849",
72 | "price": "\u00c2\u00a337.59"
73 | },
74 | {
75 | "title": "Libertarianism for Beginners",
76 | "price": "\u00c2\u00a351.33"
77 | },
78 | {
79 | "title": "It's Only the Himalayas",
80 | "price": "\u00c2\u00a345.17"
81 | },
82 | {
83 | "title": "In Her Wake",
84 | "price": "\u00c2\u00a312.84"
85 | },
86 | {
87 | "title": "How Music Works",
88 | "price": "\u00c2\u00a337.32"
89 | },
90 | {
91 | "title": "Foolproof Preserving: A Guide to Small Batch Jams, Jellies, Pickles, Condiments, and More: A Foolproof Guide to Making Small Batch Jams, Jellies, Pickles, Condiments, and More",
92 | "price": "\u00c2\u00a330.52"
93 | },
94 | {
95 | "title": "Chase Me (Paris Nights #2)",
96 | "price": "\u00c2\u00a325.27"
97 | },
98 | {
99 | "title": "Black Dust",
100 | "price": "\u00c2\u00a334.53"
101 | },
102 | {
103 | "title": "Birdsong: A Story in Pictures",
104 | "price": "\u00c2\u00a354.64"
105 | },
106 | {
107 | "title": "America's Cradle of Quarterbacks: Western Pennsylvania's Football Factory from Johnny Unitas to Joe Montana",
108 | "price": "\u00c2\u00a322.50"
109 | },
110 | {
111 | "title": "Aladdin and His Wonderful Lamp",
112 | "price": "\u00c2\u00a353.13"
113 | },
114 | {
115 | "title": "Worlds Elsewhere: Journeys Around Shakespeare\u00e2\u0080\u0099s Globe",
116 | "price": "\u00c2\u00a340.30"
117 | },
118 | {
119 | "title": "Wall and Piece",
120 | "price": "\u00c2\u00a344.18"
121 | },
122 | {
123 | "title": "The Four Agreements: A Practical Guide to Personal Freedom",
124 | "price": "\u00c2\u00a317.66"
125 | },
126 | {
127 | "title": "The Five Love Languages: How to Express Heartfelt Commitment to Your Mate",
128 | "price": "\u00c2\u00a331.05"
129 | },
130 | {
131 | "title": "The Elephant Tree",
132 | "price": "\u00c2\u00a323.82"
133 | },
134 | {
135 | "title": "The Bear and the Piano",
136 | "price": "\u00c2\u00a336.89"
137 | },
138 | {
139 | "title": "Sophie's World",
140 | "price": "\u00c2\u00a315.94"
141 | },
142 | {
143 | "title": "Penny Maybe",
144 | "price": "\u00c2\u00a333.29"
145 | },
146 | {
147 | "title": "Maude (1883-1993):She Grew Up with the country",
148 | "price": "\u00c2\u00a318.02"
149 | },
150 | {
151 | "title": "In a Dark, Dark Wood",
152 | "price": "\u00c2\u00a319.63"
153 | },
154 | {
155 | "title": "Behind Closed Doors",
156 | "price": "\u00c2\u00a352.22"
157 | },
158 | {
159 | "title": "You can't bury them all: Poems",
160 | "price": "\u00c2\u00a333.63"
161 | },
162 | {
163 | "title": "Slow States of Collapse: Poems",
164 | "price": "\u00c2\u00a357.31"
165 | },
166 | {
167 | "title": "Reasons to Stay Alive",
168 | "price": "\u00c2\u00a326.41"
169 | },
170 | {
171 | "title": "Private Paris (Private #10)",
172 | "price": "\u00c2\u00a347.61"
173 | },
174 | {
175 | "title": "#HigherSelfie: Wake Up Your Life. Free Your Soul. Find Your Tribe.",
176 | "price": "\u00c2\u00a323.11"
177 | },
178 | {
179 | "title": "Without Borders (Wanderlove #1)",
180 | "price": "\u00c2\u00a345.07"
181 | },
182 | {
183 | "title": "When We Collided",
184 | "price": "\u00c2\u00a331.77"
185 | },
186 | {
187 | "title": "We Love You, Charlie Freeman",
188 | "price": "\u00c2\u00a350.27"
189 | },
190 | {
191 | "title": "Untitled Collection: Sabbath Poems 2014",
192 | "price": "\u00c2\u00a314.27"
193 | },
194 | {
195 | "title": "Unseen City: The Majesty of Pigeons, the Discreet Charm of Snails & Other Wonders of the Urban Wilderness",
196 | "price": "\u00c2\u00a344.18"
197 | },
198 | {
199 | "title": "Unicorn Tracks",
200 | "price": "\u00c2\u00a318.78"
201 | },
202 | {
203 | "title": "Unbound: How Eight Technologies Made Us Human, Transformed Society, and Brought Our World to the Brink",
204 | "price": "\u00c2\u00a325.52"
205 | },
206 | {
207 | "title": "Tsubasa: WoRLD CHRoNiCLE 2 (Tsubasa WoRLD CHRoNiCLE #2)",
208 | "price": "\u00c2\u00a316.28"
209 | },
210 | {
211 | "title": "Throwing Rocks at the Google Bus: How Growth Became the Enemy of Prosperity",
212 | "price": "\u00c2\u00a331.12"
213 | },
214 | {
215 | "title": "This One Summer",
216 | "price": "\u00c2\u00a319.49"
217 | },
218 | {
219 | "title": "Thirst",
220 | "price": "\u00c2\u00a317.27"
221 | },
222 | {
223 | "title": "The Torch Is Passed: A Harding Family Story",
224 | "price": "\u00c2\u00a319.09"
225 | },
226 | {
227 | "title": "The Secret of Dreadwillow Carse",
228 | "price": "\u00c2\u00a356.13"
229 | },
230 | {
231 | "title": "The Pioneer Woman Cooks: Dinnertime: Comfort Classics, Freezer Food, 16-Minute Meals, and Other Delicious Ways to Solve Supper!",
232 | "price": "\u00c2\u00a356.41"
233 | },
234 | {
235 | "title": "The Past Never Ends",
236 | "price": "\u00c2\u00a356.50"
237 | },
238 | {
239 | "title": "The Natural History of Us (The Fine Art of Pretending #2)",
240 | "price": "\u00c2\u00a345.22"
241 | },
242 | {
243 | "title": "The Nameless City (The Nameless City #1)",
244 | "price": "\u00c2\u00a338.16"
245 | },
246 | {
247 | "title": "The Murder That Never Was (Forensic Instincts #5)",
248 | "price": "\u00c2\u00a354.11"
249 | },
250 | {
251 | "title": "The Most Perfect Thing: Inside (and Outside) a Bird's Egg",
252 | "price": "\u00c2\u00a342.96"
253 | },
254 | {
255 | "title": "The Mindfulness and Acceptance Workbook for Anxiety: A Guide to Breaking Free from Anxiety, Phobias, and Worry Using Acceptance and Commitment Therapy",
256 | "price": "\u00c2\u00a323.89"
257 | },
258 | {
259 | "title": "The Life-Changing Magic of Tidying Up: The Japanese Art of Decluttering and Organizing",
260 | "price": "\u00c2\u00a316.77"
261 | },
262 | {
263 | "title": "The Inefficiency Assassin: Time Management Tactics for Working Smarter, Not Longer",
264 | "price": "\u00c2\u00a320.59"
265 | },
266 | {
267 | "title": "The Gutsy Girl: Escapades for Your Life of Epic Adventure",
268 | "price": "\u00c2\u00a337.13"
269 | },
270 | {
271 | "title": "The Electric Pencil: Drawings from Inside State Hospital No. 3",
272 | "price": "\u00c2\u00a356.06"
273 | },
274 | {
275 | "title": "The Death of Humanity: and the Case for Life",
276 | "price": "\u00c2\u00a358.11"
277 | },
278 | {
279 | "title": "The Bulletproof Diet: Lose up to a Pound a Day, Reclaim Energy and Focus, Upgrade Your Life",
280 | "price": "\u00c2\u00a349.05"
281 | }
282 | ]
--------------------------------------------------------------------------------