Python Control Structures, Functions, OOP & File Handling PART A – CONTROL STRUCTURES Decision Making Introduction Decision making allows programs to choose different paths based on conditions (True/False). Python uses if , if-else , elif , and nested if for conditional branching. 1. The if Statement Executes a block of code only if the condition is true . if condition: statement(s) Example: num = 10 if num % 2 == 0: print("Even number") 2. The if-else Statement Provides two alternative paths of execution. If the condition is true, the if block runs; otherwise, the else block runs. if condition: statement(s) else: statement(s) Example: age = 17 if age >= 18: print("Eligible to vote") else: print("Not eligible") 3. The elif Statement (If-Elif-Else Ladder) Checks multiple conditions sequentially. Stands for "else if". Python tests conditions in order; the first true condition's block executes, and the ladder stops. if condition1: statements elif condition2: statements elif condition3: statements else: statements Example: marks = 72 if marks >= 90: print("A grade") elif marks >= 75: print("B grade") elif marks >= 60: print("C grade") else: print("D grade") 4. Nested if Statements An if-else statement placed inside another if or else block. Allows complex decision-making. if condition1: if condition2: statements else: statements else: statements Example: num = 25 if num > 0: if num % 5 == 0: print("Positive and divisible by 5") else: print("Positive but not divisible by 5") else: print("Number is negative") Looping Introduction Allows a block of code to be executed repeatedly. Python provides for and while loops. Supports loop control statements: break , continue , and pass . 1. The for Loop Iterates over a sequence (list, tuple, string, set, dictionary), accessing each element. for variable in sequence: statements Example: for x in [10, 20, 30]: print(x) Uses range() for counting loops: for i in range(1, 5): print(i) 2. The while Loop Repeatedly executes a block of code as long as a condition remains true. Useful when iterations are not known beforehand. while condition: statements Example: i = 1 while i Avoid infinite loops by updating the condition inside the loop. Loop Control Statements: break, continue, and pass break : Immediately terminates the loop. for x in range(10): if x == 5: break print(x) continue : Skips the current iteration and moves to the next. for x in range(5): if x == 2: continue print(x) pass : Does nothing; acts as a placeholder where a statement is syntactically required. for x in range(3): pass # no operation Nested Loops A loop inside another loop. The inner loop runs completely for every iteration of the outer loop. Useful for multi-dimensional data. for i in range(3): for j in range(2): print(i, j) Exception Handling Manages runtime errors and prevents crashes. Uses try-except mechanism. Improves reliability, avoids abrupt termination, aids debugging. try, except, else, finally blocks try block: Code that may raise an exception. except block: Catches the error; executes only when an exception occurs. else block: Runs only if no exception occurs in the try block. finally block: Always executes, regardless of whether an exception occurred (e.g., for cleanup). Example: try: x = 10 / 0 except ZeroDivisionError: print("Cannot divide by zero") else: print("No errors occurred") finally: print("Execution complete") Conditional Branching Allows a program to make decisions and execute different code blocks based on a True/False condition. Uses if , if-else , elif , and nested if statements. Example: x = 25 if x > 0: print("Positive") elif x == 0: print("Zero") else: print("Negative") PART B – FUNCTIONS Defining Functions A block of reusable code to perform a specific task. Improves modularity, reduces repetition. Uses the def keyword. def function_name(parameters): "optional docstring" statements Example: def greet(name): print("Hello", name) Return Statement Used inside a function to send a value back to the caller and immediately terminates function execution. Can return single, multiple (as tuples), or no values (returns None ). return expression Example: def add(a, b): return a + b result = add(10, 20) print(result) return without an expression exits the function and sends None . Calling Functions To execute a function's code, call it by its name followed by parentheses. Arguments can be passed inside the parentheses. function_name(arguments) Example: def greet(name): print("Hello", name) greet("Rahul") # Calling the function Function calls can store returned values into variables. Example with return: def add(a, b): return a + b result = add(5, 10) # Function call print(result) Pass by Reference vs Pass-by-Value (Pass by Object Reference) Python uses pass by object reference (pass-by-assignment). Functions receive a reference to the object. Mutable Objects (e.g., lists, dictionaries): Changes inside the function reflect outside because both caller and function refer to the same memory location. Example: def changeme(mylist): mylist.append(100) lst = [10, 20, 30] changeme(lst) print(lst) # [10, 20, 30, 100] Immutable Objects (e.g., integers, strings, tuples): Function cannot modify the original object. Reassignment inside creates a new local object. Example: def changeme(x): x = 50 # creates a new reference a = 10 changeme(a) print(a) # 10 (unchanged) Recursion A programming technique where a function calls itself to solve a problem. Splits large problems into smaller subproblems. Requires a base case (stopping condition) and a recursive case (function calls itself). Example: Factorial def factorial(n): if n == 1: # base case return 1 else: return n * factorial(n - 1) # recursive case Lambda Functions Small, anonymous (unnamed) functions defined with the lambda keyword. Can have any number of arguments but only one expression. Used for simple, short-period functions (e.g., with map() , filter() , sorted() ). lambda arguments : expression Examples: x = lambda a : a + 10 print(x(5)) # 15 mul = lambda a, b : a * b print(mul(3, 4)) # 12 Modules A Python file ( .py ) containing Python code (functions, variables, classes). Allows code organization and reuse. To create: write code in a .py file. To use: import or from...import . Example: Creating a Module ( calc.py ) def sum(a, b): return a + b Using the module: import calc print(calc.sum(5, 10)) Packages A directory structure organizing related modules. Helps group modules for management, reuse, and easy importing. A folder is recognized as a package if it contains a special file named __init__.py . Example Folder Structure: MyApp/ ├── mypackage/ │ ├── __init__.py │ ├── greet.py │ └── functions.py Importing modules from a package: from mypackage import functions functions.sum(10, 20) The __init__.py File A special Python file indicating to the interpreter that a folder should be treated as a package. Can be empty or contain initialization code that runs when the package is imported. Marks a folder as a Python package. Controls what is accessible when the package is imported. Example ( __init__.py ): from .functions import average, power from .greet import SayHello Now these can be imported directly: from mypackage import power, SayHello Custom Functions User-defined functions created using the def keyword to perform a specific task. Improve code reusability, structure, and readability. Can accept parameters, contain multiple statements, and return values. def function_name(parameters): "optional docstring" statements return value Example: def add(a, b): return a + b result = add(5, 10) print(result) PART C – LIBRARY MODULES random Module Generates random numbers and performs random operations. Used in simulations, games, testing. Important Functions: random() – returns a random float $0 \le x randint(a, b) – returns a random integer $a \le x \le b$. uniform(a, b) – random float between $a$ and $b$. choice(seq) – selects a random item from a sequence. shuffle(list) – shuffles elements of a list randomly. Example: import random print(random.randint(1, 10)) math Module Provides mathematical functions (trigonometric, logarithms, constants, rounding, power). Used in scientific/engineering applications. Important Functions: sqrt(x) – square root. pow(a, b) – $a^b$. log(x) – natural logarithm. sin(x) , cos(x) , tan(x) . ceil(x) , floor(x) . Constants: pi , e . Example: import math print(math.sqrt(16)) # 4.0 time Module Works with time values, delays, timestamps, and performance measurements. Used in animations, scheduling. Important Functions: time() – current time in seconds since epoch. sleep(seconds) – pauses execution. ctime() – converts time to readable string. localtime() – returns structured time. Example: import time print(time.ctime()) os Module Interacts with the operating system. Tasks include file/directory creation, deletion, renaming, navigation, environment variables. Important Functions: getcwd() – returns current working directory. listdir() – lists files in a directory. mkdir() – creates a directory. remove() – deletes a file. rename(old, new) – renames a file. Example: import os print(os.getcwd()) sys Module Provides access to system-specific parameters and functions. Handles command-line arguments, exits programs, interacts with Python runtime. Important Functions: argv – command-line arguments. exit() – terminates the program. version – shows Python version. path – lists module search paths. Example: import sys print(sys.version) shutil Module Supports high-level file operations (copying, moving, deleting files/directories). Used in file management scripts. Important Functions: copy(src, dst) – copies a file. move(src, dst) – moves or renames a file. rmtree(path) – deletes a folder recursively. Example: import shutil shutil.copy("a.txt", "backup.txt") glob Module Searches for files matching a specific pattern. Supports wildcard characters ( * , ? , [] ). Useful for batch processing. Important Function: glob(pattern) – returns a list of filenames matching the pattern. Example: import glob print(glob.glob("*.txt")) re Module (Regular Expressions) Used for pattern matching, searching, and text manipulation using regular expressions. Helps validate input, extract patterns, replace text. Important Functions: search() – searches for a pattern. match() – checks for a match at the start. findall() – returns all matches. sub() – replaces text. Example: import re print(re.findall("\d+", "Age 20, Roll 45")) statistics Module Provides functions for mathematical statistics of numeric data. Used in data analysis, research, and computation of statistical results. Important Functions: mean() – average. median() – middle value. mode() – most common value. stdev() – standard deviation. Example: import statistics print(statistics.mean([10, 20, 30])) PART D – OOP Introduction to OOP Object-Oriented Programming (OOP) is a programming approach based on objects, combining data and behavior. Improves reusability, modularity, and clarity. Major principles: class, object, inheritance, polymorphism, encapsulation, abstraction . 1. Class A user-defined blueprint for creating objects. Groups related data (attributes) and functions (methods). Defined using the class keyword. Does not occupy memory until an object is created. class ClassName: statements Example: class Car: def __init__(self, model, year): # Constructor self.model = model self.year = year 2. Object An instance of a class. Represents a real-world entity, contains data (attributes) and behavior (methods). Created by calling the class as a function. Python allocates memory for attributes when an object is created. Example: c1 = Car("Toyota", 2016) print(c1.model, c1.year) 3. Methods & 4. Attributes Attributes: Variables inside a class that store data related to an object. Represent state/properties. Typically defined in __init__ using self . Methods: Functions defined inside a class that operate on attributes and define object behavior. Always take self as the first parameter. Example: class Car: def __init__(self, model, year): # attributes self.model = model self.year = year def display(self): # method print(self.model, self.year) c1 = Car("Toyota", 2016) c1.display() 5. Inheritance Allows a new class (child) to acquire properties and methods of an existing class (parent). Promotes code reuse, establishes class relationships. Supports single, multilevel, multiple inheritance. Child class can add features or override parent methods. Example: class Animal: def sound(self): print("Makes a sound") class Dog(Animal): # inheritance def sound(self): print("Barks") # method overriding 6. Polymorphism Means "many forms". Allows the same method name to behave differently depending on the object calling it. Method overriding (child class provides its own implementation of a parent method) is a common form. Example: class Bird: def fly(self): print("Bird flies") class Penguin(Bird): def fly(self): print("Penguins cannot fly") Here, the same fly() method behaves differently for different objects. 7. Encapsulation Bundling data (attributes) and methods inside a class, while restricting direct access to some components. Protects internal state, allows controlled access via methods. Python uses naming conventions ( _protected , __private ). Example: class Account: def __init__(self, balance): self.__balance = balance # private attribute def show(self): print(self.__balance) 8. Abstraction Hides unnecessary details, shows only essential features. Focuses on "what" an object does, not "how". Implemented using classes, methods, and sometimes the abc (Abstract Base Class) module. Example: class Vehicle: def start(self): pass # abstract behavior 9. Built-in Class Attributes Provide information about the class, its objects, and inheritance. Useful for debugging and introspection. Common Built-in Attributes: __dict__ : Dictionary containing the class or object's namespace (attributes). __doc__ : Documentation string of the class. __name__ : Name of the class. __module__ : Module in which the class is defined. __bases__ : Tuple of base classes (used in inheritance). Example: class Demo: "Sample class" pass print(Demo.__doc__) print(Demo.__name__) print(Demo.__module__) print(Demo.__dict__) PART E – FILE HANDLING 1. File Types Text files: Store data in human-readable characters (ASCII or Unicode). Used for documents, logs, code. Read/written in string format. Example: with open("note.txt", "w") as f: f.write("Hello World") Binary files: Store data in raw byte format (0s and 1s). Examples: images, audio, video. Must be opened using rb (read binary) or wb (write binary). Reading returns bytes. Example: with open("image.jpg", "rb") as f: data = f.read() 2. Access Modes Specify how a file should be opened for read, write, append operations using open() function. Common Modes: r : Read-only (file must exist). w : Write (overwrites file or creates new). a : Append to end of file. r+ : Read and write (file must exist). w+ : Write and read (overwrites or creates new). a+ : Append and read. rb , wb , ab : Binary versions of the above modes. 3. Opening & Closing Files Files are opened using the open() function, which returns a file object. After operations, files must be closed using close() to free resources. Example: f = open("data.txt", "r") # file operations... f.close() The with statement automatically closes the file: with open("data.txt", "r") as f: content = f.read() 4. Writing to Files Uses write() (for strings) and writelines() (for lists of strings). File must be opened in w , w+ , or a mode. Example: f = open("data.txt", "w") f.write("Hello Python\n") f.writelines(["Line1\n", "Line2\n"]) f.close() w mode overwrites existing content; a mode appends. 5. Reading Files Methods for reading file contents. File must be opened in r , r+ , or a+ mode. read() : Reads the entire file as a string. readline() : Reads one line at a time. readlines() : Reads all lines and returns them as a list. Example: f = open("data.txt", "r") print(f.read()) # entire file f.close()