Build a simple contacts manager using a dictionary:
contacts = {
"Ahmed": "050-1234567",
"Sara": "055-7654321",
"Ali": "052-1112233"
}
# print all contacts
for name, number in contacts.items():
print(f"{name}: {number}")
# search for a contact
search = input("Search name: ").strip().title()
if search in contacts:
print(f"Number: {contacts[search]}")
else:
print("Contact not found")Extend it — let the user add a new contact and delete one
Screenshot your output
Bonus — store each contact as a nested dict with number and email
Please open Telegram to view this post
VIEW IN TELEGRAM
You have been writing code that runs top to bottom
But what happens when you need to do the same thing in 10 different places?
You do not copy paste it 10 times
You put it in a function and call it whenever you need it
Functions are one of the most important concepts in programming
Everything in real code is built with functions
This lecture covers:
Please open Telegram to view this post
VIEW IN TELEGRAM
You create a function with the def keyword:
def greet():
print("Hello! Welcome to the channel")
Nothing happens yet — you need to call it:
greet() # Hello! Welcome to the channel
greet() # Hello! Welcome to the channel
greet() # Hello! Welcome to the channel
One function, called 3 times
If you need to change the message you change it in one place — not 3
This is the power of functions
Please open Telegram to view this post
VIEW IN TELEGRAM
Parameters let you pass data into a function:
def greet(name):
print(f"Hello {name}!")
greet("Ahmed") # Hello Ahmed!
greet("Sara") # Hello Sara!
greet("Ali") # Hello Ali!
Multiple parameters:
def introduce(name, age, city):
print(f"My name is {name}, I am {age} years old and from {city}")
introduce("Ahmed", 22, "Dubai")
Parameter = the variable in the function definition
Argument = the actual value you pass when calling it
People use these words interchangeably — do not stress about it
Please open Telegram to view this post
VIEW IN TELEGRAM
Functions can also give something back using return
def add(a, b):
return a + b
result = add(10, 5)
print(result) # 15
Without return your function does something but gives nothing back
With return your function produces a value you can use elsewhere
def is_adult(age):
if age >= 18:
return True
return False
if is_adult(20):
print("Access granted")
else:
print("Access denied")
Return also stops the function immediately
Any code after return does not run
Please open Telegram to view this post
VIEW IN TELEGRAM
You can give parameters a default value
If nothing is passed — it uses the default
def greet(name, message="Welcome back"):
print(f"Hello {name}! {message}")
greet("Ahmed") # Hello Ahmed! Welcome back
greet("Sara", "You are now banned") # Hello Sara! You are now banned
Default parameters must always come after non-default ones
You will use this constantly in bot handlers
For example a send_message function where parse_mode defaults to HTML
Please open Telegram to view this post
VIEW IN TELEGRAM
Sometimes you do not know how many arguments will be passed
*args — accepts any number of positional arguments as a tuple:
def add_all(*numbers):
return sum(numbers)
print(add_all(1, 2, 3)) # 6
print(add_all(1, 2, 3, 4, 5)) # 15
**kwargs — accepts any number of keyword arguments as a dictionary:
def show_info(**details):
for key, value in details.items():
print(f"{key}: {value}")
show_info(name="Ahmed", age=22, city="Dubai")
You do not need to memorize these right now
Just know they exist — you will see them when reading library code
Please open Telegram to view this post
VIEW IN TELEGRAM
Watch this after reading through all the posts
Python Full Course 2024 — freeCodeCamp
Covers creating custom functions, parameters, default values, and organizing code
Please open Telegram to view this post
VIEW IN TELEGRAM
Build a calculator using functions:
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
return "Cannot divide by zero"
return a / b
a = float(input("First number: "))
b = float(input("Second number: "))
op = input("Operation (+, -, *, /): ")
if op == "+":
print(add(a, b))
elif op == "-":
print(subtract(a, b))
elif op == "*":
print(multiply(a, b))
elif op == "/":
print(divide(a, b))
else:
print("Invalid operation")
Screenshot your output with a few different calculations
Bonus — wrap the whole thing in a loop so it keeps running until user types "exit"
Please open Telegram to view this post
VIEW IN TELEGRAM
Your code will crash
Not maybe — definitely
The question is whether your program handles it gracefully or just dies
Error handling is what separates beginner code from production code
Real apps never crash on the user — they catch errors and respond properly
This lecture covers:
Please open Telegram to view this post
VIEW IN TELEGRAM
When Python cannot run your code it raises an exception
By default this crashes your program with an error message
Common errors you have probably already seen:
print(x) # NameError — x does not exist
int("hello") # ValueError — cannot convert "hello" to int
10 / 0 # ZeroDivisionError — cannot divide by zero
my_list[99] # IndexError — index out of range
user["email"] # KeyError — key does not exist in dict
Each error type tells you exactly what went wrong
Read your error messages — they are your friend, not your enemy
Please open Telegram to view this post
VIEW IN TELEGRAM
Wrap risky code in a try block
If it crashes Python jumps to the except block instead of dying
try:
age = int(input("Enter your age: "))
print(f"You are {age} years old")
except:
print("That is not a valid number")
Now if the user types "hello" instead of a number
Your program does not crash — it prints the error message and continues
Always catch specific exceptions when you can:
try:
age = int(input("Enter your age: "))
print(f"You are {age} years old")
except ValueError:
print("Please enter a number, not text")
Catching specific errors makes your code cleaner and easier to debug
Please open Telegram to view this post
VIEW IN TELEGRAM
else — runs only if no exception occurred:
try:
age = int(input("Enter your age: "))
except ValueError:
print("Invalid input")
else:
print(f"Age saved: {age}") # only runs if try succeeded
finally — always runs no matter what:
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero")
finally:
print("This always runs") # cleanup code goes here
finally is used for cleanup — closing files, closing database connections
You will use it a lot in bot development
Please open Telegram to view this post
VIEW IN TELEGRAM
try:
number = int(input("Enter a number: "))
result = 100 / number
print(f"Result: {result}")
except ValueError:
print("That is not a number")
except ZeroDivisionError:
print("Cannot divide by zero")
except Exception as e:
print(f"Something went wrong: {e}") # catches anything else
Exception as e gives you the actual error message as a variable
Useful for logging what went wrong
Order matters — put specific exceptions first, general ones last
Please open Telegram to view this post
VIEW IN TELEGRAM
You can also trigger errors yourself using raise
Useful when you want to enforce rules in your functions
def set_age(age):
if age < 0:
raise ValueError("Age cannot be negative")
if age > 150:
raise ValueError("That age is not realistic")
return age
try:
set_age(-5)
except ValueError as e:
print(f"Error: {e}")
This is how you protect your functions from bad input
You will use this pattern constantly in bot command handlers
Please open Telegram to view this post
VIEW IN TELEGRAM
Watch this after reading through all the posts
Python Full Course 2024 — freeCodeCamp
Covers exceptions, try/except, handling specific errors, and abstracting user input
Please open Telegram to view this post
VIEW IN TELEGRAM
Take the calculator from last lecture and add proper error handling:
def divide(a, b):
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
while True:
try:
a = float(input("First number: "))
b = float(input("Second number: "))
op = input("Operation (+, -, *, /): ")
if op == "+":
print(a + b)
elif op == "-":
print(a - b)
elif op == "*":
print(a * b)
elif op == "/":
print(divide(a, b))
else:
print("Invalid operation")
except ValueError as e:
print(f"Error: {e}")
except Exception as e:
print(f"Something went wrong: {e}")
Test it with bad inputs — letters, division by zero, invalid operators
Make sure it never crashes — just shows an error and continues
Screenshot your output
Please open Telegram to view this post
VIEW IN TELEGRAM