0% found this document useful (0 votes)
6 views27 pages

Python Study Notes

This document is a comprehensive study guide for Python, covering topics from basic to intermediate levels, including variables, data types, control flow, functions, data structures, file handling, and object-oriented programming. Each section provides explanations, examples, and real-life analogies to facilitate understanding. The guide is designed to prepare learners for exams and practical applications in Python programming.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views27 pages

Python Study Notes

This document is a comprehensive study guide for Python, covering topics from basic to intermediate levels, including variables, data types, control flow, functions, data structures, file handling, and object-oriented programming. Each section provides explanations, examples, and real-life analogies to facilitate understanding. The guide is designed to prepare learners for exams and practical applications in Python programming.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

🐍

PYTHON
Complete Study Notes
Basic → Intermediate | Exam Ready

📋 What this covers:


1. Variables, Data Types & Operators
2. Control Flow (if/else, loops)
3. Functions & Scope
4. Lists, Tuples, Dicts, Sets
5. Strings & File Handling
6. OOP (Classes, Inheritance, Polymorphism)
7. Exception Handling
8. Modules & Libraries
9. Comprehensions & Lambdas
10. Decorators & Generators (Intermediate)
📘 Chapter 1: Python Basics
Python is a high-level, interpreted, dynamically typed language. Think of it like giving instructions in plain English
to a computer.

▶ 1.1 Variables & Data Types


A variable is like a labeled box that stores data.

# Variables - Real Life Analogy


name = "Riya" # str → like a name tag
age = 21 # int → whole number
gpa = 8.5 # float → decimal number
passed = True # bool → True or False
nothing = None # NoneType → empty/no value

Type Example Real World Example Key Note


int 42 Student roll number No decimal

float 3.14 Temperature 36.6°C Has decimal

str "Hello" Your name, a message Use "" or ''

bool True/False Light ON/OFF switch Capital T/F

NoneType None Empty seat in class Means nothing/null

💡 type() function tells you the type of any variable!


Example: type(42) → <class int> | type("Hi") → <class str>

▶ 1.2 Type Conversion


# Type Conversion
x = int("42") # "42" → 42 (str to int)
y = float(10) # 10 → 10.0 (int to float)
z = str(3.14) # 3.14 → "3.14" (float to str)
b = bool(0) # 0 → False | bool(1) → True

▶ 1.3 Operators
Category Operators Example
Arithmetic + - * / // % ** 10 // 3 = 3 | 2**3 = 8
Category Operators Example
Comparison == != > < >= <= 5 > 3 → True

Logical and or not True and False → False

Assignment = += -= *= /= x += 5 means x = x + 5

Identity is is not x is None → True/False

Membership in not in "a" in "apple" → True

# Operators in Action
# Real Life: Shopping Cart
price = 100
discount = 20
final = price - discount # 80
tax = final * 0.18 # 14.4
total = final + tax # 94.4

is_expensive = total > 500 # False


📘 Chapter 2: Control Flow

▶ 2.1 if / elif / else


Control flow = deciding what code runs based on conditions. Like traffic signals!

# if/elif/else - ATM Example


# Real Life: ATM Machine
balance = 5000
withdraw = int(input("Enter amount: "))

if withdraw > balance:


print("Insufficient funds!")
elif withdraw <= 0:
print("Invalid amount!")
elif withdraw % 100 != 0:
print("Enter in multiples of 100")
else:
balance -= withdraw
print(f"Withdrawal successful! Balance: {balance}")

⚠️ Indentation is MANDATORY in Python (4 spaces or 1 tab)


Python uses indentation instead of {} like Java/C
Wrong indentation = IndentationError (very common exam trap!)

▶ 2.2 Loops
◆ for Loop
# for Loop
# Real Life: Taking attendance in class
students = ["Ankit", "Priya", "Rahul", "Sneha"]

for student in students:


print(f"Present: {student}")

# range() - generates sequence of numbers


for i in range(1, 6): # 1, 2, 3, 4, 5
print(f"Question {i}")

# range(start, stop, step)


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

