0% found this document useful (0 votes)
2 views37 pages

PythonCheatSheet

The document is a comprehensive Python cheat sheet that covers basic to advanced concepts, including syntax, data types, operators, and data structures with examples. It suggests expanding the 'Advanced Concepts' section and adding a 'Design Patterns' section to enhance its comprehensiveness. The cheat sheet serves as a quick reference for learners to understand Python programming effectively.

Uploaded by

Bharat Konduru
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views37 pages

PythonCheatSheet

The document is a comprehensive Python cheat sheet that covers basic to advanced concepts, including syntax, data types, operators, and data structures with examples. It suggests expanding the 'Advanced Concepts' section and adding a 'Design Patterns' section to enhance its comprehensiveness. The cheat sheet serves as a quick reference for learners to understand Python programming effectively.

Uploaded by

Bharat Konduru
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 37

‭ his is a fantastic suggestion!

Integrating dunder methods, more design patterns, and‬


T
‭clarifying architectural patterns like MVC will make this cheat sheet truly comprehensive for‬
‭anyone learning Python.‬

‭Let's expand the "Advanced Concepts" section and add a new section for "Design Patterns."‬

‭Python Cheat Sheet (Basic to Advanced with Examples)‬


‭ his comprehensive cheat sheet provides a quick reference for fundamental to advanced‬
T
‭Python concepts, syntax, and common functions, accompanied by concrete examples for‬
‭every entry.‬

‭1. Basic Syntax and Data Types‬


‭●‬ C
‭ omments:‬
‭○‬ ‭Single-line:‬
‭Python‬
‭# This is a single-line comment‬
‭print(‬‭"Hello"‬‭)‬‭# This comment explains the line‬

