mirror of
https://github.com/blshaer/python-by-example.git
synced 2026-03-27 23:29:25 +01:00
338 lines
9.6 KiB
Python
338 lines
9.6 KiB
Python
"""
|
|
================================================================================
|
|
File: 01_function_basics.py
|
|
Topic: Python Functions - Basic Concepts
|
|
================================================================================
|
|
|
|
This file demonstrates the fundamentals of functions in Python. Functions
|
|
are reusable blocks of code that perform specific tasks, making your code
|
|
more organized, readable, and maintainable.
|
|
|
|
Key Concepts:
|
|
- Defining functions with def
|
|
- Calling functions
|
|
- Function documentation (docstrings)
|
|
- Variable scope (local vs global)
|
|
- Basic parameters
|
|
|
|
================================================================================
|
|
"""
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# 1. Defining and Calling Functions
|
|
# -----------------------------------------------------------------------------
|
|
# Use 'def' keyword to define a function
|
|
|
|
print("--- Defining and Calling Functions ---")
|
|
|
|
# Simple function with no parameters
|
|
def greet():
|
|
"""Print a greeting message."""
|
|
print("Hello, World!")
|
|
|
|
# Call the function
|
|
greet()
|
|
|
|
# Function with a parameter
|
|
def greet_person(name):
|
|
"""Greet a specific person."""
|
|
print(f"Hello, {name}!")
|
|
|
|
greet_person("Baraa")
|
|
greet_person("Sara")
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# 2. Function with Multiple Parameters
|
|
# -----------------------------------------------------------------------------
|
|
|
|
print("\n--- Multiple Parameters ---")
|
|
|
|
def introduce(name, age, city):
|
|
"""Introduce a person with their details."""
|
|
print(f"My name is {name}, I am {age} years old, and I live in {city}.")
|
|
|
|
introduce("Ali", 25, "Cairo")
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# 3. Return Values
|
|
# -----------------------------------------------------------------------------
|
|
# Functions can return values using 'return'
|
|
|
|
print("\n--- Return Values ---")
|
|
|
|
def add(a, b):
|
|
"""Add two numbers and return the result."""
|
|
return a + b
|
|
|
|
result = add(5, 3)
|
|
print(f"5 + 3 = {result}")
|
|
|
|
# Using returned value in expressions
|
|
total = add(10, 20) + add(5, 5)
|
|
print(f"(10+20) + (5+5) = {total}")
|
|
|
|
# Function without explicit return returns None
|
|
def print_message(msg):
|
|
print(msg)
|
|
|
|
result = print_message("Hello")
|
|
print(f"Function without return: {result}") # None
|
|
|
|
# Early return
|
|
def get_grade(score):
|
|
"""Return letter grade based on score."""
|
|
if score >= 90:
|
|
return "A"
|
|
if score >= 80:
|
|
return "B"
|
|
if score >= 70:
|
|
return "C"
|
|
if score >= 60:
|
|
return "D"
|
|
return "F"
|
|
|
|
print(f"\nScore 85 → Grade {get_grade(85)}")
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# 4. Docstrings - Function Documentation
|
|
# -----------------------------------------------------------------------------
|
|
# Use triple quotes to document what a function does
|
|
|
|
print("\n--- Docstrings ---")
|
|
|
|
def calculate_area(length, width):
|
|
"""
|
|
Calculate the area of a rectangle.
|
|
|
|
Args:
|
|
length: The length of the rectangle (positive number)
|
|
width: The width of the rectangle (positive number)
|
|
|
|
Returns:
|
|
The area of the rectangle (length * width)
|
|
|
|
Example:
|
|
>>> calculate_area(5, 3)
|
|
15
|
|
"""
|
|
return length * width
|
|
|
|
# Access docstring
|
|
print(f"Function docstring:\n{calculate_area.__doc__}")
|
|
|
|
# Using help()
|
|
# help(calculate_area) # Uncomment to see full help
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# 5. Variable Scope - Local vs Global
|
|
# -----------------------------------------------------------------------------
|
|
# Variables inside functions are local by default
|
|
|
|
print("\n--- Variable Scope ---")
|
|
|
|
global_var = "I am global"
|
|
|
|
def demonstrate_scope():
|
|
"""Demonstrate variable scope."""
|
|
local_var = "I am local"
|
|
print(f" Inside function - global_var: {global_var}")
|
|
print(f" Inside function - local_var: {local_var}")
|
|
|
|
demonstrate_scope()
|
|
print(f"Outside function - global_var: {global_var}")
|
|
# print(local_var) # This would cause an error!
|
|
|
|
# Modifying global variables inside functions
|
|
counter = 0
|
|
|
|
def increment_counter():
|
|
"""Increment the global counter."""
|
|
global counter # Declare we want to modify global variable
|
|
counter += 1
|
|
print(f" Counter inside function: {counter}")
|
|
|
|
print(f"\nCounter before: {counter}")
|
|
increment_counter()
|
|
increment_counter()
|
|
print(f"Counter after: {counter}")
|
|
|
|
# Local variable shadows global
|
|
value = 100
|
|
|
|
def shadow_example():
|
|
"""Local variable shadows global."""
|
|
value = 200 # This is a new local variable, not the global one
|
|
print(f" Inside function: {value}")
|
|
|
|
print(f"\nGlobal value: {value}")
|
|
shadow_example()
|
|
print(f"Global value unchanged: {value}")
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# 6. Multiple Return Values
|
|
# -----------------------------------------------------------------------------
|
|
# Functions can return multiple values as a tuple
|
|
|
|
print("\n--- Multiple Return Values ---")
|
|
|
|
def get_min_max(numbers):
|
|
"""Return both minimum and maximum of a list."""
|
|
return min(numbers), max(numbers)
|
|
|
|
data = [5, 2, 8, 1, 9, 3]
|
|
minimum, maximum = get_min_max(data)
|
|
print(f"List: {data}")
|
|
print(f"Min: {minimum}, Max: {maximum}")
|
|
|
|
# Return multiple named values using dictionary
|
|
def analyze_text(text):
|
|
"""Analyze text and return statistics."""
|
|
return {
|
|
"length": len(text),
|
|
"words": len(text.split()),
|
|
"uppercase": sum(1 for c in text if c.isupper())
|
|
}
|
|
|
|
stats = analyze_text("Hello World! How Are You?")
|
|
print(f"\nText stats: {stats}")
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# 7. Pass Statement - Placeholder Functions
|
|
# -----------------------------------------------------------------------------
|
|
# Use pass to create empty function bodies
|
|
|
|
print("\n--- Placeholder Functions ---")
|
|
|
|
def future_feature():
|
|
"""This will be implemented later."""
|
|
pass # Placeholder - does nothing
|
|
|
|
def another_placeholder():
|
|
"""Placeholder with ellipsis (also valid)."""
|
|
... # Alternative to pass
|
|
|
|
future_feature() # Can be called, just does nothing
|
|
print("Placeholder functions work!")
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# 8. Nested Functions
|
|
# -----------------------------------------------------------------------------
|
|
# Functions can be defined inside other functions
|
|
|
|
print("\n--- Nested Functions ---")
|
|
|
|
def outer_function(message):
|
|
"""Outer function that contains an inner function."""
|
|
|
|
def inner_function():
|
|
"""Inner function that uses outer's variable."""
|
|
print(f" Inner says: {message}")
|
|
|
|
print("Outer function called")
|
|
inner_function()
|
|
|
|
outer_function("Hello from outer!")
|
|
|
|
# Inner function not accessible outside
|
|
# inner_function() # This would cause an error!
|
|
|
|
# Practical example: Helper function
|
|
def calculate_statistics(numbers):
|
|
"""Calculate various statistics using helper functions."""
|
|
|
|
def mean(nums):
|
|
return sum(nums) / len(nums)
|
|
|
|
def variance(nums):
|
|
avg = mean(nums)
|
|
return sum((x - avg) ** 2 for x in nums) / len(nums)
|
|
|
|
return {
|
|
"mean": mean(numbers),
|
|
"variance": variance(numbers),
|
|
"std_dev": variance(numbers) ** 0.5
|
|
}
|
|
|
|
data = [2, 4, 4, 4, 5, 5, 7, 9]
|
|
stats = calculate_statistics(data)
|
|
print(f"\nStatistics for {data}:")
|
|
for key, value in stats.items():
|
|
print(f" {key}: {value:.2f}")
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# 9. Functions as Objects
|
|
# -----------------------------------------------------------------------------
|
|
# In Python, functions are first-class objects
|
|
|
|
print("\n--- Functions as Objects ---")
|
|
|
|
def say_hello(name):
|
|
"""Just say hello."""
|
|
return f"Hello, {name}!"
|
|
|
|
# Assign function to variable
|
|
greeting_func = say_hello
|
|
print(greeting_func("World"))
|
|
|
|
# Store functions in a list
|
|
def add_one(x): return x + 1
|
|
def double(x): return x * 2
|
|
def square(x): return x * x
|
|
|
|
operations = [add_one, double, square]
|
|
value = 5
|
|
|
|
print(f"\nApplying operations to {value}:")
|
|
for func in operations:
|
|
print(f" {func.__name__}({value}) = {func(value)}")
|
|
|
|
# Pass function as argument
|
|
def apply_operation(func, value):
|
|
"""Apply a function to a value."""
|
|
return func(value)
|
|
|
|
print(f"\napply_operation(double, 10) = {apply_operation(double, 10)}")
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# 10. Practical Examples
|
|
# -----------------------------------------------------------------------------
|
|
|
|
print("\n--- Practical Examples ---")
|
|
|
|
# Temperature converter
|
|
def celsius_to_fahrenheit(celsius):
|
|
"""Convert Celsius to Fahrenheit."""
|
|
return (celsius * 9/5) + 32
|
|
|
|
def fahrenheit_to_celsius(fahrenheit):
|
|
"""Convert Fahrenheit to Celsius."""
|
|
return (fahrenheit - 32) * 5/9
|
|
|
|
print(f"20°C = {celsius_to_fahrenheit(20):.1f}°F")
|
|
print(f"68°F = {fahrenheit_to_celsius(68):.1f}°C")
|
|
|
|
# Password validator
|
|
def is_valid_password(password):
|
|
"""
|
|
Check if password meets requirements:
|
|
- At least 8 characters
|
|
- Contains uppercase letter
|
|
- Contains lowercase letter
|
|
- Contains digit
|
|
"""
|
|
if len(password) < 8:
|
|
return False, "Too short"
|
|
if not any(c.isupper() for c in password):
|
|
return False, "No uppercase letter"
|
|
if not any(c.islower() for c in password):
|
|
return False, "No lowercase letter"
|
|
if not any(c.isdigit() for c in password):
|
|
return False, "No digit"
|
|
return True, "Valid password"
|
|
|
|
test_passwords = ["short", "alllowercase", "ALLUPPERCASE", "ValidPass123"]
|
|
print("\nPassword validation:")
|
|
for pwd in test_passwords:
|
|
is_valid, message = is_valid_password(pwd)
|
|
print(f" '{pwd}': {message}")
|