◆ while Loop
# while Loop
# Real Life: OTP verification (3 attempts)
correct_otp = "9876"
attempts = 3

while attempts > 0:


otp = input("Enter OTP: ")
if otp == correct_otp:
print("Login Successful!")
break
else:
attempts -= 1
print(f"Wrong! {attempts} attempts left")

if attempts == 0:
print("Account locked!")

◆ Loop Control: break, continue, pass


Keyword What it does Analogy
break Exits the loop immediately Emergency exit door

continue Skips current iteration, goes to next Skip a song in playlist

pass Does nothing (placeholder) Empty room - reserved for later

# Loop Control
# continue example: Skip even numbers
for i in range(1, 10):
if i % 2 == 0:
continue
print(i) # prints: 1 3 5 7 9
📘 Chapter 3: Functions
A function is a reusable block of code. Like a recipe - write once, use many times!

▶ 3.1 Defining and Calling Functions


# Functions
# Syntax
def function_name(parameters):
"""Docstring - describes what function does"""
# code block
return value

# Real Life: Pizza Order Calculator


def calculate_bill(pizzas, price_per_pizza=200, discount=0):
subtotal = pizzas * price_per_pizza
final = subtotal - (subtotal * discount / 100)
return final

bill = calculate_bill(3) # 600


bill2 = calculate_bill(3, 250) # 750
bill3 = calculate_bill(3, 250, 10) # 675

▶ 3.2 Types of Arguments


Type Syntax Example
Positional Values in order calc(3, 250)

Keyword Name=value calc(discount=10, pizzas=3)

Default param=default def f(x, y=10)

*args Variable positional def f(*nums): sum all

**kwargs Variable keyword def f(**info): key-value pairs

# *args and **kwargs


# *args - Real Life: Shopping cart with unlimited items
def cart_total(*prices):
return sum(prices)

print(cart_total(50, 80, 120, 200)) # 450

# **kwargs - Real Life: User profile


def create_profile(**details):
for key, value in [Link]():
print(f"{key}: {value}")

create_profile(name="Raj", age=20, city="Mumbai")

▶ 3.3 Scope (LEGB Rule)


🔭 L - Local: Inside current function
E - Enclosing: Inside outer function (for nested functions)
G - Global: Module/file level
B - Built-in: Python built-ins (print, len, etc.)
Python searches in this exact order!

# Scope Example
x = 10 # Global

def outer():
y = 20 # Enclosing
def inner():
z = 30 # Local
print(x, y, z) # Can access all!
inner()

# global keyword - to modify global variable inside function


count = 0
def increment():
global count
count += 1

▶ 3.4 Lambda Functions


Lambda = small anonymous (unnamed) function. One liner!
# Lambda
# Syntax: lambda arguments: expression

square = lambda x: x * x
print(square(5)) # 25

# Real Life: Sorting students by marks


students = [("Aman", 85), ("Bina", 92), ("Cary", 78)]
[Link](key=lambda s: s[1]) # Sort by marks
print(students) # [(Cary,78), (Aman,85), (Bina,92)]

# with map() - apply to each item


prices = [100, 200, 300]
discounted = list(map(lambda p: p * 0.9, prices))
# [90.0, 180.0, 270.0]
📘 Chapter 4: Data Structures

▶ 4.1 Lists
Ordered, mutable (changeable), allows duplicates. Like a shopping list!
# Lists
# Create
fruits = ["apple", "banana", "mango", "apple"]

# Access (0-indexed)
print(fruits[0]) # apple
print(fruits[-1]) # apple (last item)

# Slicing [start:stop:step]
print(fruits[1:3]) # ["banana", "mango"]
print(fruits[::-1]) # reverse the list

# Common Methods
[Link]("orange") # Add at end
[Link](1, "grapes") # Add at index 1
[Link]("banana") # Remove by value
[Link]() # Remove last item
[Link](0) # Remove at index 0
[Link]() # Sort A-Z
[Link]() # Reverse
len(fruits) # Count items
"apple" in fruits # Check membership

💡 Real Life: Marks list, playlist, cart items, student names


List is MUTABLE - you can change, add, remove items
Negative index: -1 is last, -2 is second last...