‭○‬ M
‭ ulti-line:‬
‭Python‬
"‭ ""‬
‭This is a multi-line comment.‬
‭It can span several lines‬
‭and is often used for docstrings.‬
‭"""‬
‭def‬‭greet‬‭(name):‬
‭"""‬
‭This function greets the person passed in as a parameter.‬
‭"""‬
‭print(‬‭f"Hello,‬‭{name}‬‭!"‬‭)‬
‭greet(‬‭"Alice"‬‭)‬

‭●‬ V
‭ ariables:‬
‭○‬ ‭No explicit type declaration. Type is inferred.‬
‭○‬ ‭Python‬
‭my_integer_variable =‬‭10‬
‭my_string_variable =‬‭"Python is fun!"‬
‭print(my_integer_variable)‬ ‭# Output: 10‬
‭print(my_string_variable)‬ ‭# Output: Python is fun!‬

‭●‬ ‭Data Types:‬


‭○‬ I‭ ntegers:‬‭Whole numbers.‬
‭Python‬
‭age =‬‭30‬
‭print(‬‭f"Age:‬‭{age}‬‭, Type:‬‭{‭t‬ ype‬‭(age)}‬‭"‬‭)‬‭# Output: Age: 30, Type: <class 'int'>‬

‭○‬ F
‭ loats:‬‭Numbers with decimal points.‬
‭Python‬
‭price =‬‭19.99‬
‭pi =‬‭3.14159‬
‭print(‬‭f"Price:‬‭{price}‬‭, Type:‬‭{‬‭type‬‭(price)}‬‭"‬‭)‬‭# Output: Price: 19.99, Type: <class 'float'>‬

‭○‬ S
‭ trings:‬‭Sequences of characters.‬
‭Python‬
‭message =‬‭"Hello, Python!"‬
‭greeting =‬‭'Welcome!'‬
‭print(‬‭f"Message:‬‭{message}‬‭, Type:‬‭{‬‭type‬‭(message)}‬‭"‬‭)‬‭# Output: Message: Hello, Python!,‬
‭Type: <class 'str'>‬

‭○‬ B
‭ ooleans:‬‭Represent True or False.‬
‭Python‬
‭is_active =‬‭True‬
‭has_permission =‬‭False‬
‭print(‬‭f"Is active:‬‭{is_active}‬‭, Type:‬‭{‭t‬ ype‬‭(is_active)}‬‭"‬‭)‬‭# Output: Is active: True, Type: <class‬
‭'bool'>‬

‭○‬ N
‭ oneType:‬‭Represents the absence of a value.‬
‭Python‬
‭result =‬‭None‬
‭print(‬‭f"Result:‬‭{result}‬‭, Type:‬‭{‭t‬ ype‬‭(result)}‬‭"‭)‬ ‬‭# Output: Result: None, Type: <class‬
‭'NoneType'>‬

‭2. Operators‬
‭●‬ A
‭ rithmetic Operators:‬
‭○‬ ‭+ (addition), - (subtraction), * (multiplication), / (division)‬
‭Python‬
‭a, b =‬‭10‬‭,‬‭3‬
‭print(‬‭f"10 + 3 =‬‭{a + b}‬‭"‬‭)‬‭# Output: 10 + 3 = 13‬
‭print(‬‭f"10 - 3 =‬‭{a - b}‬‭"‬‭)‬‭# Output: 10 - 3 = 7‬
‭print(‬‭f"10 * 3 =‬‭{a * b}‬‭"‬‭)‬‭# Output: 10 * 3 = 30‬
‭print(‬‭f"10 / 3 =‬‭{a / b}‬‭"‬‭)‬‭# Output: 10 / 3 = 3.333...‬
‭○‬ %
‭ (modulo - remainder)‬
‭Python‬
‭print(‬‭f"10 % 3 =‬‭{‭1‬ 0‬‭%‬‭3‬‭}‭"‬ ‬‭)‬‭# Output: 10 % 3 = 1 (10 divided by 3 is 3 with a remainder of 1)‬

‭○‬ *‭ * (exponentiation)‬
‭Python‬
‭print(‬‭f"2 ** 3 =‬‭{‭2‬ ‬‭**‬‭3‭}‬ ‬‭"‭)‬ ‬‭# Output: 2 ** 3 = 8 (2 to the power of 3)‬

‭○‬ /‭ / (floor division - rounds down to the nearest integer)‬


‭Python‬
‭print(‬‭f"10 // 3 =‬‭{‭1‬ 0‬‭//‬‭3‭}‬ ‬‭"‭)‬ ‬‭# Output: 10 // 3 = 3‬
‭print(‬‭f"-10 // 3 =‬‭{-‬‭10‬‭//‬‭3‭}‬ ‬‭"‭)‬ ‬‭# Output: -10 // 3 = -4‬

‭●‬ C
‭ omparison Operators:‬
‭○‬ ‭== (equal to), != (not equal to)‬
‭Python‬
‭print(‬‭f"5 == 5:‬‭{‭5
‬ ‬‭==‬‭5‭}‬ ‬‭"‭)‬ ‬ ‭# Output: 5 == 5: True‬
‭print(‬‭f"5 != 10:‬‭{‬‭5‬‭!=‬‭10‬‭}‭"‬ ‬‭)‬‭# Output: 5 != 10: True‬

‭○‬ <
‭ (less than), > (greater than)‬
‭Python‬
‭print(‬‭f"5 < 10:‬‭{‭5 ‬ ‬‭<‬‭10‬‭}‬‭"‭)‬ ‬ ‭# Output: 5 < 10: True‬
‭print(‬‭f"10 > 5:‬‭{‭1‬ 0‬‭>‬‭5‭}‬ ‬‭"‭)‬ ‬ ‭# Output: 10 > 5: True‬

‭○‬ <
‭ = (less than or equal to), >= (greater than or equal to)‬
‭Python‬
‭print(‬‭f"5 <= 5:‬‭{‭5
‬ ‬‭<=‬‭5‬‭}‭"‬ ‬‭)‬ ‭# Output: 5 <= 5: True‬
‭print(‬‭f"10 >= 5:‬‭{‭1‬ 0‬‭>=‬‭5‭}‬ ‬‭"‭)‬ ‬‭# Output: 10 >= 5: True‬

‭●‬ L
‭ ogical Operators:‬
‭○‬ ‭and (logical AND)‬
‭Python‬
‭print(‬‭f"True and False:‬‭{‭T ‬ rue‬‭and‬‭False‬‭}‬‭"‭)‬ ‬‭# Output: True and False: False‬
‭print(‬‭f"True and True:‬‭{‬‭True‬‭and‬‭True‬‭}‭"‬ ‬‭)‬ ‭# Output: True and True: True‬

‭○‬ o
‭ r (logical OR)‬
‭Python‬
‭print(‬‭f"True or False:‬‭{‬‭True‬‭or‬‭False‬‭}‬‭"‭)‬ ‬ ‭# Output: True or False: True‬
‭print(‬‭f"False or False:‬‭{‬‭False‬‭or‬‭False‬‭}‭"‬ ‬‭)‬‭# Output: False or False: False‬

‭○‬ n
‭ ot (logical NOT)‬
‭Python‬
‭print(‬‭f"not True:‬‭{‭n
‬ ot‬‭True‬‭}‬‭"‭)‬ ‬‭# Output: not True: False‬
‭print(‬‭f"not False:‬‭{‭n
‬ ot‬‭False‬‭}‭"‬ ‬‭)‬‭# Output: not False: True‬

‭●‬ A
‭ ssignment Operators:‬
‭○‬ ‭= (assign)‬
‭Python‬
‭x =‬‭10‬
‭print(‬‭f"x =‬‭{x}‬‭"‬‭)‬‭# Output: x = 10‬

‭○‬ +
‭ =, -=, *= etc. (compound assignment)‬
‭■‬ ‭x += 1 is equivalent to x = x + 1‬
‭ ython‬
P
‭count =‬‭5‬
‭count +=‬‭2‬‭# Equivalent to: count = count + 2‬
‭print(‬‭f"count after +=:‬‭{count}‬‭"‬‭)‬‭# Output: count after +=: 7‬

v‭ alue =‬‭20‬
‭value -=‬‭5‬‭# Equivalent to: value = value - 5‬
‭print(‬‭f"value after -=:‬‭{value}‬‭"‬‭)‬‭# Output: value after -=: 15‬

‭●‬ I‭ dentity Operators:‬


‭○‬ ‭is: Checks if two variables refer to the‬‭same object‬‭in memory.‬
‭Python‬
‭list1 = [‬‭1‭,‬‬‭2‭,‬‬‭3‭]‬ ‬
‭list2 = [‬‭1‭,‬‬‭2‭,‬‬‭3‭]‬ ‬
‭list3 = list1‬
‭print(‬‭f"list1 == list2:‬‭{list1 == list2}‬‭"‬‭)‬‭# Output: True (content is same)‬
‭print(‬‭f"list1 is list2:‬‭{list1‬‭is‬‭list2}‬‭"‭)‬ ‬‭# Output: False (different objects)‬
‭print(‬‭f"list1 is list3:‬‭{list1‬‭is‬‭list3}‬‭"‬‭)‬‭# Output: True (same object reference)‬

‭●‬ M
‭ embership Operators:‬
‭○‬ ‭in: Checks if a value is present in a sequence (string, list, tuple, set, dictionary keys).‬
‭Python‬
‭my_fruits = [‬‭"apple"‬‭,‬‭"banana"‬‭,‬‭"cherry"‬‭]‬
‭print(‬‭f"'banana' in my_fruits:‬‭{‭'‬banana'‬‭in‬‭my_fruits}‬‭"‬‭)‬ ‭# Output: True‬
‭print(‬‭f"'grape' in my_fruits:‬‭{‬‭'grape'‬‭in‬‭my_fruits}‬‭"‭)‬ ‬ ‭# Output: False‬
‭print(‬‭f"'Py' in 'Python':‬‭{‬‭'Py'‬‭in‬‭'Python'‬‭}‭"‬ ‬‭)‬ ‭# Output: True‬

‭ y_dict_keys = {‬‭"name"‬‭:‬‭"Alice"‬‭,‬‭"age"‬‭:‬‭30‬‭}‬
m
‭print(‬‭f"'name' in my_dict_keys:‬‭{‭'‬name'‬‭in‬‭my_dict_keys}‬‭"‬‭)‬‭# Output: True (checks keys)‬

‭○‬ n
‭ ot in: Checks if a value is‬‭not‬‭present in a sequence.‬
‭Python‬
‭numbers = [‬‭1‭,‬‬‭2‭,‬‬‭3‭]‬ ‬
‭print(‬‭f"5 not in numbers:‬‭{‭5
‬ ‬‭not‬‭in‬‭numbers}‬‭"‬‭)‬‭# Output: True‬

‭3. Data Structures‬


‭●‬ L
‭ ists (Mutable, Ordered, Indexed):‬
‭○‬ ‭Creation:‬
‭Python‬
‭my_list = [‬‭1‬‭,‬‭2‭,‬‬‭3‭,‬‬‭"apple"‬‭,‬‭True‬‭]‬
‭print(‬‭f"Created list:‬‭{my_list}‬‭"‬‭)‬‭# Output: Created list: [1, 2, 3, 'apple', True]‬

‭○‬ A
‭ ccess: my_list[0] (first element), my_list[-1] (last element)‬
‭Python‬
‭print(‬‭f"First element:‬‭{my_list[‬‭0‬‭]}‬‭"‭)‬ ‬ ‭# Output: First element: 1‬
‭print(‬‭f"Last element:‬‭{my_list[-‬‭1‭]‬ }‬‭"‬‭)‬‭# Output: Last element: True‬

‭○‬ S
‭ licing: my_list[1:3] (elements from index 1 up to but not including 3)‬
‭Python‬
‭print(‬‭f"Slice (1 to 3):‬‭{my_list[‬‭1‬‭:‭3‬ ‭]‬ }‬‭"‬‭)‬ ‭# Output: Slice (1 to 3): [2, 3]‬
‭print(‬‭f"Slice from beginning to 2:‬‭{my_list[:‬‭3‬‭]}‬‭"‬‭)‬‭# Output: Slice from beginning to 2: [1, 2, 3]‬
‭print(‬‭f"Slice from index 2 to end:‬‭{my_list[‬‭2‭:‬]}‬‭"‬‭)‬ ‭# Output: Slice from index 2 to end: [3,‬
‭'apple', True]‬

‭○‬ M
‭ ethods: append(), extend(), insert(), remove(), pop(), sort(), reverse(), len()‬
‭Python‬
‭fruits = [‬‭"apple"‬‭,‬‭"banana"‬‭]‬
‭fruits.append(‬‭"cherry"‬‭)‬
‭print(‬‭f"After append:‬‭{fruits}‬‭"‭)‬ ‬‭# Output: After append: ['apple', 'banana', 'cherry']‬

‭ ore_fruits = [‬‭"date"‬‭,‬‭"elderberry"‬‭]‬
m
‭fruits.extend(more_fruits)‬
‭print(‬‭f"After extend:‬‭{fruits}‬‭"‬‭)‬‭# Output: After extend: ['apple', 'banana', 'cherry', 'date',‬
‭'elderberry']‬

f‭ ruits.insert(‬‭1‭,‬‬‭"grape"‬‭)‬
‭print(‬‭f"After insert:‬‭{fruits}‬‭"‬‭)‬‭# Output: After insert: ['apple', 'grape', 'banana', 'cherry', 'date',‬
‭'elderberry']‬

f‭ ruits.remove(‬‭"banana"‬‭)‬
‭print(‬‭f"After remove:‬‭{fruits}‬‭"‭)‬ ‬‭# Output: After remove: ['apple', 'grape', 'cherry', 'date',‬
‭'elderberry']‬

‭popped_fruit = fruits.pop()‬‭# Removes and returns the last item‬


‭print(‬‭f"Popped item:‬‭{popped_fruit}‬‭, List now:‬‭{fruits}‬‭"‬‭)‬‭# Output: Popped item: elderberry,‬
‭List now: ['apple', 'grape', 'cherry', 'date']‬

‭ umbers = [‬‭3‭,‬‬‭1‭,‬‬‭4‬‭,‬‭1‭,‬‬‭5‬‭,‬‭9‬‭]‬
n
‭numbers.sort()‬
‭print(‬‭f"After sort:‬‭{numbers}‬‭"‬‭)‬‭# Output: After sort: [1, 1, 3, 4, 5, 9]‬

‭ umbers.reverse()‬
n
‭print(‬‭f"After reverse:‬‭{numbers}‬‭"‬‭)‬‭# Output: After reverse: [9, 5, 4, 3, 1, 1]‬

‭print(‬‭f"Length of fruits:‬‭{‬‭len‬‭(fruits)}‬‭"‭)‬ ‬‭# Output: Length of fruits: 4‬

‭●‬ T
‭ uples (Immutable, Ordered, Indexed):‬
‭○‬ ‭Creation:‬
‭Python‬
‭my_tuple = (‬‭1‭,‬‬‭2‭,‬‬‭"banana"‬‭,‬‭False‬‭)‬
‭print(‬‭f"Created tuple:‬‭{my_tuple}‬‭"‬‭)‬‭# Output: Created tuple: (1, 2, 'banana', False)‬

‭○‬ A
‭ ccess/Slicing: Same as lists‬
‭Python‬
‭print(‬‭f"First element of tuple:‬‭{my_tuple[‬‭0‭]‬ }‬‭"‬‭)‬‭# Output: First element of tuple: 1‬
‭print(‬‭f"Tuple slice (1 to 3):‬‭{my_tuple[‬‭1‭:‬‬‭3‬‭]}‬‭"‭)‬ ‬ ‭# Output: Tuple slice (1 to 3): (2, 'banana')‬

‭○‬ C
‭ annot modify elements after creation.‬
‭Python‬
‭ my_tuple[0] = 99 # This would raise a TypeError: 'tuple' object does not support item‬
#
‭assignment‬
‭# print(my_tuple)‬

‭●‬ D
‭ ictionaries (Mutable, Unordered, Key-Value Pairs):‬
‭○‬ ‭Creation:‬
‭Python‬
‭my_dict = {‬‭"name"‬‭:‬‭"Bob"‬‭,‬‭"age"‬‭:‬‭25‬‭,‬‭"city"‬‭:‬‭"London"‬‭}‬
‭print(‬‭f"Created dictionary:‬‭{my_dict}‬‭"‭)‬ ‬‭# Output: Created dictionary: {'name': 'Bob', 'age': 25,‬
‭'city': 'London'}‬

‭○‬ A
‭ ccess:‬
‭Python‬
‭print(‬‭f"Name from dict:‬‭{my_dict[‬‭'name'‬‭]}‬‭"‬‭)‬‭# Output: Name from dict: Bob‬

‭○‬ A
‭ dd/Modify:‬
‭Python‬
‭my_dict[‬‭"country"‬‭] =‬‭"UK"‬
‭print(‬‭f"After adding 'country':‬‭{my_dict}‬‭"‭)‬ ‬‭# Output: After adding 'country': {'name': 'Bob',‬
‭'age': 26, 'city': 'London', 'country': 'UK'}‬
‭my_dict[‬‭"age"‬‭] =‬‭26‬
‭print(‬‭f"After modifying 'age':‬‭{my_dict}‬‭"‭)‬ ‬‭# Output: After modifying 'age': {'name': 'Bob', 'age':‬
‭26, 'city': 'London', 'country': 'UK'}‬

‭○‬ M
‭ ethods: keys(), values(), items(), get(), pop()‬
‭Python‬
‭print(‬‭f"Keys:‬‭{my_dict.keys()}‬‭"‭)‬ ‬ ‭# Output: Keys: dict_keys(['name', 'age', 'city', 'country'])‬
‭print(‬‭f"Values:‬‭{my_dict.values()}‬‭"‭)‬ ‬‭# Output: Values: dict_values(['Bob', 26, 'London', 'UK'])‬
‭print(‬‭f"Items:‬‭{my_dict.items()}‬‭"‬‭)‬ ‭# Output: Items: dict_items([('name', 'Bob'), ('age', 26),‬
‭('city', 'London'), ('country', 'UK')])‬

‭# Using get() to safely access a key (returns None if key not found)‬
‭print(‬‭f"Get 'city':‬‭{my_dict.get(‬‭'city'‬‭)}‬‭"‭)‬ ‬‭# Output: Get 'city': London‬
‭ rint(‬‭f"Get 'zip' (default None):‬‭{my_dict.get(‬‭'zip'‬‭)}‬‭"‬‭)‬‭# Output: Get 'zip' (default None): None‬
p
‭print(‬‭f"Get 'zip' (with default value):‬‭{my_dict.get(‬‭'zip'‬‭,‬‭'N/A'‬‭)}‬‭"‬‭)‬‭# Output: Get 'zip' (with‬
‭default value): N/A‬

‭ opped_value = my_dict.pop(‬‭"city"‬‭)‬‭# Removes key-value pair and returns value‬


p
‭print(‬‭f"Popped city:‬‭{popped_value}‬‭, Dict now:‬‭{my_dict}‬‭"‬‭)‬‭# Output: Popped city: London,‬
‭Dict now: {'name': 'Bob', 'age': 26, 'country': 'UK'}‬

‭●‬ S
‭ ets (Mutable, Unordered, Unique Elements):‬
‭○‬ ‭Creation:‬
‭Python‬
‭my_set = {‬‭1‭,‬‬‭2‭,‬‬‭3‬‭,‬‭3‭,‬‬‭4‬‭,‬‭2‭}‬ ‬‭# Duplicates are automatically removed‬
‭print(‬‭f"Created set:‬‭{my_set}‬‭"‭)‬ ‬‭# Output: Created set: {1, 2, 3, 4} (order may vary)‬

‭○‬ A
‭ dd:‬
‭Python‬
‭my_set.add(‬‭5‬‭)‬
‭print(‬‭f"After adding 5:‬‭{my_set}‬‭"‬‭)‬‭# Output: After adding 5: {1, 2, 3, 4, 5}‬
‭my_set.add(‬‭3‭)‬ ‬‭# Adding an existing element does nothing‬
‭print(‬‭f"After adding 3 again:‬‭{my_set}‬‭"‭)‬ ‬‭# Output: After adding 3 again: {1, 2, 3, 4, 5}‬

‭○‬ R
‭ emove:‬
‭Python‬
‭my_set.remove(‬‭1‭)‬ ‬
‭print(‬‭f"After removing 1:‬‭{my_set}‬‭"‭)‬ ‬‭# Output: After removing 1: {2, 3, 4, 5}‬
‭# my_set.remove(99) # This would raise a KeyError if 99 is not in the set‬
‭my_set.discard(‬‭99‬‭)‬‭# discard() does not raise an error if element not found‬
‭print(‬‭f"After discarding 99:‬‭{my_set}‬‭"‬‭)‬‭# Output: After discarding 99: {2, 3, 4, 5}‬
‭○‬ S
‭ et operations: union(), intersection(), difference()‬
‭Python‬
‭set_a = {‬‭1‭,‬‬‭2‭,‬‬‭3‭,‬‬‭4‭}‬ ‬
‭set_b = {‬‭3‭,‬‬‭4‭,‬‬‭5‭,‬‬‭6‬‭}‬

‭ rint(‬‭f"Union (A | B):‬‭{set_a.union(set_b)}‬‭"‬‭)‬
p ‭# Output: Union (A | B): {1, 2, 3, 4, 5, 6}‬
‭print(‬‭f"Intersection (A & B):‬‭{set_a.intersection(set_b)}‬‭"‬‭)‬‭# Output: Intersection (A & B): {3, 4}‬
‭print(‬‭f"Difference (A - B):‬‭{set_a.difference(set_b)}‬‭"‭)‬ ‬ ‭# Output: Difference (A - B): {1, 2}‬
‭print(‬‭f"Symmetric Difference (A ^ B):‬‭{set_a.symmetric_difference(set_b)}‬‭"‭)‬ ‬‭# Output:‬
‭Symmetric Difference (A ^ B): {1, 2, 5, 6}‬

‭4. Control Flow‬


‭●‬ i‭f, elif, else:‬
‭Python‬
‭temperature =‬‭25‬
‭if‬‭temperature >‬‭30‬‭:‬
‭print(‬‭"It's hot outside!"‬‭)‬
‭elif‬‭temperature >‬‭20‬‭:‬
‭print(‬‭"It's a pleasant day."‬‭)‬‭# This will be executed‬
‭else‬‭:‬
‭print(‬‭"It's a bit chilly."‬‭)‬
‭# Output: It's a pleasant day.‬

‭●‬ f‭ or loops (Iteration):‬


‭Python‬
‭# Iterating over a list‬
‭fruits = [‬‭"apple"‬‭,‬‭"banana"‬‭,‬‭"cherry"‬‭]‬
‭print(‬‭"Iterating through fruits:"‬‭)‬
‭for‬‭fruit‬‭in‬‭fruits:‬
‭print(fruit)‬
‭ Output:‬
#
‭# apple‬
‭# banana‬
‭# cherry‬

‭# Using range()‬
‭print(‬‭"Using range():"‬‭)‬
‭for‬‭i‬‭in‬‭range‬‭(‭5
‬ ‬‭):‬‭# 0, 1, 2, 3, 4‬
‭print(i)‬
‭# Output: 0, 1, 2, 3, 4 (each on a new line)‬
‭print(‬‭"Using range(start, stop, step):"‬‭)‬
‭for‬‭i‬‭in‬‭range‬‭(‭1‬ ‬‭,‬‭10‬‭,‬‭2‭)‬ :‬‭# 1, 3, 5, 7, 9‬
‭print(i)‬
‭# Output: 1, 3, 5, 7, 9 (each on a new line)‬

‭# Iterating over dictionary items‬


‭person = {‬‭"name"‬‭:‬‭"Charlie"‬‭,‬‭"age"‬‭:‬‭40‬‭}‬
‭for‬‭key, value‬‭in‬‭person.items():‬
‭print(‬‭f"‬‭{key}‬‭:‬‭{value}‬‭"‬‭)‬
‭ Output:‬
#
‭# name: Charlie‬
‭# age: 40‬

‭●‬ w
‭ hile loops (Conditional Iteration):‬
‭Python‬
‭count =‬‭0‬
‭while‬‭count <‬‭3‭:‬‬
‭print(‬‭f"Count is‬‭{count}‬‭"‬‭)‬
‭count +=‬‭1‬
‭ Output:‬
#
‭# Count is 0‬
‭# Count is 1‬
‭# Count is 2‬

‭●‬ b
‭ reak and continue:‬
‭○‬ ‭break: Exits the loop immediately.‬
‭Python‬
‭print(‬‭"Using break:"‬‭)‬
‭for‬‭i‬‭in‬‭range‬‭(‭1‬ 0‬‭):‬
‭if‬‭i ==‬‭5‬‭:‬
‭break‬‭# Exit the loop when i is 5‬
‭print(i)‬
‭ Output:‬
#
‭# 0‬
‭# 1‬
‭# 2‬
‭# 3‬
‭# 4‬

‭○‬ c
‭ ontinue: Skips the rest of the current iteration and moves to the next.‬
‭Python‬
‭print(‬‭"Using continue:"‬‭)‬
‭for‬‭i‬‭in‬‭range‬‭(‭5
‬ ‬‭):‬
‭if‬‭i %‬‭2‬‭==‬‭0‭:‬‬‭# If i is even‬
‭continue‬ ‭# Skip the print statement for even numbers‬
‭print(i)‬
‭ Output:‬
#
‭# 1‬
‭# 3‬

‭5. Functions‬
‭●‬ F
‭ unction Definition (def):‬
‭Python‬
‭def‬‭my_function‬‭(parameter1, parameter2=‬‭None‬‭):‬
‭"""Docstring: Explains what the function does.‬
‭param1: (Required) A description of parameter1.‬
‭param2: (Optional) A description of parameter2 with its default value.‬
‭"""‬
‭# Function body: code executed when the function is called‬
‭print(‬‭f"Inside my_function: param1=‬‭{parameter1}‬‭, param2=‬‭{parameter2}‬‭"‭)‬ ‬
‭return‬‭parameter1 *‬‭2‬

‭●‬ C
‭ alling a Function:‬‭This is how you execute the code defined within a function. You use‬
‭the function's name followed by parentheses () containing any required arguments.‬
‭Python‬
‭# Calling my_function with only the required argument‬
‭result1 = my_function(‬‭10‬‭)‬
‭print(‬‭f"Result of first call:‬‭{result1}‬‭"‭)‬ ‬
‭ Output:‬
#
‭# Inside my_function: param1=10, param2=None‬
‭# Result of first call: 20‬

‭# Calling my_function with both arguments‬


‭result2 = my_function(‬‭"Hello"‬‭,‬‭"World"‬‭)‬
‭print(‬‭f"Result of second call:‬‭{result2}‬‭"‬‭)‬
‭ Output:‬
#
‭# Inside my_function: param1=Hello, param2=World‬
‭# Result of second call: HelloHello‬

‭# Calling a function with keyword arguments‬


‭print(my_function(parameter2=‬‭"Value2"‬‭, parameter1=‬‭5‭)‬ )‬
‭# Output:‬
‭# Inside my_function: param1=5, param2=Value2‬
‭# Result of third call: 10‬

‭●‬ A
‭ rguments:‬
‭○‬ ‭Positional arguments (as shown above)‬
‭‬ K
○ ‭ eyword arguments (as shown above)‬
‭○‬ ‭Arbitrary positional arguments (*args): Gathers all remaining positional arguments‬
‭into a tuple.‬
‭Python‬
‭def‬‭func_with_args‬‭(*args):‬
‭print(‬‭f"Args received:‬‭{args}‬‭"‬‭)‬

‭func_with_args(‬‭1‬‭,‬‭2‭,‬‬‭"hello"‬‭,‬‭True‬‭)‬
‭# Output: Args received: (1, 2, 'hello', True)‬

‭○‬ A
‭ rbitrary keyword arguments (**kwargs): Gathers all remaining keyword arguments‬
‭into a dictionary.‬
‭Python‬
‭def‬‭func_with_kwargs‬‭(**kwargs):‬
‭print(‬‭f"Kwargs received:‬‭{kwargs}‬‭"‬‭)‬

‭func_with_kwargs(name=‬‭"David"‬‭, age=‬‭30‬‭, city=‬‭"Hyderabad"‬‭)‬


‭# Output: Kwargs received: {'name': 'David', 'age': 30, 'city': 'Hyderabad'}‬

‭○‬ C
‭ ombining all argument types:‬
‭Python‬
‭def‬‭func_with_all‬‭(required_param, *args, default_param=‬‭"default"‬‭, **kwargs):‬
‭print(‬‭f"Required Param:‬‭{required_param}‬‭"‭)‬ ‬
‭ rint(‬‭f"Positional Args (*args):‬‭{args}‬‭"‬‭)‬
p
‭print(‬‭f"Default Param:‬‭{default_param}‬‭"‭)‬ ‬
‭print(‬‭f"Keyword Args (**kwargs):‬‭{kwargs}‬‭"‭)‬ ‬

‭func_with_all(‬‭"first"‬‭,‬‭10‬‭,‬‭20‬‭, item=‬‭"laptop"‬‭, price=‬‭1200‬‭)‬


‭ Output:‬
#
‭# Required Param: first‬
‭# Positional Args (*args): (10, 20)‬
‭# Default Param: default‬
‭# Keyword Args (**kwargs): {'item': 'laptop', 'price': 1200}‬

‭●‬ R
‭ eturn Values:‬‭Functions can send data back using the return statement.‬
‭Python‬
‭def‬‭calculate_area‬‭(length, width):‬
‭area = length * width‬
‭return‬‭area‬‭# Returns the calculated area‬

r‭ oom_area = calculate_area(‬‭5‭,‬‬‭8‬‭)‬
‭print(‬‭f"The area of the room is:‬‭{room_area}‬‭square units."‬‭)‬‭# Output: The area of the room is: 40‬
‭square units.‬
‭●‬ L
‭ ambda Functions (Anonymous functions):‬‭Small, single-expression functions.‬
‭○‬ ‭Python‬
‭add =‬‭lambda‬‭x, y: x + y‬
‭print(‬‭f"Lambda add(2, 3):‬‭{add(‬‭2‭,‬‬‭3‬‭)}‬‭"‬‭)‬‭# Output: Lambda add(2, 3): 5‬

‭# Using lambda with sorted() for custom sorting‬


‭points = [(‬‭1‭,‬‬‭2‭)‬ , (‬‭0‭,‬‬‭5‬‭), (‬‭3‬‭,‬‭1‭)‬ ]‬
‭# Sort by the second element of each tuple‬
s‭ orted_points =‬‭sorted‬‭(points, key=‬‭lambda‬‭point: point[‬‭1‭]‬ )‬
‭print(‬‭f"Sorted points by y-coord:‬‭{sorted_points}‬‭"‭)‬ ‬‭# Output: Sorted points by y-coord: [(3,‬
‭1), (1, 2), (0, 5)]‬

‭6. Input/Output‬
‭●‬ I‭ nput from user:‬‭name = input("Enter your name: ") (returns a string)‬
‭Python‬
‭ user_name = input("Please enter your name: ")‬
#
‭# print(f"Hello, {user_name}!")‬
‭# Example interaction:‬
‭# Please enter your name: Gini‬
‭# Hello, Gini!‬

‭ Example: Taking integer input (requires type conversion)‬


#
‭# num_str = input("Enter a number: ")‬
‭# num = int(num_str) # Convert string to integer‬
‭# print(f"You entered: {num}, Type: {type(num)}")‬

‭●‬ P
‭ rint to console (print()):‬
‭○‬ ‭Basic printing:‬
‭Python‬
‭print(‬‭"Hello, World!"‬‭)‬‭# Output: Hello, World!‬

‭○‬ f‭ -string formatting (formatted string literals - modern and recommended):‬


‭Python‬
‭user_name =‬‭"Eve"‬
‭user_age =‬‭28‬
‭print(‬‭f"User:‬‭{user_name}‬‭, Age:‬‭{user_age}‬‭"‭)‬ ‬‭# Output: User: Eve, Age: 28‬

‭○‬ U
‭ sing sep and end arguments:‬
‭Python‬
‭item_price =‬‭150.00‬
‭print(‬‭"Product:"‬‭,‬‭"Laptop"‬‭,‬‭"Price:"‬‭, item_price, sep=‬‭" | "‬‭, end=‬‭".\n"‬‭)‬
‭# Output: Product: | Laptop | Price: | 150.0.‬
‭print(‬‭"This is on a new line because of previous 'end'."‬‭)‬

‭○‬ O
‭ ld-style % formatting (less common now):‬
‭Python‬
‭print(‬‭"My name is %s and I am %d years old."‬‭% (‬‭"Frank"‬‭,‬‭35‬‭))‬
‭# Output: My name is Frank and I am 35 years old.‬

‭○‬ .‭format() method (still widely used):‬


‭Python‬
‭print(‬‭"My name is {} and I am {} years old."‬‭.‭f‬ ormat‬‭(‭"‬ Grace"‬‭,‬‭22‬‭))‬
‭# Output: My name is Grace and I am 22 years old.‬

‭7. File Handling‬


‭●‬ O
‭ pening a file:‬
‭Python‬
‭ It's best practice to use 'with' statement for file handling.‬
#
‭# It ensures the file is automatically closed even if errors occur.‬
‭try‬‭:‬
‭# 'w' mode for writing (creates new file or truncates existing)‬
‭with‬‭open‬‭(‬‭"example.txt"‬‭,‬‭"w"‬‭)‬‭as‬‭file:‬
‭ le.write(‬‭"Hello, Python!\n"‬‭)‬
fi
‭file.write(‬‭"This is a new line.\n"‬‭)‬
‭print(‬‭"Successfully wrote to example.txt"‬‭)‬

‭# 'r' mode for reading‬


‭with‬‭open‬‭(‬‭"example.txt"‬‭,‬‭"r"‬‭)‬‭as‬‭file:‬
‭ ontent = file.read()‬
c
‭print(‬‭"\nContent of example.txt:"‬‭)‬
‭print(content)‬

‭# 'a' mode for appending (adds to end of file)‬


‭with‬‭open‬‭(‬‭"example.txt"‬‭,‬‭"a"‬‭)‬‭as‬‭file:‬
‭ le.write(‬‭"Appending another line.\n"‬‭)‬
fi
‭print(‬‭"\nSuccessfully appended to example.txt"‬‭)‬

‭with‬‭open‬‭(‬‭"example.txt"‬‭,‬‭"r"‬‭)‬‭as‬‭file:‬
‭ ontent_after_append = file.read()‬
c
‭print(‬‭"\nContent after append:"‬‭)‬
‭print(content_after_append)‬

‭except‬‭IOError‬‭as‬‭e:‬
‭print(‬‭f"Error handling file:‬‭{e}‬‭"‭)‬ ‬
‭# After running this, a file named 'example.txt' will be created/modified in the same directory.‬

‭○‬ M
‭ odes:‬
‭■‬ ‭"r": Read (default)‬
‭■‬ ‭"w": Write (creates new file or truncates existing)‬
‭■‬ ‭"a": Append (adds to end of file)‬
‭■‬ ‭"x": Exclusive creation (fails if file exists)‬
‭Python‬
‭ try:‬
#
‭# with open("new_exclusive_file.txt", "x") as file:‬
‭# file.write("This file was created exclusively.")‬
‭# print("new_exclusive_file.txt created successfully.")‬
‭# except FileExistsError:‬
‭# print("new_exclusive_file.txt already exists!")‬

‭■‬ "‭ b": Binary mode (e.g., for images, rb, wb)‬
‭Python‬
‭ with open("image.jpg", "rb") as img_file:‬
#
‭# binary_data = img_file.read()‬
‭# # process binary_data‬

‭ ‬ ‭"t": Text mode (default)‬



‭ ‬ ‭Reading:‬

‭○‬ ‭file.read(): Reads entire file content as a single string.‬
‭Python‬
‭# Already shown in the example above.‬

‭○‬ fi
‭ le.readline(): Reads one line at a time.‬
‭Python‬
‭with‬‭open‬‭(‬‭"example.txt"‬‭,‬‭"r"‬‭)‬‭as‬‭file:‬
‭first_line = file.readline()‬
‭second_line = file.readline()‬
‭print(‬‭f"First line:‬‭{first_line.strip()}‬‭"‬‭)‬
‭print(‬‭f"Second line:‬‭{second_line.strip()}‬‭"‬‭)‬
‭ Output (after previous writes):‬
#
‭# First line: Hello, Python!‬
‭# Second line: This is a new line.‬

‭○‬ fi
‭ le.readlines(): Reads all lines into a list of strings.‬
‭Python‬
‭with‬‭open‬‭(‬‭"example.txt"‬‭,‬‭"r"‬‭)‬‭as‬‭file:‬
‭all_lines = file.readlines()‬
‭print(‬‭"All lines as a list:"‬‭)‬
‭for‬‭line‬‭in‬‭all_lines:‬
‭print(line.strip())‬‭# .strip() removes trailing newline characters‬
‭ Output (after previous writes):‬
#
‭# All lines as a list:‬
‭# Hello, Python!‬
‭# This is a new line.‬
‭# Appending another line.‬

‭●‬ W
‭ riting:‬
‭○‬ ‭file.write(string): Writes a string to the file.‬
‭Python‬
‭# Already shown in the examples for "w" and "a" modes above.‬

‭8. Error Handling (Try-Except)‬

‭Python‬

‭try‬‭:‬
‭# Code that might raise an exception‬
‭num1 =‬‭int‬‭(‬‭input‬‭(‭"‬ Enter a numerator: "‬‭))‬
‭num2 =‬‭int‬‭(‭i‬nput‬‭(‭"‬ Enter a denominator: "‬‭))‬
‭result = num1 / num2‬
‭print(‬‭f"Result of division:‬‭{result}‬‭"‬‭)‬
‭except‬‭ZeroDivisionError:‬
‭print(‬‭"Error: Cannot divide by zero!"‬‭)‬
‭except‬‭ValueError:‬
‭print(‬‭"Error: Invalid input. Please enter integers only."‬‭)‬
‭except‬‭Exception‬‭as‬‭e:‬‭# Catch any other unexpected exceptions‬
‭print(‬‭f"An unexpected error occurred:‬‭{e}‬‭"‭)‬ ‬
‭else‬‭:‬
‭# Code to run if no exceptions occurred in the 'try' block‬
‭print(‬‭"Division successful, no errors encountered."‬‭)‬
‭ nally‬‭:‬
fi
‭# Code that always runs, regardless of exceptions‬
‭print(‬‭"Execution of the division attempt finished."‬‭)‬

‭print(‬‭"\n--- Example with a successful run ---"‬‭)‬


‭try‬‭:‬
‭x =‬‭10‬
‭y =‬‭2‬
z‭ = x / y‬
‭print(‬‭f"Result:‬‭{z}‬‭"‭)‬ ‬
‭except‬‭ZeroDivisionError:‬
‭print(‬‭"Caught ZeroDivisionError!"‬‭)‬
‭except‬‭ValueError:‬
‭print(‬‭"Caught ValueError!"‬‭)‬
‭else‬‭:‬
‭print(‬‭"No exceptions in this successful try block."‬‭)‬
‭finally‬‭:‬
‭print(‬‭"Finally block executed for successful run."‬‭)‬

‭ Example interaction and output for division:‬


#
‭# Enter a numerator: 10‬
‭# Enter a denominator: 0‬
‭# Error: Cannot divide by zero!‬
‭# Execution of the division attempt finished.‬

‭ Enter a numerator: abc‬


#
‭# Enter a denominator: 5‬
‭# Error: Invalid input. Please enter integers only.‬
‭# Execution of the division attempt finished.‬

‭ Enter a numerator: 10‬


#
‭# Enter a denominator: 2‬
‭# Result of division: 5.0‬
‭# Division successful, no errors encountered.‬
‭# Execution of the division attempt finished.‬

‭9. Object-Oriented Programming (OOP)‬


‭●‬ C
‭ lass Definition (class):‬‭This is the blueprint for creating objects (instances).‬
‭Python‬
‭class‬‭Dog:‬
‭# Class variable: shared by all instances of the class‬
‭species =‬‭"Canis familiaris"‬

‭# Constructor (`__init__`): Special method called when a new object is created.‬


‭def‬‭__init__‬‭(self, name, age):‬
‭"""‬
I‭nitializes a new Dog object.‬
‭'self' refers to the instance being created/operated on.‬
‭"""‬
‭self.name = name‬ ‭# Instance attribute (unique to each object)‬
‭self.age = age‬ ‭# Instance attribute‬
‭print(‬‭f"A new dog named‬‭{self.name}‬‭has been created!"‬‭)‬

‭# Instance Method: operates on the object's instance attributes.‬


‭def‬‭bark‬‭(self):‬
‭"""Returns a string indicating the dog's bark."""‬
‭return‬‭f"‬‭{self.name}‬‭says Woof!"‬

