PYTHON QUICK REFERENCE

VARIABLES & TYPES

x = 5  # int
y = 3.14  # float
name = "Python"  # str
is_valid = True  # bool
nums = [1, 2, 3]  # list
coord = (4, 5)  # tuple
unique = {1, 2, 3}  # set
person = {"name": "John", "age": 30}  # dict

COMMON OPERATIONS

# Arithmetic
result = 10 + 5 * 2  # 20

# String concatenation
full_name = "John" + " " + "Doe"

# List operations
nums.append(4)
nums.pop()

# Dictionary access
age = person["age"]

CONTROL FLOW

# If statement
if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
else:
    grade = "C"

# For loop
for i in range(5):
    print(i)

# While loop
while count < 10:
    count += 1

ESSENTIAL FUNCTIONS

len([1,2,3])  # 3
type("hello")  # 
int("42")  # 42
str(100)  # "100"
list(range(5))  # [0,1,2,3,4]
sorted([3,1,2])  # [1,2,3]
sum([1,2,3])  # 6

DAY 1: PYTHON FOUNDATIONS

VARIABLES & DATA TYPES

Variables store data values. Python is dynamically typed.

# Integer
age = 25
print(type(age))  # 

# Float
price = 19.99
print(type(price))  # 

# String
name = "Alice"
print(type(name))  # 

# Boolean
is_active = True
print(type(is_active))  # 

TIPS:

  • Variable names should be descriptive (use snake_case)
  • Python is case-sensitive: myVarmyvar
  • Use type() to check variable type

TYPE CASTING

Converting between data types.

# String to integer
num_str = "123"
num_int = int(num_str)  # 123

# Integer to string
num = 456
num_as_str = str(num)  # "456"

# Float to integer (truncates decimal)
float_num = 3.99
int_num = int(float_num)  # 3 (not rounded!)

# Integer to float
int_num = 7
float_num = float(int_num)  # 7.0

COMMON PITFALLS:

  • int("3.14") raises ValueError (use float first)
  • int("hello") raises ValueError
  • Cast before operations: int("5") + 10 works, "5" + 10 doesn't

INPUT & OUTPUT

Getting user input and displaying output.

# Basic print
print("Hello, World!")
print("Value is:", 42)

# Formatted output
name = "Bob"
age = 30
print(f"{name} is {age} years old")  # f-string (modern)
print("{} is {} years old".format(name, age))  # .format()
print("%s is %d years old" % (name, age))  # % formatting

# User input
user_name = input("Enter your name: ")
print(f"Hello, {user_name}!")

# Input always returns string
age_input = input("Enter your age: ")
age = int(age_input)  # Convert to int for calculations

DAY 2: OPERATORS & CONTROL FLOW

OPERATORS

TYPE OPERATOR DESCRIPTION EXAMPLE
Arithmetic + - * / // % ** Addition, subtraction, multiplication, division, floor division, modulus, exponent 10 // 3 = 3
Comparison == != > < >= <= Equal, not equal, greater than, less than, etc. 5 != 3 → True
Logical and or not Logical AND, OR, NOT True and False → False
Assignment = += -= *= /= Assign and update values x += 5 (x = x + 5)
Membership in not in Check if value exists in sequence "a" in "apple" → True
Identity is is not Check if objects are the same a is b

CONDITIONAL STATEMENTS

# Basic if-else
age = 18
if age >= 18:
    print("You can vote!")
else:
    print("Too young to vote")

# if-elif-else chain
score = 85
if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"  # This executes for score=85
elif score >= 70:
    grade = "C"
else:
    grade = "F"

print(f"Grade: {grade}")

# Nested conditions
temperature = 25
is_sunny = True

if temperature > 20:
    if is_sunny:
        print("Perfect beach weather!")
    else:
        print("Warm but cloudy")
else:
    print("Too cold for beach")

# One-liner (ternary)
status = "adult" if age >= 18 else "minor"