▶ 4.2 Tuples
Ordered, IMMUTABLE (cannot change), allows duplicates. Like a sealed envelope!
# Tuples
# Create (use parentheses)
coordinates = (28.6139, 77.2090) # Delhi GPS coords
person = ("Ananya", 22, "CS") # Name, age, dept

# Access same as list


print(coordinates[0]) # 28.6139

# Tuple packing / unpacking


name, age, dept = person # Unpacking!
print(name) # Ananya

# Single element tuple - needs trailing comma!


single = (42,) # This is a tuple
not_tuple = (42) # This is just int 42 in parens!
Feature List Tuple
Syntax [] ()

Mutable? Yes No (read-only)

Speed Slower Faster

Use when Data can change Data stays fixed

Example Cart items GPS coordinates, DB records

▶ 4.3 Dictionaries
Key-value pairs, mutable, ordered (Python 3.7+). Like a real dictionary or contact book!
# Dictionaries
# Create
student = {
"name": "Karan",
"age": 20,
"marks": [85, 90, 78]
}

# Access
print(student["name"]) # Karan
print([Link]("phone", "N/A")) # safe access - N/A if not found

# Modify
student["age"] = 21 # Update
student["city"] = "Delhi" # Add new key
del student["age"] # Delete key

# Loop through
for key, value in [Link]():
print(f"{key}: {value}")

# Useful methods
[Link]() # all keys
[Link]() # all values
[Link]() # key-value pairs
"name" in student # True

▶ 4.4 Sets
Unordered, no duplicates, mutable. Like a Venn diagram!
# Sets
# Create
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}

# Operations
A | B # Union: {1,2,3,4,5,6,7,8}
A & B # Intersection: {4,5}
A - B # Difference: {1,2,3}
A ^ B # Symmetric diff: {1,2,3,6,7,8}

# Real Life: Remove duplicates from attendance


attendance = ["Ram", "Sita", "Ram", "Gita", "Sita"]
unique = set(attendance)
print(unique) # {"Ram", "Sita", "Gita"}
📘 Chapter 5: Strings
Strings are sequences of characters. Immutable in Python.
# Strings
# String creation
name = "Python"
multi = """This is
multi-line string"""

# Indexing & Slicing


print(name[0]) # P
print(name[-1]) # n
print(name[1:4]) # yth
print(name[::-1]) # nohtyP (reverse)

# f-strings (best way to format!)


age = 20
print(f"I am {age} years old") # I am 20 years old
print(f"Next year: {age + 1}") # Next year: 21
print(f"Pi is {3.14159:.2f}") # Pi is 3.14

Method What it does Example


upper() ALL CAPS "hello".upper() → "HELLO"

lower() all small "HELLO".lower() → "hello"

strip() Remove whitespace " hi ".strip() → "hi"

split() Split into list "a,b,c".split(",") → [a,b,c]

join() Join list into str ",".join(["a","b"]) → "a,b"

replace() Replace part "cat".replace("c","b") → "bat"

find() Find index of substr "hello".find("ll") → 2

count() Count occurrences "banana".count("a") → 3

startswith() Starts with? "Python".startswith("Py") → True

isdigit() All digits? "123".isdigit() → True


📘 Chapter 6: File Handling
Reading and writing files. Always use with statement (auto-closes file)!
# File Handling
# Modes: r=read, w=write(overwrite), a=append, r+=read+write

# WRITE to a file
with open("[Link]", "w") as f:
[Link]("Python is awesome!\n")
[Link]("Learning is fun!\n")

# READ entire file


with open("[Link]", "r") as f:
content = [Link]()
print(content)

# READ line by line (memory efficient)


with open("[Link]", "r") as f:
for line in f:
print([Link]())

# APPEND to file
with open("[Link]", "a") as f:
[Link]("More content!\n")

# Real Life: Saving student marks to file


students = {"Arjun": 85, "Maya": 92}
with open("[Link]", "w") as f:
for name, marks in [Link]():
[Link](f"{name}: {marks}\n")