‭# Another Instance Method‬


‭def‬‭get_age_in_dog_years‬‭(self):‬
‭"""Calculates the dog's age in 'dog years'."""‬
‭return‬‭self.age *‬‭7‬

‭# Static Method (`@staticmethod`):‬


‭# Does not take `self` or `cls`. Behaves like a regular function‬
‭# but is logically related to the class.‬
‭ staticmethod‬
@
‭def‬‭describe_dog_breed‬‭():‬
‭"""Provides a general description about dogs."""‬
‭return‬‭"Dogs are loyal companions."‬

‭# Class Method (`@classmethod`):‬


‭# Takes the class itself (`cls`) as the first argument.‬
‭ Often used as alternative constructors or for methods that operate on class-level data.‬
#
‭@classmethod‬
‭def‬‭create_ancient_dog‬‭(cls, name):‬
‭"""Creates a Dog instance with a default 'ancient' age."""‬
‭return‬‭cls(name,‬‭100‬‭)‬‭# `cls(name, 100)` is equivalent to `Dog(name, 100)`‬

‭●‬ O
‭ bject Instantiation (Creating Instances):‬‭This is the act of creating an‬‭object‬‭(a‬
‭specific instance) from a‬‭class‬‭blueprint.‬
‭Python‬
‭# Creating instances (objects) of the Dog class‬
‭my_dog = Dog(‬‭"Buddy"‬‭,‬‭5‬‭)‬‭# Calls the __init__ method‬
‭your_dog = Dog(‬‭"Lucy"‬‭,‬‭2‭)‬ ‬
‭ Output:‬
#
‭# A new dog named Buddy has been created!‬
‭# A new dog named Lucy has been created!‬