TRUTHY & FALSY VALUES:

  • Falsy: False, 0, 0.0, "", [], {}, None
  • Truthy: Everything else (including negative numbers!)
  • Useful for checking if list is empty: if items: (not if len(items) > 0:)

DAY 3: LOOPS & FLOW CONTROL

FOR LOOPS

# Basic for loop
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)

# With range()
for i in range(5):  # 0 to 4
    print(i)

for i in range(2, 8):  # 2 to 7
    print(i)

for i in range(0, 10, 2):  # 0, 2, 4, 6, 8
    print(i)

# Looping with index
for i, fruit in enumerate(fruits):
    print(f"{i}: {fruit}")

# Nested loops
for i in range(3):
    for j in range(2):
        print(f"({i}, {j})")

WHILE LOOPS

# Basic while loop
count = 0
while count < 5:
    print(count)
    count += 1  # Don't forget to increment!

# While with condition
password = ""
while password != "secret":
    password = input("Enter password: ")
print("Access granted!")

# Infinite loop (with break)
while True:
    user_input = input("Enter 'quit' to exit: ")
    if user_input == "quit":
        break
    print(f"You entered: {user_input}")

LOOP CONTROL STATEMENTS

# break - exit loop immediately
for i in range(10):
    if i == 5:
        break
    print(i)  # Prints 0,1,2,3,4

# continue - skip to next iteration
for i in range(5):
    if i == 2:
        continue
    print(i)  # Prints 0,1,3,4

# pass - placeholder (does nothing)
for i in range(5):
    if i == 3:
        pass  # TODO: Add implementation later
    print(i)

# else with loops (executes if loop completes without break)
for i in range(3):
    print(i)
else:
    print("Loop completed!")  # This runs

for i in range(3):
    if i == 1:
        break
    print(i)
else:
    print("Loop completed!")  # This doesn't run

PATTERN PRINTING EXAMPLE:

# Print right triangle
for i in range(1, 6):
    print("*" * i)

# Output:
# *
# **
# ***
# ****
# *****

# Print pyramid
n = 5
for i in range(1, n+1):
    spaces = " " * (n - i)
    stars = "*" * (2*i - 1)
    print(spaces + stars)

DAY 4: STRINGS & STRING HANDLING

STRING BASICS

# Creation
s1 = "Hello"
s2 = 'World'
s3 = """Multi-line
string"""
s4 = str(123)  # "123"

# Indexing
text = "Python"
first_char = text[0]  # "P"
last_char = text[-1]  # "n"
# text[0] = "J"  # ERROR: Strings are immutable!

# Slicing [start:end:step]
text = "Python Programming"
print(text[0:6])  # "Python"
print(text[7:])   # "Programming"
print(text[:6])   # "Python"
print(text[::2])  # "Pto rgamn"
print(text[::-1]) # Reverse: "gnimmargorP nohtyP"

STRING METHODS

METHOD DESCRIPTION EXAMPLE
.upper() .lower() Case conversion "Hello".upper() → "HELLO"
.strip() .lstrip() .rstrip() Remove whitespace " hi ".strip() → "hi"
.split() .join() Split/join strings "a,b,c".split(",") → ["a","b","c"]
.replace() Replace substring "hello".replace("l","x") → "hexxo"
.find() .index() Find substring "hello".find("ll") → 2
.startswith() .endswith() Check prefix/suffix "file.txt".endswith(".txt") → True
.isalpha() .isdigit() .isalnum() Character tests "abc".isalpha() → True

STRING PROBLEMS

# Palindrome check
def is_palindrome(s):
    s = s.lower().replace(" ", "")
    return s == s[::-1]

print(is_palindrome("racecar"))  # True
print(is_palindrome("hello"))    # False

# Anagram check
def is_anagram(s1, s2):
    return sorted(s1.lower()) == sorted(s2.lower())

