├── .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 |
15 | 25 | 31 |
32 |

All shorten URLs

33 | {% if all_urls %} 34 |
35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | {% for url in all_urls%} 46 | 47 | 52 | 53 | 54 | 63 | 64 | {% endfor%} 65 | 66 |
Short URLOriginal URLVisitsAction
48 | 49 | http://localhost:5000/{{url[1]}} 50 | 51 | {{url[0]}}{{url[2]}} 55 |
60 | 61 |
62 |
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 | ] --------------------------------------------------------------------------------