Skip to main content

Functions

Introducing Functions

Lets do a simple problem that involves airthmetic operators:

Problem: Calculate the area of a rectangle

Solution without functions

#We want to calculate the area of multiple rectangles by providing their length and width.

# Calculate and print the area of first rectangle
area1 = None
length1 = 5
width1 = 3
print(f"Area of second rectangle: {area1}")

# Calculate and print the area of second rectangle
area2 = None
length2 = 7
width2 = 4
area2 = None
print(f"Area of second rectangle: {area2}")

# Calculate and print the area of third rectangle
area3 = None
length3 = 10
width3 = 2
print(f"Area of third rectangle: {area3}")

As you can see, we have to repeat the same code every time. What if we had to calculate the area of 5 functions?

With functions, we can encapsulate the logic to calculate the area and reuse it easily.

Solution with functions

# Define a function to calculate the area of a rectangle
def calculate_rectangle_area(length, width):
return length * width

# First rectangle
length1 = 5
width1 = 3
area1 = calculate_rectangle_area(length1, width1)
print(f"Area of first rectangle: {area1}")

# Second rectangle
length2 = 7
width2 = 4
area2 = calculate_rectangle_area(length2, width2)
print(f"Area of second rectangle: {area2}")

# Third rectangle
length3 = 10
width3 = 2
area3 = calculate_rectangle_area(length3, width3)
print(f"Area of third rectangle: {area3}")

Why functions are better:

  1. Avoid Repetition: The logic to calculate the area is written only once.
  2. Reusability: You can use the same function wherever you need it.
  3. Readability: Code is easier to read and maintain since the function name clearly states what it does.
  4. Scalability: Adding more rectangle calculations is simple with just one function call.

Lets us study another problem that can be simplified using functions.

We are tasked with developing a system to evaluate and display the performance of students based on their marks. Each student is assigned a grade based on predefined rules:

  • Marks >= 90: Grade A
  • Marks >= 80: Grade B
  • Marks >= 70: Grade C
  • Marks >= 60: Grade D
  • Marks < 60: Grade F

The system should handle the following:

  • Calculate the grade for a student based on their marks.
  • Display each student's name, marks, and grade in a clear format.

Solution without functions:

# Student 1
name1 = "Alice"
marks1 = 92
if marks1 >= 90:
grade1 = "A"
elif marks1 >= 80:
grade1 = "B"
elif marks1 >= 70:
grade1 = "C"
elif marks1 >= 60:
grade1 = "D"
else:
grade1 = "F"
print(f"Student: {name1}, Marks: {marks1}, Grade: {grade1}")

# Student 2
name2 = "Bob"
marks2 = 75
if marks2 >= 90:
grade2 = "A"
elif marks2 >= 80:
grade2 = "B"
elif marks2 >= 70:
grade2 = "C"
elif marks2 >= 60:
grade2 = "D"
else:
grade2 = "F"
print(f"Student: {name2}, Marks: {marks2}, Grade: {grade2}")

# Student 3
name3 = "Charlie"
marks3 = 58
if marks3 >= 90:
grade3 = "A"
elif marks3 >= 80:
grade3 = "B"
elif marks3 >= 70:
grade3 = "C"
elif marks3 >= 60:
grade3 = "D"
else:
grade3 = "F"
print(f"Student: {name3}, Marks: {marks3}, Grade: {grade3}")

# Student 4
name4 = "Robert"
marks4 = 82
if marks4 >= 90:
grade4 = "A"
elif marks4 >= 80:
grade4 = "B"
elif marks4 >= 70:
grade4 = "C"
elif marks4 >= 60:
grade4 = "D"
else:
grade4 = "F"
print(f"Student: {name4}, Marks: {marks4}, Grade: {grade4}")

Before proceeding answer these questions:

  1. How many lines of code the above program has?
  2. Add another student to the above code and run it:
