Advanced Python: Functions, Control Flow & OOP
Part 1: Advanced Functions
1.1 Default Parameters and Keyword Arguments
You can give function parameters default values:
python
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"
print(greet("Alice")) # Hello, Alice!
print(greet("Bob", "Hi")) # Hi, Bob!
print(greet("Charlie", greeting="Hey")) # Hey, Charlie! (keyword argument)
1.2 *args and **kwargs
Handle variable numbers of arguments:
python
# *args - collects positional arguments into a tuple
def add_all(*numbers):
total = 0
for num in numbers:
total += num
return total
print(add_all(1, 2, 3)) #6
print(add_all(5, 10, 15, 20)) # 50
# **kwargs - collects keyword arguments into a dictionary
def print_info(**info):
for key, value in [Link]():
print(f"{key}: {value}")
print_info(name="Alice", age=25, city="New York")
1.3 Lambda Functions
Short, anonymous functions for simple operations:
python
# Regular function
def square(x):
return x ** 2
# Lambda equivalent
square_lambda = lambda x: x ** 2
# Often used with map, filter, sorted
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared) # [1, 4, 9, 16, 25]
# Filter even numbers
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # [2, 4]
1.4 Function Decorators (Preview)
Functions that modify other functions:
python
def uppercase_decorator(func):
def wrapper():
result = func()
return [Link]()
return wrapper
@uppercase_decorator
def greet():
return "hello world"
print(greet()) # HELLO WORLD
Part 2: Control Statements
2.1 If-Elif-Else Statements
python
age = 18
if age < 13:
print("Child")
elif age < 20:
print("Teenager")
elif age < 60:
print("Adult")
else:
print("Senior")
2.2 Ternary Operator
Compact if-else for simple conditions:
python
age = 20
status = "Adult" if age >= 18 else "Minor"
print(status) # Adult
2.3 For Loops
python
# Iterate over lists
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# Using range()
for i in range(5): # 0 to 4
print(i)
# With index and value using enumerate()
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")
# Iterate over dictionaries
person = {"name": "Alice", "age": 25}
for key, value in [Link]():
print(f"{key}: {value}")
2.4 While Loops
python
count = 0
while count < 5:
print(count)
count += 1
# Be careful with infinite loops!
# while True:
# print("This runs forever!")
2.5 Break, Continue, and Pass
python
# break - exit the loop
for i in range(10):
if i == 5:
break
print(i) # Prints 0-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(3):
pass # TODO: implement later
2.6 List Comprehensions
Create lists using compact syntax:
python
# Traditional way
squares = []
for x in range(10):
[Link](x ** 2)
# List comprehension
squares = [x ** 2 for x in range(10)]
# With condition
evens = [x for x in range(20) if x % 2 == 0]
print(evens) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
Part 3: Object-Oriented Programming (OOP)
3.1 Classes and Objects
Classes are blueprints for creating objects:
python
class Dog:
# Constructor method - runs when object is created
def __init__(self, name, age):
[Link] = name # instance variable
[Link] = age
# Instance method
def bark(self):
return f"{[Link]} says Woof!"
def get_age_in_human_years(self):
return [Link] * 7
# Create objects (instances)
dog1 = Dog("Buddy", 3)
dog2 = Dog("Max", 5)
print([Link]) # Buddy
print([Link]()) # Buddy says Woof!
print(dog1.get_age_in_human_years()) # 21
3.2 Class Variables vs Instance Variables
python
class Employee:
# Class variable (shared by all instances)
company_name = "TechCorp"
employee_count = 0
def __init__(self, name, salary):
# Instance variables (unique to each instance)
[Link] = name
[Link] = salary
Employee.employee_count += 1
emp1 = Employee("Alice", 50000)
emp2 = Employee("Bob", 60000)
print(Employee.company_name) # TechCorp
print(Employee.employee_count) #2
print([Link]) # Alice
3.3 Inheritance
Create classes based on existing classes:
python
# Parent class (Base class)
class Animal:
def __init__(self, name):
[Link] = name
def speak(self):
return "Some sound"
# Child classes (Derived classes)
class Dog(Animal):
def speak(self): # Method overriding
return f"{[Link]} barks"
class Cat(Animal):
def speak(self):
return f"{[Link]} meows"
dog = Dog("Buddy")
cat = Cat("Whiskers")
print([Link]()) # Buddy barks
print([Link]()) # Whiskers meows
3.4 The super() Function
Call parent class methods:
python
class Vehicle:
def __init__(self, brand, model):
[Link] = brand
[Link] = model
def info(self):
return f"{[Link]} {[Link]}"
class Car(Vehicle):
def __init__(self, brand, model, doors):
super().__init__(brand, model) # Call parent constructor
[Link] = doors
def info(self):
return f"{super().info()} with {[Link]} doors"
car = Car("Toyota", "Camry", 4)
print([Link]()) # Toyota Camry with 4 doors
3.5 Encapsulation (Private Variables)
Use underscore prefix to indicate "private" attributes:
python
class BankAccount:
def __init__(self, owner, balance):
[Link] = owner
self.__balance = balance # Private variable (convention)
def deposit(self, amount):
if amount > 0:
self.__balance += amount
return True
return False
def get_balance(self):
return self.__balance
account = BankAccount("Alice", 1000)
[Link](500)
print(account.get_balance()) # 1500
# print(account.__balance) # AttributeError (not directly accessible)
3.6 Class Methods and Static Methods
python
class MathOperations:
pi = 3.14159
# Class method - works with class itself
@classmethod
def circle_area(cls, radius):
return [Link] * radius ** 2
# Static method - doesn't need class or instance
@staticmethod
def add(a, b):
return a + b
# Call without creating an instance
print(MathOperations.circle_area(5)) # 78.53975
print([Link](10, 20)) # 30
3.7 Magic Methods (Dunder Methods)
Special methods that add "magic" to your classes:
python
class Book:
def __init__(self, title, author, pages):
[Link] = title
[Link] = author
[Link] = pages
# String representation
def __str__(self):
return f"{[Link]} by {[Link]}"
# Length
def __len__(self):
return [Link]
# Comparison
def __eq__(self, other):
return [Link] == [Link]
book1 = Book("Python Basics", "John Doe", 200)
book2 = Book("Advanced Python", "Jane Smith", 200)
print(book1) # Python Basics by John Doe
print(len(book1)) # 200
print(book1 == book2) # True (same number of pages)
Practice Exercises
Exercise 1: Functions
Create a function that takes any number of numbers and returns their average.
python
# Your solution here
def average(*numbers):
# Complete this
pass
Exercise 2: Control Flow
Write a program that prints "Fizz" for multiples of 3, "Buzz" for multiples of 5, and "FizzBuzz"
for multiples of both, for numbers 1-30.
Exercise 3: OOP
Create a Rectangle class with:
• Constructor that takes width and height
• Methods to calculate area and perimeter
• A method to check if it's a square
• Use proper encapsulation
python
# Your solution here
class Rectangle:
# Complete this
pass
Key Takeaways
1. Functions: Use default parameters, *args/**kwargs for flexibility, and lambda for simple
operations
2. Control Flow: Master if/elif/else, loops, and list comprehensions for efficient code
3. OOP: Classes encapsulate data and behavior, inheritance promotes code reuse, and special
methods add powerful functionality
Next Steps
• Practice creating your own classes with real-world examples
• Explore more magic methods like __add__ , __getitem__ , __call__
• Learn about multiple inheritance and abstract base classes
• Study design patterns that use OOP principles