print(is_anagram("listen", "silent"))  # True
print(is_anagram("hello", "world"))    # False

DAY 5: LISTS, TUPLES & SETS

LISTS

# Creation
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, True]
empty = []
from_range = list(range(5))  # [0,1,2,3,4]

# Access & modification
numbers[0] = 10  # Lists are mutable
print(numbers[-1])  # Last element: 5
print(numbers[1:4])  # Slice: [2,3,4]

# Common methods
numbers.append(6)  # Add to end
numbers.insert(0, 0)  # Insert at index 0
numbers.extend([7, 8])  # Add multiple items
removed = numbers.pop()  # Remove last item (8)
numbers.remove(3)  # Remove first occurrence of 3
if 4 in numbers:  # Check existence
    print("Found 4")
    
# List comprehension (powerful!)
squares = [x**2 for x in range(10)]
even_squares = [x**2 for x in range(10) if x % 2 == 0]

TUPLES

# Creation (immutable)
point = (10, 20)
single = (5,)  # Comma required for single element
coordinates = tuple([1, 2, 3])

# Access (same as lists)
x = point[0]
y = point[1]

# Unpacking
x, y = point  # x=10, y=20

# Why use tuples?
# 1. Faster than lists
# 2. Safe (can't be modified accidentally)
# 3. Can be used as dictionary keys
# 4. Return multiple values from functions

# Returning multiple values
def get_stats(numbers):
    return min(numbers), max(numbers), sum(numbers)/len(numbers)

min_val, max_val, avg = get_stats([1,2,3,4,5])

SETS

# Creation (unique, unordered)
unique_nums = {1, 2, 3, 3, 2}  # {1, 2, 3}
empty_set = set()  # {} creates empty dict!

# Set operations
A = {1, 2, 3, 4}
B = {3, 4, 5, 6}

print(A | B)  # Union: {1,2,3,4,5,6}
print(A & B)  # Intersection: {3,4}
print(A - B)  # Difference: {1,2}
print(A ^ B)  # Symmetric difference: {1,2,5,6}

# Methods
A.add(5)
A.remove(2)  # Error if not exists
A.discard(2)  # No error if not exists
A.pop()  # Remove random element

# Set comprehension
unique_chars = {char for char in "hello world" if char != " "}

DAY 6: DICTIONARIES & DATA STRUCTURES

DICTIONARY BASICS

# Creation
student = {"name": "Alice", "age": 20, "grade": "A"}
empty_dict = {}
another = dict(name="Bob", age=21)

# Access
print(student["name"])  # "Alice"
print(student.get("age"))  # 20
print(student.get("height", "N/A"))  # "N/A" (default if key missing)

# Modification
student["age"] = 21  # Update
student["height"] = 165  # Add new key
del student["grade"]  # Remove key

# Check key existence
if "name" in student:
    print("Name exists")

# Iteration
for key in student:  # Or student.keys()
    print(key, student[key])

for key, value in student.items():
    print(f"{key}: {value}")

DICTIONARY METHODS

METHOD DESCRIPTION EXAMPLE
.keys() Get all keys list(student.keys())
.values() Get all values list(student.values())
.items() Get (key, value) pairs list(student.items())
.get(key, default) Safe access with default student.get("x", 0)
.pop(key, default) Remove and return value age = student.pop("age")
.update(other_dict) Merge dictionaries student.update({"city": "NYC"})
.setdefault(key, default) Get value or set default student.setdefault("score", 100)

NESTED DICTIONARIES & JSON

# Nested dictionary
company = {
    "name": "TechCorp",
    "employees": {
        "101": {"name": "Alice", "position": "Developer"},
        "102": {"name": "Bob", "position": "Designer"}
    },
    "departments": ["IT", "HR", "Finance"]
}

# Access nested values
print(company["employees"]["101"]["name"])  # "Alice"

# JSON-like structure (common in web APIs)
import json