# Student 4
name3 = "Robert"
marks3 = 82
  1. How many extra lines of code had to be added?
  2. What is the total lines of code after adding Student #4?
  3. What is the average line of code per student for the above program?
  4. There is a bug in the above program. Can you identify it?
  5. What would be the total lines of code for 10 students? How about 100 students?

Solution with functions

# Define a function to calculate grade based on marks
def calculate_grade(marks):
if marks >= 90:
return "A"
elif marks >= 80:
return "B"
elif marks >= 70:
return "C"
elif marks >= 60:
return "D"
else:
return "F"

# Define a function to print student details
def display_student_grade(name, marks):
grade = calculate_grade(marks)
print(f"Student: {name}, Marks: {marks}, Grade: {grade}")

# Student 1
name1 = "Alice"
marks1 = 92
display_student_grade(name1, marks1)

# Student 2
name2 = "Bob"
marks2 = 75
display_student_grade(name2, marks2)

# Student 3
name3 = "Charlie"
marks3 = 58
display_student_grade(name3, marks3)

Now answer these questions:

  1. How many lines of code the above program has?
  2. Add another student to the above code and run it:
# Student 4
name3 = "Robert"
marks3 = 82
  1. How many extra lines of code had to be added?
  2. What is the total lines of code after adding Student #4?
  3. What is the average line of code per student for the above program?
  4. What would be the total lines of code for 10 students? How about 100 students?

Anatomy of the Function

Lets understand what a function is and how it works with the following example:

  • Example Function: Calculating the Square of a Number
def calculate_square(number):
square = number * number
return square

Function Definition:

def calculate_square(number):
  • def: The keyword used to define a function.
  • calculate_square: The name of the function. It should describe what the function does.
  • number: The parameter or input to the function. This is a placeholder that takes a value when the function is called.

Function Body:

square = number * number
  • This is the actual logic or task the function performs.
  • In this case, the function calculates the square by multiplying the input number by itself and storing the result in a variable called square.

Return Statement:

return square
  • The return keyword is used to send the output (or result) of the function back to the caller.
  • Without return, the function would execute but not provide any output.

How to Call the Function

After defining the function, you can call it to use it:

result = calculate_square(5)
print(f"The square of 5 is {result}")
  • calculate_square(5): This calls the function, passing 5 as the value for the parameter number.
  • The function executes and returns the result, which is stored in the variable result.
  • The output would be: The square of 5 is 25.

Key Points to Remember

  • Input (Parameters): Functions can take inputs (like number) to work with dynamic data.
  • Logic (Body): This is where the function performs its task, which can involve calculations, operations, or other processes.
  • Output (Return): Functions can return a result for further use. Without return, the function won't give back a value.
  • Reusability: Functions can be reused multiple times with different inputs, saving effort and making your code cleaner.

Exercises

Now that we know what functions are and how they work, please fix the code for following function definitons.

  • Fix code
  • Explain what was fixed in a comment at the end of the code
#Troubleshooting functions: #1
def add_numbers(a, b):
"""This function adds two numbers."""
result = a + b

a = 5
b = 10
c = add_numbers(a, b)
print(f"Sum of {a} and {b} is: {c}")

#What did you change?
#Troubleshooting functions: #2

def greet_user(name):
"""This function greets a user by name."""
print(f"Hello, username!")

user = "Peter"
greet_user(user)

#What did you change?

#Troubleshooting functions: #3

def greet_user(name):
"""This function greets a user by name."""
print(f"Hello, {username}!")

user = "Peter"
greet_user(user)

#What did you change?

#Troubleshooting functions: #4

def greet_user(name):
"""This function greets a user by name."""
print(f"Hello, {name}!")

user_name = "Peter"
greet_user(user)

#What did you change?
#Troubleshooting functions: #5

def calculate_rectangle_area(length, width):
"""This function calculates the area of a rectangle."""
area = 10 * width
return area

length = 20
width = 30
area_rectangle = calculate_rectangle_area(length, width)
print(f"Area of rectangle with width {width} and length {length} is: {area_rectangle}")

#What did you change?
#Troubleshooting functions: #6