💡 Always use "with open(...)" - it automatically closes the file even if an error occurs!
readlines() → returns list of lines
readline() → reads one line at a time
📘 Chapter 7: Object-Oriented Programming (OOP)
OOP models real-world things as objects with properties (attributes) and behaviors (methods).

▶ 7.1 Classes and Objects


# Class & Object - Bank Account
# Real Life: BankAccount class
class BankAccount:
bank_name = "National Bank" # Class attribute (shared)

def __init__(self, owner, balance=0): # Constructor


[Link] = owner # Instance attribute
[Link] = balance

def deposit(self, amount): # Method


[Link] += amount
print(f"Deposited {amount}. Balance: {[Link]}")

def withdraw(self, amount):


if amount > [Link]:
print("Insufficient funds!")
else:
[Link] -= amount
print(f"Withdrawn {amount}. Balance: {[Link]}")

def __str__(self): # String representation


return f"Account[{[Link]}]: Rs.{[Link]}"

# Create objects (instances)


acc1 = BankAccount("Priya", 5000)
acc2 = BankAccount("Rohan")

[Link](1000) # Deposited 1000. Balance: 6000


[Link](2000) # Withdrawn 2000. Balance: 4000
print(acc1) # Account[Priya]: Rs.4000

▶ 7.2 The 4 Pillars of OOP


◆ 1. Encapsulation - Hide internal details
# Encapsulation
# Private: __ prefix (name mangling)
# Protected: _ prefix (convention)
class Student:
def __init__(self, name, marks):
[Link] = name
self.__marks = marks # Private!

def get_marks(self): # Getter


return self.__marks

def set_marks(self, m): # Setter (with validation)


if 0 <= m <= 100:
self.__marks = m

s = Student("Anuj", 85)
print(s.get_marks()) # 85
# s.__marks → AttributeError (protected!)

◆ 2. Inheritance - Child class gets parent class features


# Inheritance
# Real Life: Animal → Dog, Cat
class Animal:
def __init__(self, name):
[Link] = name

def eat(self):
print(f"{[Link]} is eating")

def speak(self):
print("Some sound...")

class Dog(Animal): # Dog inherits from Animal


def speak(self): # Overriding parent method
print(f"{[Link]} says: Woof!")

def fetch(self): # Dog-specific method


print(f"{[Link]} is fetching!")

class Cat(Animal):
def speak(self):
print(f"{[Link]} says: Meow!")

d = Dog("Bruno")
[Link]() # Bruno is eating (from Animal)
[Link]() # Bruno says: Woof! (overridden)
[Link]() # Bruno is fetching!

# super() - call parent class method


class GuideDog(Dog):
def __init__(self, name, owner):
super().__init__(name) # Call Dog/__init__
[Link] = owner

◆ 3. Polymorphism - Same method, different behavior


# Polymorphism
# Method Overriding (runtime polymorphism)
animals = [Dog("Rex"), Cat("Whiskers")]

for animal in animals:


[Link]() # Each speaks differently!
# Rex says: Woof!
# Whiskers says: Meow!

# Duck Typing - "If it walks like a duck..."


class Circle:
def area(self): return 3.14 * 5 * 5

class Rectangle:
def area(self): return 10 * 5

shapes = [Circle(), Rectangle()]


for s in shapes:
print([Link]()) # Works for any shape!

◆ 4. Abstraction - Show only necessary details


# Abstraction
from abc import ABC, abstractmethod

class Shape(ABC): # Abstract class


@abstractmethod
def area(self): # Abstract method - MUST be implemented
pass

def describe(self): # Concrete method


print(f"Area = {[Link]()}")
class Circle(Shape):
def __init__(self, r): self.r = r
def area(self): return 3.14 * self.r ** 2

# Shape() # Error! Cannot instantiate abstract class


c = Circle(5)
[Link]() # Area = 78.5
📘 Chapter 8: Exception Handling
Handle errors gracefully instead of crashing. Like a safety net!
# Exception Handling
# Basic try-except
try:
x = int(input("Enter number: ")) # May fail!
result = 100 / x
print(f"Result: {result}")
except ValueError:
print("Please enter a valid number!")
except ZeroDivisionError:
print("Cannot divide by zero!")
except Exception as e:
print(f"Unexpected error: {e}") # Catch all
else:
print("No errors! Everything ran fine.") # Runs if no exception
finally:
print("This ALWAYS runs (cleanup code!)") # Always executes