# Python dict to JSON string
person_dict = {"name": "John", "age": 30}
json_string = json.dumps(person_dict)  # '{"name": "John", "age": 30}'

# JSON string to Python dict
parsed_dict = json.loads(json_string)

# Dictionary comprehension
squares = {x: x**2 for x in range(5)}  # {0:0, 1:1, 2:4, 3:9, 4:16}

DAY 7: FUNCTIONS & FUNCTIONAL PROGRAMMING

FUNCTION BASICS

# Defining functions
def greet(name):
    """Return a greeting message."""  # Docstring
    return f"Hello, {name}!"

# Calling functions
message = greet("Alice")
print(message)  # "Hello, Alice!"

# Functions without return
def print_sum(a, b):
    print(f"Sum: {a + b}")  # Returns None

# Multiple return values
def min_max(numbers):
    return min(numbers), max(numbers)

low, high = min_max([1, 5, 2, 8, 3])

FUNCTION ARGUMENTS

# Positional arguments
def power(base, exponent):
    return base ** exponent

result = power(2, 3)  # 8

# Keyword arguments
result = power(exponent=3, base=2)  # Order doesn't matter

# Default parameters
def greet(name, greeting="Hello"):
    return f"{greeting}, {name}!"

print(greet("Alice"))  # "Hello, Alice!"
print(greet("Bob", "Hi"))  # "Hi, Bob!"

# Variable-length arguments
def sum_all(*args):  # args is a tuple
    return sum(args)

print(sum_all(1, 2, 3, 4))  # 10

def print_info(**kwargs):  # kwargs is a dictionary
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Alice", age=25, city="NYC")

LAMBDA & FUNCTIONAL TOOLS

# Lambda functions (anonymous)
square = lambda x: x ** 2
print(square(5))  # 25

# Often used with map, filter, reduce
numbers = [1, 2, 3, 4, 5]

# map: apply function to all items
squares = list(map(lambda x: x**2, numbers))  # [1, 4, 9, 16, 25]

# filter: keep items where function returns True
evens = list(filter(lambda x: x % 2 == 0, numbers))  # [2, 4]

# reduce: apply function cumulatively
from functools import reduce
product = reduce(lambda x, y: x * y, numbers)  # 120

# List comprehension alternative
squares = [x**2 for x in numbers]  # Often more readable
evens = [x for x in numbers if x % 2 == 0]

RECURSION

# Factorial example
def factorial(n):
    if n <= 1:  # Base case
        return 1
    return n * factorial(n - 1)  # Recursive case

print(factorial(5))  # 120

# Fibonacci sequence
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(6))  # 8

# Recursion tips:
# 1. Always have a base case
# 2. Ensure progress toward base case
# 3. Python has recursion limit (~1000)

DAY 8: MODULES, PACKAGES & FILE HANDLING

MODULES

# Importing modules
import math
print(math.sqrt(16))  # 4.0

# Import with alias
import datetime as dt
today = dt.date.today()

# Import specific functions
from random import randint, choice
number = randint(1, 10)
item = choice(["apple", "banana", "cherry"])

# Import everything (not recommended)
from os import *  # Pollutes namespace

# Create your own module
# Save as mymodule.py:
"""
def greet(name):
    return f"Hello, {name}!"

PI = 3.14159
"""

# Then import it:
# import mymodule
# print(mymodule.greet("Alice"))

USEFUL BUILT-IN MODULES

MODULE PURPOSE COMMON FUNCTIONS
math Mathematical operations sqrt(), ceil(), floor(), pi
random Random number generation randint(), choice(), shuffle()
datetime Date and time operations date.today(), datetime.now()
os Operating system interface listdir(), getcwd(), path.join()
sys System parameters argv, exit(), version
json JSON encoding/decoding dumps(), loads()

FILE HANDLING

# Reading files
with open("data.txt", "r") as file:  # 'r' = read mode
    content = file.read()  # Read entire file
    # OR: lines = file.readlines()  # List of lines

