Lesson 7 - Functions & Code Blocks
Learning Objective
Define reusable functions with def, use parameters and default values, and understand the difference between return and print and how each function call gets its own local scope.
Introduction
As programs grow, repeating the same block of code becomes messy and error-prone.
Imagine fixing a bug in one copy of some logic but forgetting to update four other copies elsewhere in the program. Functions solve this problem by allowing you to write the logic once, give it a name, and call it whenever you need it.
In this lesson, you’ll learn:
- How to define functions using
def - How to pass information into functions using parameters
- How to provide default parameter values
- The difference between
returnandprint - How local scope works inside functions
What Is a Function?
A function is a reusable block of code that performs a specific task.
Example:
def greet():
print("Hello!")Calling the function:
greet()Output:
Hello!The function’s code runs only when the function is called.
Function Parameters
Parameters allow functions to receive input values.
Example:
def greet(name):
print(f"Hello, {name}!")Calling:
greet("Priya")Output:
Hello, Priya!The value "Priya" is passed into the function through the name parameter.
Default Parameters
Functions can provide default values for parameters.
def greet(name, times=1):
for _ in range(times):
print(f"Hello, {name}!")Examples:
greet("Priya")Uses the default:
Hello, Priya!And:
greet("Priya", times=3)Produces:
Hello, Priya!
Hello, Priya!
Hello, Priya!Code
# functions.py
def convert_c_to_f(celsius):
fahrenheit = celsius * 9 / 5 + 32
return fahrenheit
def describe_temperature(celsius, unit="C"):
if unit == "F":
value = convert_c_to_f(celsius)
label = "F"
else:
value = celsius
label = "C"
return f"{value:.1f}°{label}"
print(describe_temperature(20))
print(describe_temperature(20, unit="F"))
def greet(name, times=1):
for _ in range(times):
print(f"Hello, {name}!")
greet("Priya")
greet("Priya", times=3)Expected Output
Click to see expected output
20.0°C
68.0°F
Hello, Priya!
Hello, Priya!
Hello, Priya!
Hello, Priya!Returning Values
Functions often calculate something and send the result back to the caller.
Example:
def square(x):
return x * xUsage:
result = square(5)
print(result)Output:
25The caller receives the value and can store or reuse it.
Functions Calling Functions
Functions can call other functions.
Example from this lesson:
def convert_c_to_f(celsius):
return celsius * 9 / 5 + 32
def describe_temperature(celsius, unit="F"):
value = convert_c_to_f(celsius)
return f"{value:.1f}°F"This helps keep programs modular and easier to maintain.
Local Scope
Variables created inside a function exist only while that function is running.
def example():
message = "Hello"
print(message)This works:
example()But this does not:
print(message)Output:
NameError: name 'message' is not definedThe variable only exists inside the function’s local scope.
🔧 Under the Hood
What’s the difference between return and print?
print() displays information on the screen.
def add(a, b):
print(a + b)Calling:
result = add(2, 3)Displays:
5But:
print(result)Outputs:
Nonebecause the function did not return anything.
By contrast:
def add(a, b):
return a + bNow:
result = add(2, 3)
print(result)Outputs:
5and the value can be reused in later calculations.
Local Scope
Each time a function is called, Python creates a fresh local scope.
For example:
def convert_c_to_f(celsius):
fahrenheit = celsius * 9 / 5 + 32
return fahrenheitThe variable:
fahrenheitexists only while that function call is executing.
When the function finishes, its local variables disappear.
This prevents variables inside one function from interfering with variables elsewhere in the program.
Student Challenge
Challenge 1
Write a function called is_prime(n) that returns True if n is prime and False otherwise.
Then use it to print every prime number between 2 and 30.
Hint
The moment you find a divisor that divides n evenly, you already know the number is not prime.
Return:
Falseimmediately instead of continuing the loop.
Click to see solution
# primes.py
def is_prime(n):
if n < 2:
return False
for divisor in range(2, n):
if n % divisor == 0:
return False
return True
for number in range(2, 31):
if is_prime(number):
print(number)Challenge 2
Wrap a square patrol sequence into a reusable function and run it on your BonicBot.
Extend the function by adding:
laps=1so the entire square patrol can be repeated multiple times.
Then compare your implementation with the SDK’s built-in:
bot.draw_square(side_m)Full details are available in the Python SDK reference.
Hint
Wrap the existing loop:
for _ in range(4):inside another loop:
for lap in range(laps):to repeat the full square path.
Click to see solution
# challenge_patrol_function.py
from bonicbot_bridge import BonicBot
def patrol_square(bot, side_m=0.4, speed=0.2, laps=1):
for _ in range(laps):
for _ in range(4):
bot.drive_distance(side_m, speed=speed)
bot.rotate_angle(90, speed=45.0)
bot.stop()
with BonicBot(host='192.168.0.188') as bot:
print(f"Battery before patrol: {bot.get_battery()}%")
patrol_square(bot, side_m=0.4, laps=2)
print(f"Battery after patrol: {bot.get_battery()}%")Reflection Question
patrol_square()takesbotas a parameter instead of assuming a global variable calledbotalready exists. What does passing it in as a parameter let you do that a hardcoded global reference wouldn’t?
By the end of this lesson, you should be able to define functions, pass parameters, use default values, return results, understand local scope, and build reusable pieces of logic that make larger programs easier to maintain.