Exception When it occurs


ValueError int("abc") - wrong value type

ZeroDivisionError 10/0 - divide by zero

IndexError list[99] - index out of range

KeyError dict["missing"] - key not found

TypeError "a" + 1 - wrong type operation

FileNotFoundError open("[Link]") - file missing

AttributeError [Link] - attribute on None

NameError Using undefined variable

# Custom Exceptions
# Raise custom exceptions
class InsufficientFundsError(Exception):
def __init__(self, amount, balance):
[Link] = f"Need {amount}, but only {balance} available"
super().__init__([Link])

def withdraw(balance, amount):


if amount > balance:
raise InsufficientFundsError(amount, balance)
return balance - amount

try:
withdraw(1000, 5000)
except InsufficientFundsError as e:
print(e)
📘 Chapter 9: List Comprehensions
A concise way to create lists. Much faster and cleaner than for loops!
# List Comprehensions
# Syntax: [expression for item in iterable if condition]

# Without comprehension
squares = []
for x in range(1, 6):
[Link](x**2)

# WITH comprehension (same result, one line!)


squares = [x**2 for x in range(1, 6)]
# [1, 4, 9, 16, 25]

# With condition - only even squares


even_sq = [x**2 for x in range(1, 11) if x % 2 == 0]
# [4, 16, 36, 64, 100]

# Real Life: Filter passing students


marks = [45, 78, 32, 91, 55, 28, 66]
passed = [m for m in marks if m >= 50]
# [78, 91, 55, 66]

# Dict comprehension
students = ["Ali", "Ben", "Cara"]
roll = {name: i+1 for i, name in enumerate(students)}
# {"Ali": 1, "Ben": 2, "Cara": 3}

# Set comprehension
unique_lengths = {len(w) for w in ["cat","dog","elephant","fox"]}
# {3, 8} (no duplicates)
📘 Chapter 10: Modules & Libraries

▶ 10.1 Importing Modules


# Modules
import math # import whole module
from math import sqrt, pi # import specific items
import numpy as np # import with alias

# math module
print([Link](16)) # 4.0
print([Link]) # 3.14159...
print([Link](3.7)) # 3
print([Link](3.2)) # 4

# random module - Real Life: Lucky draw


import random
print([Link](1, 100)) # Random int 1-100
print([Link](["A","B","C"])) # Random item
items = [1, 2, 3, 4, 5]
[Link](items) # Shuffle in place

# datetime module
from datetime import datetime, date
now = [Link]()
print([Link]("%d/%m/%Y %H:%M")) # 25/12/2024 14:30
today = [Link]()

▶ 10.2 Creating Your Own Module


# Your Own Module
# File: [Link]
def add(a, b): return a + b
def multiply(a, b): return a * b
PI = 3.14159

# In another file:
import mymath
print([Link](3, 4)) # 7
print([Link]) # 3.14159
▶ 10.3 Important Built-in Functions
Function Purpose Example
len() Length/count len([1,2,3]) → 3

range() Number sequence range(1,6) → 1,2,3,4,5

enumerate() Index + value enumerate(["a","b"]) → (0,a),(1,b)

zip() Pair two iterables zip([1,2],[a,b]) → (1,a),(2,b)

map() Apply function to all map(str, [1,2,3]) → ["1","2","3"]

filter() Filter with condition filter(lambda x: x>2, [1,2,3,4])

sorted() Return sorted copy sorted([3,1,2]) → [1,2,3]

sum() Sum all items sum([1,2,3]) → 6

max()/min() Max/Min value max([3,1,4]) → 4

isinstance() Type check isinstance(5, int) → True


📘 Chapter 11: Intermediate Topics

▶ 11.1 Decorators
A decorator adds extra functionality to a function without modifying it. Like a wrapper!
# Decorators
# Real Life: Timing a function (like a stopwatch)
import time