‭●‬ A
‭ ccessing Attributes/Methods:‬
‭Python‬
‭# Accessing instance attributes‬
‭print(‬‭f"My dog's name:‬‭{my_dog.name}‬‭"‬‭)‬ ‭# Output: My dog's name: Buddy‬
‭print(‬‭f"Your dog's age:‬‭{your_dog.age}‬‭"‭)‬ ‬ ‭# Output: Your dog's age: 2‬
‭# Accessing class variables‬
‭print(‬‭f"Species (from class):‬‭{Dog.species}‬‭"‭)‬ ‬ ‭# Output: Species (from class): Canis‬
‭familiaris‬
‭print(‬‭f"My dog's species (from instance):‬‭{my_dog.species}‬‭"‬‭)‬ ‭# Output: My dog's species (from‬
‭instance): Canis familiaris‬

‭# Calling instance methods‬


‭ rint(my_dog.bark())‬
p ‭# Output: Buddy says Woof!‬
‭print(your_dog.get_age_in_dog_years())‬ ‭# Output: 14 (2 * 7)‬

‭# Calling static methods (can be called via class or instance, but class is common)‬
‭print(Dog.describe_dog_breed())‬ ‭# Output: Dogs are loyal companions.‬
‭print(my_dog.describe_dog_breed())‬ ‭# Output: Dogs are loyal companions.‬

‭# Calling class methods‬


‭ ncient_dog = Dog.create_ancient_dog(‬‭"Fido"‬‭)‬‭# Calls the create_ancient_dog class method‬
a
‭print(‬‭f"Ancient dog's name:‬‭{ancient_dog.name}‬‭, age:‬‭{ancient_dog.age}‬‭"‭)‬ ‬
‭ Output:‬
#
‭# A new dog named Fido has been created!‬
‭# Ancient dog's name: Fido, age: 100‬

‭●‬ I‭ nheritance:‬‭Creating a new class (subclass/child) from an existing class‬


‭(superclass/parent), inheriting its attributes and methods.‬
‭Python‬
‭class‬‭Labrador(Dog):‬‭# Labrador inherits from Dog‬
‭def‬‭__init__‬‭(self, name, age, color):‬
‭super‬‭().__init__(name, age)‬‭# Call the parent class's constructor‬
‭self.color = color‬

‭def‬‭retrieve‬‭(self):‬
‭return‬‭f"‬‭{self.name}‬‭is retrieving the ball!"‬

‭ olden = Labrador(‬‭"Goldie"‬‭,‬‭3‭,‬‬‭"Golden"‬‭)‬
g
‭print(‬‭f"New Labrador:‬‭{golden.name}‬‭, Age:‬‭{golden.age}‬‭, Color:‬‭{golden.color}‬‭"‭)‬ ‬
‭print(golden.bark())‬ ‭# Inherited method‬
‭print(golden.retrieve())‬ ‭# New method‬
‭ Output:‬
#
‭# A new dog named Goldie has been created!‬
‭# New Labrador: Goldie, Age: 3, Color: Golden‬
‭# Goldie says Woof!‬
‭# Goldie is retrieving the ball!‬

‭●‬ ‭Polymorphism:‬‭Objects of different classes can be treated uniformly if they share a‬


‭ ommon interface (e.g., method names).‬
c
‭Python‬
‭class‬‭Cat:‬
‭def‬‭make_sound‬‭(self):‬
‭return‬‭"Meow!"‬

‭class‬‭Cow:‬
‭def‬‭make_sound‬‭(self):‬
‭return‬‭"Moo!"‬

‭ We need to ensure Dog also has a make_sound method for this example to work fully‬
#
‭class‬‭NewDog(Dog):‬‭# A slightly modified Dog class for this example‬
‭def‬‭make_sound‬‭(self):‬
‭return‬‭self.bark()‬‭# Reusing the bark logic‬