# Writing files
with open("output.txt", "w") as file:  # 'w' = write (overwrites)
    file.write("Hello, World!\n")
    file.write("Second line\n")

# Appending to files
with open("log.txt", "a") as file:  # 'a' = append
    file.write("New log entry\n")

# Reading line by line (memory efficient)
with open("large_file.txt", "r") as file:
    for line in file:
        print(line.strip())  # Process each line

# File modes:
# 'r' - read (default)
# 'w' - write (creates or truncates)
# 'a' - append (creates or appends)
# 'x' - exclusive creation (fails if exists)
# 'b' - binary mode ('rb', 'wb')
# '+' - read and write ('r+', 'w+')

DAY 9: EXCEPTION HANDLING & DEBUGGING

EXCEPTION HANDLING BASICS

# Basic try-except
try:
    result = 10 / 0
except ZeroDivisionError:
    print("Cannot divide by zero!")

# Multiple exceptions
try:
    num = int(input("Enter a number: "))
    result = 10 / num
    print(f"Result: {result}")
except ValueError:
    print("Invalid input! Please enter a number.")
except ZeroDivisionError:
    print("Cannot divide by zero!")
except Exception as e:  # Catch any other exception
    print(f"Unexpected error: {e}")

# else and finally
try:
    file = open("data.txt", "r")
    content = file.read()
except FileNotFoundError:
    print("File not found!")
else:
    print("File read successfully!")
    print(content)
finally:
    print("This always executes")
    # Good for cleanup (closing files, connections)

COMMON EXCEPTIONS

EXCEPTION CAUSE EXAMPLE
ValueError Invalid value/conversion int("abc")
TypeError Wrong type operation "5" + 3
IndexError Invalid sequence index list[10] (list has 3 items)
KeyError Missing dictionary key dict["missing_key"]
FileNotFoundError File doesn't exist open("nonexistent.txt")
ZeroDivisionError Division by zero 10 / 0
AttributeError Attribute doesn't exist "hello".non_existent()

RAISING EXCEPTIONS

# Raising exceptions
def calculate_age(birth_year):
    if birth_year < 1900 or birth_year > 2023:
        raise ValueError("Invalid birth year")
    return 2023 - birth_year

try:
    age = calculate_age(1800)
except ValueError as e:
    print(f"Error: {e}")

# Custom exceptions
class InvalidEmailError(Exception):
    """Exception raised for invalid email addresses."""
    def __init__(self, email, message="Invalid email address"):
        self.email = email
        self.message = message
        super().__init__(self.message)

def validate_email(email):
    if "@" not in email:
        raise InvalidEmailError(email)
    return True

# Assertions (for debugging)
def calculate_average(numbers):
    assert len(numbers) > 0, "List cannot be empty"
    return sum(numbers) / len(numbers)

DAY 10: OBJECT-ORIENTED PROGRAMMING (OOP)

CLASSES & OBJECTS

# Basic class
class Dog:
    # Class attribute (shared by all instances)
    species = "Canis familiaris"
    
    # Constructor (__init__ method)
    def __init__(self, name, age):
        # Instance attributes
        self.name = name
        self.age = age
    
    # Instance method
    def bark(self):
        return f"{self.name} says woof!"
    
    def get_info(self):
        return f"{self.name} is {self.age} years old"

# Creating objects
dog1 = Dog("Buddy", 3)
dog2 = Dog("Max", 5)

print(dog1.bark())  # "Buddy says woof!"
print(dog2.get_info())  # "Max is 5 years old"
print(Dog.species)  # "Canis familiaris" (class attribute)

INHERITANCE

# Base class
class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        raise NotImplementedError("Subclass must implement this method")

# Child class
class Cat(Animal):
    def __init__(self, name, color):
        super().__init__(name)  # Call parent constructor
        self.color = color
    
    # Override parent method
    def speak(self):
        return f"{self.name} says meow!"
    
    def get_info(self):
        return f"{self.name} is a {self.color} cat"