def timer(func): # Decorator function


def wrapper(*args, **kwargs):
start = [Link]()
result = func(*args, **kwargs)
end = [Link]()
print(f"{func.__name__} took {end-start:.4f} sec")
return result
return wrapper

@timer # Apply decorator


def slow_task():
[Link](1)
return "Done!"

slow_task() # slow_task took 1.0012 sec

# Another real example: Login required


def login_required(func):
def wrapper(user, *args):
if not [Link]("logged_in"):
print("Please login first!")
return
return func(user, *args)
return wrapper

@login_required
def view_dashboard(user):
print(f"Welcome {user['name']}!")

▶ 11.2 Generators
Generators produce values one at a time using yield. Memory efficient for large data!
# Generators
# Regular function - loads ALL into memory
def get_numbers(n):
return [i for i in range(n)] # All in memory

# Generator function - produces one at a time


def gen_numbers(n):
for i in range(n):
yield i # Pause & give value

gen = gen_numbers(1000000) # No memory used yet!


print(next(gen)) # 0
print(next(gen)) # 1

# Real Life: Reading huge log file line by line


def read_large_file(path):
with open(path, "r") as f:
for line in f:
yield [Link]()

# Generator expression (like list comp with ())


squares_gen = (x**2 for x in range(10))

▶ 11.3 @property Decorator


# @property
class Temperature:
def __init__(self, celsius):
self._celsius = celsius

@property
def celsius(self): # Getter
return self._celsius

@[Link]
def celsius(self, value): # Setter with validation
if value < -273.15:
raise ValueError("Below absolute zero!")
self._celsius = value

@property
def fahrenheit(self): # Computed property
return self._celsius * 9/5 + 32

t = Temperature(100)
print([Link]) # 212.0
[Link] = 25 # Uses setter
# [Link] = -300 # ValueError!
📘 Chapter 12: Quick Exam Reference

▶ Dunder (Magic) Methods


Method When called Example use
__init__ Object creation Constructor

__str__ str(obj) / print(obj) Human-readable output

__repr__ repr(obj) Dev/debug output

__len__ len(obj) Custom length

__add__ obj1 + obj2 Operator overloading

__eq__ obj1 == obj2 Equality check

__lt__ obj1 < obj2 Less-than comparison

▶ Common Pitfalls - Exam Traps!


⚠️ 1. Mutable default argument: def f(lst=[]) → WRONG! Use def f(lst=None)
2. Integer division: 7/2 = 3.5 (float) | 7//2 = 3 (int)
3. List copy: b = a copies reference! Use b = [Link]() or b = a[:]
4. Indentation: Python uses whitespace - mix tabs/spaces = error
5. String is immutable: "hello"[0] = "H" → TypeError!
6. None comparison: use "x is None", not "x == None"
7. Global variable in function: needs "global x" keyword
8. range() excludes stop: range(1,5) = 1,2,3,4 (not 5)

▶ String Formatting Comparison


# String Formatting
name, age = "Dev", 21

# % formatting (old)
print("Name: %s, Age: %d" % (name, age))

# .format() (Python 3)
print("Name: {}, Age: {}".format(name, age))
print("Name: {0}, Age: {1}".format(name, age))

# f-strings (Python 3.6+ - BEST!)


print(f"Name: {name}, Age: {age}")
print(f"Pi = {3.14159:.2f}") # Pi = 3.14

▶ One-liners You Should Know


# Python One-liners
# Swap two variables
a, b = b, a

# Ternary operator
result = "pass" if marks >= 50 else "fail"

# Unpack a list
first, *rest = [1, 2, 3, 4, 5] # first=1, rest=[2,3,4,5]

# Multiple assignment
x = y = z = 0

# Check all / any


all([True, True, False]) # False
any([False, False, True]) # True

# Dictionary from two lists


keys = ["a", "b", "c"]
vals = [1, 2, 3]
d = dict(zip(keys, vals)) # {"a":1, "b":2, "c":3}

🎯 Best of luck for your exam! 🎯


You got this! Practice the code examples and you will ace it.

You might also like