‭ y_pet = Cat()‬
m
‭farm_animal = Cow()‬
‭my_new_dog = NewDog(‬‭"Sparky"‬‭,‬‭4‬‭)‬‭# Instantiate the NewDog‬

‭def‬‭animal_sound‬‭(animal):‬
‭print(animal.make_sound())‬

‭ rint(‬‭"\n--- Polymorphism Example ---"‬‭)‬


p
‭animal_sound(my_pet)‬ ‭# Output: Meow!‬
‭animal_sound(farm_animal)‬ ‭# Output: Moo!‬
‭animal_sound(my_new_dog)‬ ‭# Output: Sparky says Woof!‬

‭●‬ E
‭ ncapsulation:‬‭Bundling data (attributes) and methods that operate on the data within a‬
‭single unit (class). Access control (e.g., private attributes using __).‬
‭Python‬
‭class‬‭BankAccount:‬
‭def‬‭__init__‬‭(self, balance):‬
‭self.__balance = balance‬‭# __balance is a "private" attribute (name mangling)‬

‭def‬‭deposit‬‭(self, amount):‬
‭if‬‭amount >‬‭0‭:‬‬
‭self.__balance += amount‬
‭print(‬‭f"Deposited‬‭{amount}‬‭. New balance:‬‭{self.__balance}‬‭"‬‭)‬
‭else‬‭:‬
‭print(‬‭"Deposit amount must be positive."‬‭)‬

‭def‬‭withdraw‬‭(self, amount):‬
‭if‬‭0‬‭< amount <= self.__balance:‬
‭self.__balance -= amount‬
‭print(‬‭f"Withdrew‬‭{amount}‬‭. New balance:‬‭{self.__balance}‬‭"‬‭)‬
‭else‬‭:‬
‭print(‬‭"Invalid withdrawal amount or insufficient funds."‬‭)‬

‭def‬‭get_balance‬‭(self):‬
‭return‬‭self.__balance‬

‭ ccount = BankAccount(‬‭100‬‭)‬
a
‭account.deposit(‬‭50‬‭)‬ ‭# Output: Deposited 50. New balance: 150‬
‭account.withdraw(‬‭30‬‭)‬ ‭# Output: Withdrew 30. New balance: 120‬
‭print(‬‭f"Current balance:‬‭{account.get_balance()}‬‭"‭)‬ ‬‭# Output: Current balance: 120‬

‭ print(account.__balance) # This will raise an AttributeError, demonstrating encapsulation‬


#
‭# print(account._BankAccount__balance) # Can still be accessed, but convention says don't.‬

‭●‬ D
‭ under Methods (Magic Methods):‬‭Special methods identified by double underscores‬
‭(__method__) that allow Python classes to interface with built-in functions and operators.‬
‭○‬ ‭__str__(self): Defines the informal string representation of an object, returned by str()‬
‭and print(). Should be readable for end-users.‬
‭Python‬
‭class‬‭Book:‬
‭def‬‭__init__‬‭(self, title, author, pages):‬
s‭ elf.title = title‬
‭self.author = author‬
‭self.pages = pages‬

‭def‬‭__str__‬‭(self):‬
‭return‬‭f'"‬‭{self.title}‬‭" by‬‭{self.author}‬‭'‬

‭def‬‭__repr__‬‭(self):‬
‭return‬‭f"Book('‬‭{self.title}‬‭', '‬‭{self.author}‬‭',‬‭{self.pages}‬‭)"‬

‭ ook = Book(‬‭"The Hitchhiker's Guide to the Galaxy"‬‭,‬‭"Douglas Adams"‬‭,‬‭193‬‭)‬


b
‭print(book)‬‭# Uses __str__ # Output: "The Hitchhiker's Guide to the Galaxy" by Douglas‬
‭Adams‬

‭○‬ _‭ _repr__(self): Defines the "official" string representation of an object, returned by‬
‭repr() and used in interactive environments (like IDLE/Jupyter). Should be‬
‭unambiguous and, if possible, allow recreation of the object.‬
‭Python‬
‭# (Continued from Book example above)‬
‭book_repr =‬‭repr‬‭(book)‬
‭print(book_repr)‬‭# Uses __repr__ # Output: Book('The Hitchhiker\'s Guide to the Galaxy',‬
‭'Douglas Adams', 193)‬
‭# eval(book_repr) would ideally recreate the object if all constructor args are representable‬

‭○‬ _‭ _len__(self): Defines behavior for len().‬


‭Python‬
‭class‬‭MyCollection:‬
‭def‬‭__init__‬‭(self, items):‬
‭self.items = items‬
‭def‬‭__len__‬‭(self):‬
‭return‬‭len‬‭(self.items)‬

‭collection = MyCollection([‬‭1‬‭,‬‭2‭,‬‬‭3‬‭,‬‭4‭,‬‬‭5‬‭])‬
‭print(‬‭f"Length of collection:‬‭{‬‭len‬‭(collection)}‬‭"‭)‬ ‬‭# Output: Length of collection: 5‬

‭○‬ ‭__add__(self, other): Defines behavior for the‬‭+‬‭operator.‬

‭ lass Vector:‬
c
‭def init(self, x, y):‬
‭self.x = x‬
‭self.y = y‬
‭def add(self, other):‬
‭return Vector(self.x + other.x, self.y1 + other.y)‬
‭def str(self):2 # For easy printing‬
‭return f"Vector({self.x}, {self.y})"‬