# Using inheritance
cat = Cat("Whiskers", "orange")
print(cat.speak())  # "Whiskers says meow!"
print(cat.get_info())  # "Whiskers is an orange cat"

# Multiple inheritance
class Pet:
    def __init__(self, owner):
        self.owner = owner

class DogPet(Dog, Pet):
    def __init__(self, name, age, owner):
        Dog.__init__(self, name, age)
        Pet.__init__(self, owner)

ENCAPSULATION & SPECIAL METHODS

# Encapsulation with private attributes
class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.__balance = balance  # Private attribute
    
    # Getter method
    def get_balance(self):
        return self.__balance
    
    # Setter method (with validation)
    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount
            return True
        return False
    
    def withdraw(self, amount):
        if 0 < amount <= self.__balance:
            self.__balance -= amount
            return True
        return False

# Special methods (dunder methods)
class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __str__(self):  # String representation
        return f"Vector({self.x}, {self.y})"
    
    def __repr__(self):  # Official representation
        return f"Vector({self.x}, {self.y})"
    
    def __add__(self, other):  # + operator
        return Vector(self.x + other.x, self.y + other.y)
    
    def __len__(self):  # len() function
        return 2
    
    def __eq__(self, other):  # == operator
        return self.x == other.x and self.y == other.y

v1 = Vector(2, 3)
v2 = Vector(1, 1)
print(v1 + v2)  # Vector(3, 4)
print(v1 == v2)  # False

POLYMORPHISM & ABSTRACTION

# Polymorphism - same interface, different implementation
class Shape:
    def area(self):
        pass

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
    
    def area(self):
        return 3.14 * self.radius ** 2

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def area(self):
        return self.width * self.height

# Different objects, same method
shapes = [Circle(5), Rectangle(4, 6)]
for shape in shapes:
    print(f"Area: {shape.area()}")  # Polymorphic call

# Abstraction - hide complex implementation
from abc import ABC, abstractmethod

class Database(ABC):
    @abstractmethod
    def connect(self):
        pass
    
    @abstractmethod
    def query(self, sql):
        pass

class MySQLDatabase(Database):
    def connect(self):
        print("Connecting to MySQL...")
    
    def query(self, sql):
        print(f"Executing MySQL query: {sql}")

# Can't instantiate abstract class
# db = Database()  # Error!
db = MySQLDatabase()  # OK

PYTHON BEST PRACTICES

CODE STYLE (PEP 8)

  • Use 4 spaces per indentation (no tabs)
  • Limit lines to 79 characters
  • Use descriptive variable names (snake_case)
  • Class names should be CamelCase
  • Constants should be UPPER_CASE
  • Use spaces around operators and after commas

ERROR HANDLING

  • Be specific with exception types
  • Use try-except only where needed
  • Always close resources (use with statement)
  • Log errors for debugging
  • Don't use bare except: (catch-all)

PERFORMANCE TIPS

  • Use list comprehensions for simple loops
  • Use join() for string concatenation in loops
  • Avoid global variables
  • Use generators for large datasets
  • Profile before optimizing

DEBUGGING TIPS

  • Use print() for quick debugging
  • Learn to use Python debugger (pdb)
  • Read error messages carefully
  • Add type hints for clarity
  • Write unit tests

MEMORY AIDS & MNEMONICS

CONCEPT MEMORY AID EXPLANATION
List vs Tuple "Mutable List, Immutable Tuple" Lists can change, tuples cannot
Dictionary Keys "Keys must be hashable" Strings, numbers, tuples (immutable) work as keys
String Methods "isX() tests, X() transforms" isalpha() tests, upper() transforms
Slicing "[start:stop:step]" Start included, stop excluded, step direction
Truthy/Falsy "Empty is Falsy" 0, "", [], {}, None are all falsy
CODE COPIED