def calculate_circle_area(radius):
"""This function calculates the area of a circle."""
area = 3.14 * radius * radius
return area

# Calling the function
result = calculate_circle_area()

radius = 5

area_circle = calculate_circle_area()
print(f"Area of circle with radius {radius} is: {area_circle}")
#Troubleshooting functions: #7

result = multiply_numbers(3, 4)
print(f"The result is: {result}")

def multiply_numbers(a, b):
"""This function multiplies two numbers."""
return a * b

Function: Deep Dive

Now that we have a basic unnderstanding of functions, let’s dive deeper into parameters, return values, and the concept of NoneType and None in Python

Parameters

Parameters are variables that a function expects when it's called. They allow you to pass data into the function for processing.

Key Points About Parameters:

  • Parameters are placeholders defined in the function.
  • Arguments are the actual values you pass when calling the function.

Example:

def greet_user(name):
"""This function greets the user."""
print(f"Hello, {name}!")

# 'name' is the parameter, "Alice" is the argument.
greet_user("Alice") # Output: Hello, Alice!

Return Values

The return statement is used to send a result or output from a function to the place where the function is called.

Key Points About return:

  • A function without a return statement returns None by default.
  • You can return any type of value: numbers, strings, lists, dictionaries, or even other functions.
  • A return ends the function’s execution.

Example:

def add_numbers(a, b):
"""This function returns the sum of two numbers."""
return a + b

result = add_numbers(5, 7) # 5 and 7 are arguments
print(result) # Output: 12

NoneType and None

In Python, None is a special value that represents "nothing" or "no value". It is of type NoneType.

When does None occur?

  1. No return Statement: If a function does not explicitly return a value, it returns None.
  2. Explicitly Returning None: Sometimes, you might explicitly want a function to return None.

Example 1: Function Without return

def say_hello():
print("Hello!")

result = say_hello()
print(result) # Output: Hello! \n None

Example 2: Explicit None

def do_nothing():
return None

result = do_nothing()
print(result) # Output: None

How to check is a variable is None

1. Using is Operator

The is operator is the recommended way to check for None because it checks identity, ensuring the variable is exactly None.

value = None

if value is None:
print("Value is None") # Output: Value is None
else:
print("Value is not None")

2. Using is not

We can also use is not to check if a value is not None.

value = 10

if value is not None:
print("Value is not None") # Output: Value is not None
else:
print("Value is None")

3. Using Equality Operator (==) The equality operator can also be used to check for None.

value = None

if value == None: # Works, but not recommended
print("Value is None")
else:
print("Value is not None")

Exercises

Please finish these exercises using functions

#Exercise 1: Check if a user entered number is even or odd.

#Expected output:
# Enter a number: 9
# 9: Odd

#Exercise 2: Check if numbers in range 1 to 10 are even or odd?
#Expected outout:

#1: Odd
#2: Even
#3: Odd
#4: Even
#5: Odd
#6: Even
#7: Odd
#8: Even
#9: Odd
#10: Even
#Exercise 3: Prompt the user to enter a number. Print the next higher odd number closest to the user entered number

#Expected output:
# Enter a number: 5
# Next higher odd: 7

#Expected output:
# Enter a number: 6
# Next higher odd: 7
#Exercise 4: Prompt the user to enter 2 numbers: Print the higher of the numbers as outout

#Expected outout:
# Enter number 1: 34
# Enter number 2: 67
# Higher number: 67

What is a Factorial?

The factorial of a number is the product of all positive integers from 1 up to that number. It is represented by an exclamation mark (!).

Formula:

n! = n × (n−1) × (n−2) × ⋯× 1

Example:

Factorial of 3:

3! =3 × 2 × 1 = 6

Factorial of 5:

5! = 5 × 4 × 3 × 2 × 1 = 120

Factorial of 1:

1! = 1

#Write a function to calculate factorial of a user entered integer
#Expected outout:
#Enter number to calculate factorial: 4
#Factorial of 4 is: 24