v‭ 1 = Vector(1, 2)‬
‭v2 = Vector(3, 4)‬
‭v3 = v1 + v2 # Calls v1.__add__(v2)‬
‭print(f"v1 + v2 = {v3}") # Output: v1 + v2 = Vector(4, 6)‬
‭̀ ``‬
‭* Many more dunder methods exist for comparison (`__eq__`, `__lt__`), iteration (`__iter__`,‬
‭̀ __next__`), attribute access (`__getattr__`, `__setattr__`), callables (`__call__`), etc.‬

‭10. Useful Built-in Functions‬


‭●‬ l‭en(iterable): Returns the length of an object (list, string, tuple, dict, set).‬
‭Python‬
‭my_list = [‬‭10‬‭,‬‭20‬‭,‬‭30‬‭]‬
‭my_string =‬‭"Python"‬
‭my_dict = {‬‭"a"‬‭:‬‭1‭,‬‬‭"b"‬‭:‬‭2‭}‬ ‬
‭ rint(‬‭f"Length of list:‬‭{‭l‬en‬‭(my_list)}‬‭"‬‭)‬ ‭# Output: Length of list: 3‬
p
‭print(‬‭f"Length of string:‬‭{‭l‬en‬‭(my_string)}‬‭"‭)‬ ‬‭# Output: Length of string: 6‬
‭print(‬‭f"Length of dictionary:‬‭{‭l‬en‬‭(my_dict)}‬‭"‭)‬ ‬‭# Output: Length of dictionary: 2‬

‭●‬ t‭ ype(object): Returns the type of an object.‬


‭Python‬
‭num =‬‭123‬
‭text =‬‭"abc"‬
‭is_true =‬‭True‬
‭print(‬‭f"Type of num:‬‭{‭t‬ ype‬‭(num)}‬‭"‬‭)‬ ‭# Output: Type of num: <class 'int'>‬
‭print(‬‭f"Type of text:‬‭{‭t‬ ype‬‭(text)}‬‭"‬‭)‬ ‭# Output: Type of text: <class 'str'>‬
‭print(‬‭f"Type of is_true:‬‭{‬‭type‬‭(is_true)}‬‭"‭)‬ ‬‭# Output: Type of is_true: <class 'bool'>‬

‭●‬ s‭ tr(), int(), float(), bool(): Type conversion.‬


‭Python‬
‭num_str =‬‭"123"‬
‭num_int =‬‭int‬‭(num_str)‬
‭print(‬‭f"'‬‭{num_str}‬‭' as int:‬‭{num_int}‬‭, Type:‬‭{‭t‬ ype‬‭(num_int)}‬‭"‭)‬ ‬‭# Output: '123' as int: 123, Type: <class‬
‭'int'>‬

i‭nt_val =‬‭45‬
‭str_val =‬‭str‬‭(int_val)‬
‭print(‬‭f"‬‭{int_val}‬‭as str: '‬‭{str_val}‬‭', Type:‬‭{‭t‬ ype‬‭(str_val)}‬‭"‭)‬ ‬‭# Output: 45 as str: '45', Type: <class 'str'>‬

‭ oat_val =‬‭float‬‭(‬‭"3.14"‬‭)‬
fl
‭print(‬‭f"'3.14' as float:‬‭{float_val}‬‭, Type:‬‭{‭t‬ ype‬‭(float_val)}‬‭"‭)‬ ‬‭# Output: '3.14' as float: 3.14, Type: <class‬
‭'float'>‬

z‭ ero =‬‭0‬
‭empty_string =‬‭""‬
‭list_val = [‬‭1‭]‬ ‬
‭print(‬‭f"bool(0):‬‭{‭b ‬ ool‬‭(zero)}‬‭"‬‭)‬ ‭# Output: bool(0): False‬
‭print(‬‭f"bool(''):‬‭{‭b
‬ ool‬‭(empty_string)}‬‭"‬‭)‬ ‭# Output: bool(''): False‬
‭print(‬‭f"bool([1]):‬‭{‭b‬ ool‬‭(list_val)}‬‭"‬‭)‬ ‭# Output: bool([1]): True‬

‭●‬ r‭ ange(start, stop, step): Generates a sequence of numbers (used in for loops).‬
‭Python‬
‭# Already covered in for loops, but here's a direct example:‬
‭my_range =‬‭range‬‭(‬‭3‭,‬‬‭10‬‭,‬‭2‭)‬ ‬‭# Start at 3, stop before 10, step by 2‬
‭print(‬‭f"Numbers in range(3, 10, 2):‬‭{‭l‬ist‬‭(my_range)}‬‭"‭)‬ ‬‭# Output: Numbers in range(3, 10, 2): [3, 5, 7,‬
‭9]‬

‭●‬ ‭min(), max(), sum(): For numerical iterables.‬


‭ ython‬
P
‭numbers = [‬‭10‬‭,‬‭5‬‭,‬‭8‭,‬‬‭12‬‭,‬‭3‬‭]‬
‭print(‬‭f"Min:‬‭{‭m
‬ in‬‭(numbers)}‬‭"‬‭)‬‭# Output: Min: 3‬
‭print(‬‭f"Max:‬‭{‭m
‬ ax‬‭(numbers)}‬‭"‬‭)‬‭# Output: Max: 12‬
‭print(‬‭f"Sum:‬‭{‬‭sum‬‭(numbers)}‬‭"‬‭)‬‭# Output: Sum: 38‬

‭●‬ a
‭ bs(): Absolute value.‬
‭Python‬
‭print(‬‭f"Absolute value of -5:‬‭{‭a ‬ bs‬‭(-‬‭5‭)‬ }‬‭"‬‭)‬‭# Output: Absolute value of -5: 5‬
‭print(‬‭f"Absolute value of 5:‬‭{‬‭abs‬‭(‬‭5‭)‬ }‬‭"‬‭)‬ ‭# Output: Absolute value of 5: 5‬

‭●‬ r‭ ound(): Round to the nearest integer.‬


‭Python‬
‭print(‬‭f"round(3.14):‬‭{‭r‬ ound‬‭(‬‭3.14‬‭)}‬‭"‭)‬ ‬ ‭# Output: round(3.14): 3‬
‭print(‬‭f"round(3.7):‬‭{‭r‬ ound‬‭(‬‭3.7‬‭)}‬‭"‬‭)‬ ‭# Output: round(3.7): 4‬
‭print(‬‭f"round(2.5):‬‭{‬‭round‬‭(‬‭2.5‬‭)}‬‭"‭)‬ ‬ ‭# Output: round(2.5): 2 (rounds to nearest even)‬
‭print(‬‭f"round(3.5):‬‭{‭r‬ ound‬‭(‬‭3.5‬‭)}‬‭"‬‭)‬ ‭# Output: round(3.5): 4‬
‭print(‬‭f"round(3.14159, 2):‬‭{‬‭round‬‭(‭3‬ .14159‬‭,‬‭2‭)‬ }‬‭"‭)‬ ‬‭# Output: round(3.14159, 2): 3.14‬

‭●‬ e
‭ numerate(): Iterate with an index.‬
‭Python‬
‭items = [‬‭"a"‬‭,‬‭"b"‬‭,‬‭"c"‬‭]‬
‭for‬‭index, value‬‭in‬‭enumerate‬‭(items):‬
‭print(‬‭f"Index‬‭{index}‬‭:‬‭{value}‬‭"‬‭)‬
‭ Output:‬
#
‭# Index 0: a‬
‭# Index 1: b‬
‭# Index 2: c‬

‭●‬ z‭ ip(): Combine multiple iterables.‬


‭Python‬
‭names = [‬‭"Alice"‬‭,‬‭"Bob"‬‭]‬
‭ages = [‬‭25‬‭,‬‭30‬‭]‬
‭for‬‭name, age‬‭in‬‭zip‬‭(names, ages):‬
‭print(‬‭f"‬‭{name}‬‭is‬‭{age}‬‭years old."‬‭)‬
‭ Output:‬
#
‭# Alice is 25 years old.‬
‭# Bob is 30 years old.‬

‭●‬ m
‭ ap(): Apply a function to all items in an iterable.‬
‭Python‬
‭def‬‭square‬‭(num):‬
‭return‬‭num * num‬
‭numbers = [‬‭1‭,‬‬‭2‭,‬‬‭3‭,‬‬‭4‭]‬ ‬
s‭ quared_numbers =‬‭list‬‭(‬‭map‬‭(square, numbers))‬
‭print(‬‭f"Squared numbers (map):‬‭{squared_numbers}‬‭"‬‭)‬‭# Output: Squared numbers (map): [1, 4, 9,‬
1‭ 6]‬
‭# Often replaced by list comprehensions for readability‬

‭●‬ fi
‭ lter(): Filter items from an iterable based on a function.‬
‭Python‬
‭def‬‭is_even‬‭(num):‬
‭return‬‭num %‬‭2‬‭==‬‭0‬
‭ umbers = [‬‭1‭,‬‬‭2‭,‬‬‭3‭,‬‬‭4‭,‬‬‭5‭,‬‬‭6‬‭]‬
n
‭even_numbers_filtered =‬‭list‬‭(‭fi ‬ lter‬‭(is_even, numbers))‬
‭print(‬‭f"Even numbers (filter):‬‭{even_numbers_filtered}‬‭"‭)‬ ‬‭# Output: Even numbers (filter): [2, 4, 6]‬
‭# Often replaced by list comprehensions for readability‬

‭●‬ s‭ orted(): Returns a new sorted list from the items in an iterable.‬
‭Python‬
‭unsorted_list = [‬‭3‭,‬‬‭1‭,‬‬‭4‭,‬‬‭1‬‭,‬‭5‭,‬‬‭9‬‭,‬‭2‭]‬ ‬
‭sorted_list =‬‭sorted‬‭(unsorted_list)‬
‭print(‬‭f"Sorted list:‬‭{sorted_list}‬‭"‬‭)‬‭# Output: Sorted list: [1, 1, 2, 3, 4, 5, 9]‬

‭# Custom sort key with lambda (as seen before)‬


‭words = [‬‭"banana"‬‭,‬‭"apple"‬‭,‬‭"cherry"‬‭]‬
s‭ orted_by_length =‬‭sorted‬‭(words, key=‬‭len‬‭)‬
‭print(‬‭f"Sorted by length:‬‭{sorted_by_length}‬‭"‭)‬ ‬‭# Output: Sorted by length: ['apple', 'banana',‬
‭'cherry']‬

‭●‬ r‭ eversed(): Returns a reverse iterator.‬


‭Python‬
‭my_list = [‬‭1‬‭,‬‭2‭,‬‬‭3‭,‬‬‭4‬‭]‬
‭reversed_list =‬‭list‬‭(‭r‬ eversed‬‭(my_list))‬
‭print(‬‭f"Reversed list:‬‭{reversed_list}‬‭"‬‭)‬‭# Output: Reversed list: [4, 3, 2, 1]‬

‭●‬ a
‭ ny(), all():‬
‭○‬ ‭any(): Returns True if‬‭any‬‭element of the iterable is true.‬
‭○‬ ‭all(): Returns True if‬‭all‬‭elements of the iterable are true.‬
‭ ython‬
P
‭bool_list1 = [‬‭True‬‭,‬‭False‬‭,‬‭True‬‭]‬
‭bool_list2 = [‬‭False‬‭,‬‭False‬‭,‬‭False‬‭]‬
‭bool_list3 = [‬‭True‬‭,‬‭True‬‭,‬‭True‬‭]‬

‭ rint(‬‭f"any(‬‭{bool_list1}‬‭):‬‭{‭a
p ‬ ny‬‭(bool_list1)}‬‭"‭)‬ ‬‭# Output: any([True, False, True]): True‬
‭print(‬‭f"any(‬‭{bool_list2}‬‭):‬‭{‭a ‬ ny‬‭(bool_list2)}‬‭"‬‭)‬‭# Output: any([False, False, False]): False‬
‭print(‬‭f"all(‬‭{bool_list1}‬‭):‬‭{‭a
‬ ll‬‭(bool_list1)}‬‭"‬‭)‬‭# Output: all([True, False, True]): False‬
‭print(‬‭f"all(‬‭{bool_list3}‬‭):‬‭{‭a
‬ ll‬‭(bool_list3)}‬‭"‬‭)‬‭# Output: all([True, True, True]): True‬
‭11. List, Dictionary, and Set Comprehensions‬
‭●‬ L
‭ ist Comprehensions:‬‭(Already covered, but good to reiterate here)‬
‭Python‬
‭squares = [x**‬‭2‬‭for‬‭x‬‭in‬‭range‬‭(‭5‬ ‬‭)]‬
‭print(‬‭f"Squares:‬‭{squares}‬‭"‭)‬ ‬‭# Output: Squares: [0, 1, 4, 9, 16]‬

‭ ltered_list = [x‬‭for‬‭x‬‭in‬‭[‭1‬ ‬‭,‬‭2‭,‬‬‭3‬‭,‬‭4‭,‬‬‭5‬‭]‬‭if‬‭x %‬‭2‬‭!=‬‭0‬‭]‬


fi
‭print(‬‭f"Filtered odd numbers:‬‭{filtered_list}‬‭"‬‭)‬‭# Output: Filtered odd numbers: [1, 3, 5]‬

‭●‬ D
‭ ictionary Comprehensions:‬
‭Python‬
‭keys = [‬‭"a"‬‭,‬‭"b"‬‭,‬‭"c"‬‭]‬
‭values = [‬‭1‭,‬‬‭2‭,‬‬‭3‭]‬ ‬
‭my_dict_comp = {k: v‬‭for‬‭k, v‬‭in‬‭zip‬‭(keys, values)}‬
‭print(‬‭f"Dict comprehension:‬‭{my_dict_comp}‬‭"‬‭)‬‭# Output: Dict comprehension: {'a': 1, 'b': 2, 'c': 3}‬

s‭ quared_dict = {num: num**‬‭2‬‭for‬‭num‬‭in‬‭range‬‭(‭1‬ ‬‭,‬‭4‭)‬ }‬


‭print(‬‭f"Squared dict:‬‭{squared_dict}‬‭"‬‭)‬‭# Output: Squared dict: {1: 1, 2: 4, 3: 9}‬

‭●‬ S
‭ et Comprehensions:‬
‭Python‬
‭unique_squares = {x**‬‭2‬‭for‬‭x‬‭in‬‭[-‬‭1‬‭,‬‭1‬‭,‬‭2‬‭, -‬‭2‭]‬ }‬‭# Duplicates are removed automatically‬
‭print(‬‭f"Set comprehension:‬‭{unique_squares}‬‭"‭)‬ ‬‭# Output: Set comprehension: {1, 4} (order may‬
‭vary)‬

‭12. String Methods‬


‭●‬ s‭ tring.upper(), string.lower(), string.strip(), string.split(delimiter),‬
‭delimiter.join(list_of_strings), string.replace(old, new), string.find(substring),‬
‭string.startswith(prefix), string.endswith(suffix): (Examples already provided in earlier‬
‭section, these remain essential).‬
‭○‬ ‭Additional useful string methods:‬
‭■‬ ‭string.count(substring): Returns the number of occurrences of a substring.‬
‭Python‬
‭text =‬‭"banana"‬
‭print(‬‭f"Count of 'a' in 'banana':‬‭{text.count(‬‭'a'‬‭)}‬‭"‬‭)‬‭# Output: Count of 'a' in 'banana': 3‬

‭■‬ s‭ tring.isdigit(), string.isalpha(), string.isalnum(): Check character types.‬


‭Python‬
‭print(‬‭f"'123'.isdigit():‬‭{‬‭'123'‬‭.isdigit()}‬‭"‭)‬ ‬ ‭# Output: '123'.isdigit(): True‬
‭ rint(‬‭f"'abc'.isalpha():‬‭{‭'‬abc'‬‭.isalpha()}‬‭"‭)‬ ‬ ‭# Output: 'abc'.isalpha(): True‬
p
‭print(‬‭f"'ab1'.isalnum():‬‭{‬‭'ab1'‬‭.isalnum()}‬‭"‭)‬ ‬ ‭# Output: 'ab1'.isalnum(): True‬
‭print(‬‭f"'abc '.isalpha():‬‭{‭'‬abc '‬‭.isalpha()}‬‭"‭)‬ ‬‭# Output: 'abc '.isalpha(): False (because of‬
‭space)‬

‭■‬ s‭ tring.capitalize(), string.title(): Capitalize first letter or each word.‬


‭Python‬
‭print(‬‭f"'hello world'.capitalize():‬‭{‭'‬hello world'‬‭.capitalize()}‬‭"‭)‬ ‬‭# Output: 'hello‬
‭world'.capitalize(): Hello world‬
‭print(‬‭f"'hello world'.title():‬‭{‬‭'hello world'‬‭.title()}‬‭"‭)‬ ‬ ‭# Output: 'hello world'.title(): Hello‬
‭World‬

‭13. Modules and Packages‬


‭●‬ I‭ mporting a module:‬‭import math‬
‭Python‬
‭import‬‭math‬
‭print(‬‭f"Square root of 16:‬‭{math.sqrt(‬‭16‬‭)}‬‭"‬‭)‬‭# Output: Square root of 16: 4.0‬
‭print(‬‭f"Pi value:‬‭{math.pi}‬‭"‬‭)‬ ‭# Output: Pi value: 3.141592653589793‬

‭●‬ I‭ mporting specific items:‬‭from datetime import date‬


‭Python‬
‭from‬‭datetime‬‭import‬‭date, timedelta‬
‭today = date.today()‬
‭print(‬‭f"Today's date:‬‭{today}‬‭"‬‭)‬‭# Output: Today's date: 2025-06-10 (or current date)‬

t‭ omorrow = today + timedelta(days=‬‭1‬‭)‬


‭print(‬‭f"Tomorrow's date:‬‭{tomorrow}‬‭"‬‭)‬‭# Output: Tomorrow's date: 2025-06-11 (or tomorrow's‬
‭date)‬

‭●‬ A
‭ liasing imports:‬‭import numpy as np‬
‭Python‬
‭ For this to run, you'd typically need to install numpy: pip install numpy‬
#
‭# import numpy as np‬
‭# arr = np.array([1, 2, 3])‬
‭# print(f"Numpy array: {arr}")‬

‭●‬ I‭ nstalling packages:‬‭pip install package_name‬


‭Bash‬
‭ To install a package like 'requests' (for making HTTP requests):‬
#
‭# pip install requests‬

‭# Then you can import and use it in your Python code:‬


‭ import requests‬
#
‭# response = requests.get("https://www.google.com")‬
‭# print(f"Google status code: {response.status_code}")‬

‭14. Advanced Concepts‬


‭●‬ D
‭ ecorators:‬‭Functions that modify or enhance other functions.‬
‭Python‬
‭def‬‭my_decorator‬‭(func):‬
‭def‬‭wrapper‬‭():‬
‭ rint(‬‭"Something is happening before the function is called."‬‭)‬
p
‭func()‬
‭print(‬‭"Something is happening after the function is called."‬‭)‬
‭return‬‭wrapper‬

‭ my_decorator‬‭# Syntactic sugar for say_hello = my_decorator(say_hello)‬


@
‭def‬‭say_hello‬‭():‬
‭print(‬‭"Hello!"‬‭)‬

s‭ ay_hello()‬
‭# Output:‬
‭# Something is happening before the function is called.‬
‭# Hello!‬
‭# Something is happening after the function is called.‬

‭●‬ G
‭ enerators (yield):‬‭Functions that return an iterator that produces a sequence of results‬
‭on demand, instead of building a full list in memory.‬
‭Python‬
‭def‬‭count_up_to‬‭(max_num):‬
‭count =‬‭1‬
‭while‬‭count <= max_num:‬
‭yield‬‭count‬‭# Pauses execution and yields a value‬
‭count +=‬‭1‬

‭ y_generator = count_up_to(‬‭3‭)‬ ‬
m
‭print(‬‭f"First yield:‬‭{‬‭next‬‭(my_generator)}‬‭"‭)‬ ‬ ‭# Output: First yield: 1‬
‭print(‬‭f"Second yield:‬‭{‬‭next‬‭(my_generator)}‬‭"‬‭)‬‭# Output: Second yield: 2‬
‭print(‬‭"Looping through the rest:"‬‭)‬
‭for‬‭num‬‭in‬‭my_generator:‬
‭print(num)‬
‭ Output:‬
#
‭# Looping through the rest:‬
‭# 3‬
‭●‬ C
‭ ontext Managers (with statement):‬‭Ensures resources are properly acquired and‬
‭released (e.g., files, locks). Uses __enter__ and __exit__ methods.‬
‭Python‬
‭ Example (File handling is the most common built-in context manager)‬
#
‭# Shown in File Handling section:‬
‭# with open("myfile.txt", "w") as f:‬
‭# f.write("Hello")‬

‭ Custom context manager example:‬


#
‭class‬‭MyContext:‬
‭def‬‭__enter__‬‭(self):‬
‭print(‬‭"Entering the context"‬‭)‬
‭return‬‭self‬

‭def‬‭__exit__‬‭(self, exc_type, exc_val, exc_tb):‬


‭print(‬‭"Exiting the context"‬‭)‬
‭if‬‭exc_type:‬‭# If an exception occurred‬
‭print(‬‭f"An exception occurred:‬‭{exc_val}‬‭"‬‭)‬
‭return‬‭False‬‭# Propagate the exception if it happened‬

‭with‬‭MyContext()‬‭as‬‭mc:‬
‭print(‬‭"Inside the context"‬‭)‬
‭ raise ValueError("Something went wrong!") # Uncomment to see exception handling‬
#
‭# Output:‬
‭# Entering the context‬
‭# Inside the context‬
‭# (If ValueError was uncommented: An exception occurred: Something went wrong!)‬
‭# Exiting the context‬

‭●‬ I‭ terators:‬‭Objects that implement __iter__() and __next__() methods, allowing them to be‬
‭iterated over (e.g., in for loops).‬
‭Python‬
‭class‬‭MyRangeIterator:‬
‭def‬‭__init__‬‭(self, limit):‬
‭self.limit = limit‬
‭self.current =‬‭0‬

‭def‬‭__iter__‬‭(self):‬
‭return‬‭self‬

‭def‬‭__next__‬‭(self):‬
‭if‬‭self.current < self.limit:‬
‭self.current +=‬‭1‬
‭return‬‭self.current‬
‭else‬‭:‬
‭raise‬‭StopIteration‬

‭print(‬‭"\n--- Custom Iterator Example ---"‬‭)‬


‭for‬‭num‬‭in‬‭MyRangeIterator(‬‭3‭)‬ :‬
‭print(‬‭f"Iterated:‬‭{num}‬‭"‬‭)‬
‭ Output:‬
#
‭# Iterated: 1‬
‭# Iterated: 2‬
‭# Iterated: 3‬

‭●‬ D
‭ escriptors:‬‭Protocol for how attribute access works, allowing customization of attribute‬
‭behavior (advanced OOP).‬
‭Python‬
‭class‬‭Ten:‬
‭def‬‭__get__‬‭(self, obj, objtype=‬‭None‬‭):‬
‭return‬‭10‬
‭def‬‭__set__‬‭(self, obj, value):‬
‭print(‬‭f"Cannot set 'Ten' directly, trying to set‬‭{value}‬‭"‭)‬ ‬
‭# Usually, you'd raise an AttributeError or handle it.‬
‭# For demonstration, we'll allow setting but show the message.‬
‭# To truly prevent setting, you'd typically raise AttributeError.‬
‭obj.__dict__[‬‭'x'‬‭] = value‬‭# Sets directly on the instance's dictionary‬

‭class‬‭A:‬
‭x = Ten()‬‭# x is now a descriptor‬

‭ _instance = A()‬
a
‭print(‬‭f"Accessing a_instance.x (via descriptor):‬‭{a_instance.x}‬‭"‬‭)‬‭# Output: Accessing a_instance.x‬
‭(via descriptor): 10‬
‭a_instance.x =‬‭20‬‭# Calls Ten.__set__‬
‭# Output: Cannot set 'Ten' directly, trying to set 20‬
‭print(‬‭f"Accessing a_instance.x after assignment:‬‭{a_instance.x}‬‭"‬‭)‬‭# Output: Accessing‬
‭a_instance.x after assignment: 20‬
‭# Note: If __set__ was not defined, a.x = 20 would create an instance attribute named 'x' that‬
‭shadows the descriptor.‬

‭●‬ M
‭ etaclasses:‬‭Classes that create classes. They allow you to customize class creation.‬
‭Python‬
‭ Very advanced, often used in frameworks.‬
#
‭class‬‭MyMeta(‬‭type‬‭):‬
‭def‬‭__new__‬‭(mcs, name, bases, attrs):‬
‭print(‬‭f"Metaclass: Creating class‬‭{name}‬‭"‬‭)‬
‭# Add a default attribute to all classes created with this metaclass‬
‭attrs[‬‭'creation_info'‬‭] =‬‭f"Class‬‭{name}‬‭created by MyMeta"‬
‭return‬‭super‬‭().__new__(mcs, name, bases, attrs)‬

‭class‬‭MyClass(metaclass=MyMeta):‬
‭pass‬

‭class‬‭AnotherClass(MyClass):‬‭# This class also uses MyMeta via inheritance‬


‭pass‬

‭ rint(MyClass.creation_info)‬ ‭# Output: Class MyClass created by MyMeta‬


p
‭print(AnotherClass.creation_info)‬‭# Output: Class AnotherClass created by MyMeta‬

‭●‬ A
‭ synchronous Programming (async/await):‬‭For concurrent execution without using‬
‭threads, primarily for I/O-bound tasks.‬
‭○‬ ‭async‬‭: Defines a coroutine, which is a function that can pause its execution and‬
‭resume later.‬
‭○‬ ‭await‬‭: Pauses the execution of the current coroutine until the awaited async‬
‭operation (like I/O) completes.‬
‭Python‬
‭import‬‭asyncio‬
‭import‬‭time‬

‭async‬‭def‬‭fetch_data‬‭(delay, data_id):‬
‭"""Simulates an asynchronous I/O operation (e.g., network request)."""‬
‭print(‬‭f"[‬‭{time.strftime(‬‭'%H:%M:%S'‬‭)}‬‭] Start fetching data‬‭{data_id}‬‭(will take‬‭{delay}‬‭s)..."‬‭)‬
‭await‬‭asyncio.sleep(delay)‬‭# Pauses this coroutine, allows others to run‬
‭print(‬‭f"[‬‭{time.strftime(‬‭'%H:%M:%S'‬‭)}‬‭] Finished fetching data‬‭{data_id}‬‭."‬‭)‬
‭return‬‭f"Data‬‭{data_id}‬‭fetched successfully"‬

‭async‬‭def‬‭main‬‭():‬
‭"""The main asynchronous function to run."""‬
‭print(‬‭f"[‬‭{time.strftime(‬‭'%H:%M:%S'‬‭)}‬‭] Starting main program."‬‭)‬

‭# Create tasks for concurrent execution‬


t‭ ask1 = asyncio.create_task(fetch_data(‬‭3‭,‬‬‭1‬‭))‬‭# This task will take 3 seconds‬
‭task2 = asyncio.create_task(fetch_data(‬‭1‭,‬‬‭2‭)‬ )‬‭# This task will take 1 second‬
‭task3 = asyncio.create_task(fetch_data(‬‭2‭,‬‬‭3‭)‬ )‬‭# This task will take 2 seconds‬

‭# Await all tasks concurrently. `asyncio.gather` waits for all of them.‬


‭# The order of results in `gathered_results` corresponds to the order of tasks.‬
‭gathered_results =‬‭await‬‭asyncio.gather(task1, task2, task3)‬

‭print(‬‭f"[‬‭{time.strftime(‬‭'%H:%M:%S'‬‭)}‬‭] All data fetched:‬‭{gathered_results}‬‭"‬‭)‬


‭print(‬‭f"[‬‭{time.strftime(‬‭'%H:%M:%S'‬‭)}‬‭] Main program finished."‬‭)‬

‭ To run an async function, you typically use asyncio.run()‬


#
‭# asyncio.run(main())‬
‭# Example Output (timestamps will vary based on execution time):‬
‭# [01:30:00] Starting main program.‬
‭# [01:30:00] Start fetching data 1 (will take 3s)...‬
‭# [01:30:00] Start fetching data 2 (will take 1s)...‬
‭# [01:30:00] Start fetching data 3 (will take 2s)...‬
‭# [01:30:01] Finished fetching data 2.‬
‭# [01:30:02] Finished fetching data 3.‬
‭# [01:30:03] Finished fetching data 1.‬
‭# [01:30:03] All data fetched: ['Data 1 fetched successfully', 'Data 2 fetched successfully',‬
‭'Data 3 fetched successfully']‬
‭# [01:30:03] Main program finished.‬
‭ otice how tasks 2 and 3 finish before task 1, even though task 1 was started first.‬
N
‭This is because await asyncio.sleep() allows other tasks to run while one is "sleeping"‬
‭(waiting for I/O).‬

‭15. Common Design Patterns in Python‬


‭Design patterns are reusable solutions to common problems in software design.‬
‭●‬ S
‭ ingleton Pattern (Creational):‬‭Ensures a class has only one instance and provides a‬
‭global point of access to that instance.‬
‭Python‬
‭class‬‭Singleton:‬
‭_instance =‬‭None‬‭# Class-level attribute to hold the single instance‬

‭def‬‭__new__‬‭(cls, *args, **kwargs):‬


‭if‬‭cls._instance‬‭is‬‭None‬‭:‬
‭ rint(‬‭"Creating the one and only Singleton instance..."‬‭)‬
p
‭cls._instance =‬‭super‬‭().__new__(cls)‬
‭return‬‭cls._instance‬

‭def‬‭__init__‬‭(self, value):‬
‭# This __init__ will be called every time Singleton() is called,‬
‭# but the actual instance creation only happens once via __new__.‬
‭# So, handle initialization carefully for Singletons.‬
‭if‬‭not‬‭hasattr‬‭(self,‬‭'_initialized'‬‭):‬‭# Prevent re-initialization‬
s‭ elf.value = value‬
‭self._initialized =‬‭True‬
‭print(‬‭f"Singleton initialized with value:‬‭{self.value}‬‭"‭)‬ ‬

‭s1 = Singleton(‬‭"First Value"‬‭)‬


‭s2 = Singleton(‬‭"Second Value"‬‭)‬‭# This will not create a new instance, just re-call __init__‬

‭ rint(‬‭f"s1 is s2:‬‭{s1‬‭is‬‭s2}‬‭"‭)‬ ‬‭# Output: s1 is s2: True (they are the same object)‬
p
‭print(‬‭f"s1.value:‬‭{s1.value}‬‭"‭)‬ ‬‭# Output: s1.value: First Value (if _initialized check is used)‬
‭print(‬‭f"s2.value:‬‭{s2.value}‬‭"‬‭)‬‭# Output: s2.value: First Value‬

‭ Output:‬
#
‭# Creating the one and only Singleton instance...‬
‭# Singleton initialized with value: First Value‬
‭# Singleton initialized with value: Second Value (if _initialized check not used)‬
‭# s1 is s2: True‬
‭# s1.value: First Value‬
‭# s2.value: First Value‬

‭●‬ F
‭ actory Method Pattern (Creational):‬‭Defines an interface for creating an object, but‬
‭lets subclasses decide which class to instantiate.‬‭3‬
‭Python‬
‭class‬‭Dog:‬
‭def‬‭speak‬‭(self):‬
‭return‬‭"Woof!"‬

‭class‬‭Cat:‬
‭def‬‭speak‬‭(self):‬
‭return‬‭"Meow!"‬

‭class‬‭AnimalFactory:‬
‭@staticmethod‬
‭def‬‭create_animal‬‭(animal_type):‬
‭if‬‭animal_type ==‬‭"dog"‬‭:‬
‭return‬‭Dog()‬
‭elif‬‭animal_type ==‬‭"cat"‬‭:‬
‭return‬‭Cat()‬
‭else‬‭:‬
‭raise‬‭ValueError(‬‭"Unknown animal type"‬‭)‬

‭ rint(‬‭"\n--- Factory Pattern Example ---"‬‭)‬


p
‭my_dog = AnimalFactory.create_animal(‬‭"dog"‬‭)‬
‭my_cat = AnimalFactory.create_animal(‬‭"cat"‬‭)‬

‭ rint(my_dog.speak())‬‭# Output: Woof!‬


p
‭print(my_cat.speak())‬‭# Output: Meow!‬

‭●‬ A
‭ dapter Pattern (Structural):‬‭Allows objects with incompatible interfaces to‬
‭collaborate.‬
‭Python‬
‭ Existing "legacy" system interface‬
#
‭class‬‭OldLogger:‬
‭def‬‭log_message‬‭(self, msg):‬
‭print(‬‭f"Old Log:‬‭{msg}‬‭"‬‭)‬

‭ New system expects a different interface‬


#
‭class‬‭NewAnalyticsSystem:‬
‭def‬‭send_event‬‭(self, event_name, data):‬
‭print(‬‭f"New Analytics: Event='‬‭{event_name}‬‭', Data=‬‭{data}‬‭"‭)‬ ‬

‭ Adapter to make OldLogger compatible with NewAnalyticsSystem expectation‬


#
‭class‬‭LoggerToAnalyticsAdapter:‬
‭def‬‭__init__‬‭(self, logger):‬
‭self.logger = logger‬

‭def‬‭send_event‬‭(self, event_name, data):‬


‭# Adapt the call: convert event to log message‬
‭ dapted_message =‬‭f"Analytics Event:‬‭{event_name}‬‭, Data:‬‭{data}‬‭"‬
a
‭self.logger.log_message(adapted_message)‬

‭ rint(‬‭"\n--- Adapter Pattern Example ---"‬‭)‬


p
‭old_logger_instance = OldLogger()‬
‭analytics_system_instance = NewAnalyticsSystem()‬

‭# Direct call to new system‬


‭analytics_system_instance.send_event(‬‭"UserLogin"‬‭, {‬‭"user_id"‬‭:‬‭123‬‭})‬

‭# Using the adapter to send an "event" through the old logger‬


‭ dapter = LoggerToAnalyticsAdapter(old_logger_instance)‬
a
‭adapter.send_event(‬‭"PageView"‬‭, {‬‭"page"‬‭:‬‭"/home"‬‭})‬
‭ Output:‬
#
‭# Old Log: Analytics Event: PageView, Data: {'page': '/home'}‬

‭●‬ B
‭ uilder Pattern (Creational):‬‭Separates the construction of a complex object from its‬
‭representation, allowing the same construction process‬‭4‬ ‭to create different‬
r‭ epresentations.‬‭5‬
‭Python‬
‭class‬‭Burger:‬
‭def‬‭__init__‬‭(self):‬
s‭ elf.buns =‬‭None‬
‭self.patty =‬‭None‬
‭self.cheese =‬‭None‬
‭self.sauces = []‬
‭self.vegetables = []‬

‭def‬‭__str__‬‭(self):‬
‭return‬‭(‬‭f"Burger with:‬‭{self.buns}‬‭buns,‬‭{self.patty}‬‭patty, "‬
‭f"‬‭{‭'‬cheese'‬‭if‬‭self.cheese‬‭else‬‭'no cheese'‬‭}‬‭, "‬
‭f"sauces:‬‭{‭'‬, '‬‭.join(self.sauces)‬‭if‬‭self.sauces‬‭else‬‭'none'‬‭}‬‭, "‬
‭f"veg:‬‭{‭'‬, '‬‭.join(self.vegetables)‬‭if‬‭self.vegetables‬‭else‬‭'none'‬‭}‬‭"‭)‬ ‬

‭class‬‭BurgerBuilder:‬
‭def‬‭__init__‬‭(self):‬
‭self.burger = Burger()‬

‭def‬‭add_buns‬‭(self, bun_type):‬
‭self.burger.buns = bun_type‬
‭return‬‭self‬‭# Allows chaining‬

‭def‬‭add_patty‬‭(self, patty_type):‬
‭self.burger.patty = patty_type‬
‭return‬‭self‬

‭def‬‭add_cheese‬‭(self):‬
‭self.burger.cheese =‬‭True‬
‭return‬‭self‬

‭def‬‭add_sauce‬‭(self, sauce_type):‬
‭self.burger.sauces.append(sauce_type)‬
‭return‬‭self‬

‭def‬‭add_vegetable‬‭(self, veg_type):‬
‭self.burger.vegetables.append(veg_type)‬
‭return‬‭self‬

‭def‬‭build‬‭(self):‬
‭return‬‭self.burger‬

‭print(‬‭"\n--- Builder Pattern Example ---"‬‭)‬


‭# Build a complex burger step-by-step‬
‭veg_burger = (BurgerBuilder()‬
‭.add_buns(‬‭"whole wheat"‬‭)‬
‭.add_patty(‬‭"veggie"‬‭)‬
‭.add_sauce(‬‭"mayo"‬‭)‬
‭.add_vegetable(‬‭"lettuce"‬‭)‬
‭.add_vegetable(‬‭"tomato"‬‭)‬
.‭build())‬
‭ rint(veg_burger)‬
p
‭ Output: Burger with: whole wheat buns, veggie patty, no cheese, sauces: mayo, veg: lettuce,‬
#
‭tomato‬

‭cheese_burger = (BurgerBuilder()‬
‭.add_buns(‬‭"sesame"‬‭)‬
‭.add_patty(‬‭"beef"‬‭)‬
‭.add_cheese()‬
‭.add_sauce(‬‭"ketchup"‬‭)‬
‭.add_sauce(‬‭"mustard"‬‭)‬
‭.build())‬
‭print(cheese_burger)‬
‭# Output: Burger with: sesame buns, beef patty, cheese, sauces: ketchup, mustard, veg: none‬

‭16. Architectural Patterns‬


‭These are broader structural patterns for organizing code, often at the application level.‬
‭●‬ M
‭ odel-View-Controller (MVC):‬‭Divides an application into three interconnected‬
‭components to separate concerns and improve maintainability.‬
‭○‬ ‭Model:‬‭Manages the data and business logic. It notifies the View of any changes.‬
‭○‬ ‭View:‬‭Displays the data from the Model to the user. It observes the Model for‬
‭changes.‬
‭○‬ ‭Controller:‬‭Handles user input, interacts with the Model to update data, and‬
‭instructs the View to update its display.‬
‭Python‬
‭ A very simplified conceptual example of MVC in Python.‬
#
‭# In a real application, these would be separate classes/modules.‬

‭ 1. Model (Data & Logic)‬


#
‭class‬‭DataModel:‬
‭def‬‭__init__‬‭(self):‬
‭self._data =‬‭0‬
‭self._observers = []‬‭# List of views/controllers observing this model‬

‭def‬‭add_observer‬‭(self, observer):‬
‭self._observers.append(observer)‬

‭def‬‭set_data‬‭(self, value):‬
‭if‬‭self._data != value:‬
‭self._data = value‬
‭self._notify_observers()‬

‭def‬‭get_data‬‭(self):‬
‭return‬‭self._data‬

‭def‬‭_notify_observers‬‭(self):‬
‭for‬‭observer‬‭in‬‭self._observers:‬
‭observer.update()‬

‭ 2. View (Presentation)‬
#
‭class‬‭TextView:‬
‭def‬‭__init__‬‭(self, model):‬
s‭ elf._model = model‬
‭self._model.add_observer(self)‬‭# View observes the Model‬

‭def‬‭update‬‭(self):‬
‭# React to model changes and update display‬
‭print(‬‭f"View Updated: Data is now‬‭{self._model.get_data()}‬‭"‬‭)‬

‭def‬‭display‬‭(self):‬
‭print(‬‭f"Current View Display:‬‭{self._model.get_data()}‬‭"‭)‬ ‬

‭ 3. Controller (Input Handling & Orchestration)‬


#
‭class‬‭DataController:‬
‭def‬‭__init__‬‭(self, model):‬
‭self._model = model‬

‭def‬‭increment_data‬‭(self, amount=‬‭1‭)‬ :‬
‭ urrent_data = self._model.get_data()‬
c
‭self._model.set_data(current_data + amount)‬

‭def‬‭decrement_data‬‭(self, amount=‬‭1‬‭):‬
‭ urrent_data = self._model.get_data()‬
c
‭self._model.set_data(current_data - amount)‬

‭print(‬‭"\n--- MVC Pattern Example ---"‬‭)‬


‭# Setup‬
‭ odel = DataModel()‬
m
‭view = TextView(model)‬
‭controller = DataController(model)‬

‭# Initial display‬
‭view.display()‬‭# Output: Current View Display: 0‬

‭# User action via controller‬


‭controller.increment_data()‬
‭# Output: View Updated: Data is now 1‬

‭controller.increment_data(‬‭5‭)‬ ‬
‭# Output: View Updated: Data is now 6‬

‭controller.decrement_data(‬‭2‭)‬ ‬
‭# Output: View Updated: Data is now 4‬

‭view.display()‬‭# Output: Current View Display: 4‬

‭ his extended cheat sheet now thoroughly covers dunder methods, more design patterns,‬
T
‭and an introduction to architectural patterns, making it even more robust for Python‬
‭developers!‬

‭ ources‬
S
‭1.‬‭https://github.com/Mendkelokesh12/PW_-Assignments‬
‭2.‬‭https://www.scribd.com/document/673269950/Python-Programming-19-06-2023‬
‭3.‬‭https://codebricks.co.nz/python-oop-example-01‬
‭4.‬‭https://github.com/Akash193119/june‬
‭5.‬‭https://blog.csdn.net/ak_bingbing/article/details/134936284‬
‭6.‬‭https://github.com/0nur0duncu/python-files‬
‭7.‬‭https://github.com/sallehteh2003/Python‬
‭8.‬‭https://www.owlift.com/blog/submission/what-do-you-mean-by-operator-overloading-2/‬
‭9.‬‭https://www.datacamp.com/pt/blog/top-python-interview-questions-and-answers‬
‭10.‬‭https://blog.csdn.net/qq_45150540/article/details/134257875‬
‭11.‬‭https://github.com/hulinhui/Spiders‬
‭12.‬‭https://blog.csdn.net/likinguuu/article/details/131253973‬
‭13.‬‭https://github.com/bazera/ts-design-patterns‬
‭14.‬‭https://github.com/syurskyi/Python_Topics‬
‭15.‬
‭http://usawealthnewsdaily.com/stories/how-to-leverage-llms-for-effective-and-scalable-software-‬
‭development,522531?‬
‭16.‬‭https://github.com/code0monkey1/typescript-design-patterns‬
‭17.‬‭https://anakut.com/en/posts/rust/‬
‭18.‬‭https://blog.pixelfreestudio.com/how-to-implement-design-patterns-for-maintainable-code/‬

You might also like