• +2347064964053
Statogale Statogale
  • About
    • About Us
    • Our Team
    • Our Blog
  • Services
    • consultation & training
    • data analysis
    • data cleaning & validation
    • data visualization
    • machine learning
    • statistical modeling
    • All Our Services
  • Case Studies
  • Pricing
  • Contact
  • Signin
    • Login

Our Blog

  • Home
  • Blog
  • Introduction to Python Programming - Function Basics
Introduction to Python Programming - Function Basics
1 year ago
  • Mark Edosa (author)
  • consultation-and-training (category)

Introduction to Python Programming - Function Basics

Table of Contents

  • Introduction
  • Defining Functions
  • Calling a Function
  • Function Parameters and Arguments
  • Return Statement
  • Built-In Functions
  • Lambda Functions
  • An Example: Validate a Full Name

Introduction

At the end of this article, you will have learned the following:

  • how to define and use your functions
  • how to use function parameters and return statements
  • built-in functions
  • lambda functions for one-time-only tasks
  • how to create a function to meet the requirements of a "real-life" scenario.

I assume that you've read the previous articles in this series. Also, you are either a beginner programmer or an experienced programmer learning. Let's get started :)

Let's say you want to calculate the body mass index (BMI) of 20 people. Maybe under different conditions or in other parts of your program. Typically you might be tempted to go straight to the calculation.

Let's assume the height and weight of the first person were 1.71m and 68kg, respectively.


# calculate BMI

# height in meters
height = 1.71

# weight in kilograms
weight = 68

# bmi = weight/height square
bmi = weight / height**2

print(bmi)

How about the second person? You copy the code to where you need it.


# calculate BMI

# height in meters
height = 1.89

# weight in kilograms
weight = 92

# bmi = weight/height square
bmi = weight / height**2

print(bmi)

The third person? Or in a different file? You copy again.

That is way too much repetition that you want to avoid. Luckily, Python functions allow you to group or organize your codes.

An inherent benefit of using functions, apart from logic grouping, is the expression of your intention. Function names are a great way to express your intent to yourself and others who will read your code. For example, let's rewrite the above code that calculates BMI.


# define the function
def calculate_bmi(height, weight):
    bmi = weight / height**2
    return bmi

# call the function and save its output in 
# the result variable
result = calculate_bmi(1.71, 68)

print(result)

You don't have to look at the codes line by line to know what it is doing. It calculates BMI.

In Python, two categories of functions exist - Built-In functions provided by the standard library and user-defined functions (the ones you define yourself). Let's start with user-defined functions since they will enable us to understand Built-In functions.

Defining Functions

To define a function, start by using the def keyword. Followed by the name of the function, a parenthesis, a colon (:), and then the function body. The format is:

def function_name():
    # Do something here in the function body


def second_function(parameter_1, parameter_2, ..., parameter_N):
    # do something here
    
    return something # to get the result

The function name must follow the rules on variable naming. The parenthesis can contain 0 or more implicitly-defined variables called parameters or arguments. The function body can contain a return statement depending on whether the function generates an output.

Let's examine the calculate_bmi function we created above. It has a name (stating the obvious) and has two parameters (height and weight). It computes the BMI within its body (bmi = weight / height**2) and uses the return keyword to give back the result of the calculation (return bmi). Here's the function again for reference.

def calculate_bmi(height, weight):
    bmi = weight / height**2
    return bmi

Calling a Function

To use (call) a function, write its name and include a parenthesis with or without arguments (or parameters). For example, call the calculate_bmi function like so:

calculate_bmi(1.91, 80)

If the function returns a value, we can (optionally) save the value in a variable.

my_bmi = calculate_bmi(1.91, 80)
print(my_pmi)

Note: Any function that does not explicitly return a value will return None by default.

Function Parameters and Arguments

As earlier stated, parameters/arguments are variables implicitly created based on function definition. They act as the function's inputs.

A function can take multiple parameters as in the calculate_bmi function. Also, a function can have no parameter. For example:

# define a function that takes no argument/parameter
def print_hello_world():
    print("Hello World!")

# call the function
print_hello_world()

One or more arguments can have default values. A function uses the default values if you call it without specifying the argument. For example, sum_num is a function that adds two numbers. By default, those numbers are 5 and 10.

def sum_num(num1 = 5, num2 = 10):
  result = num1 + num2
  return result

We can use sum_num in several ways.

# although no arguments are passed in
# num1 is 5 and num2 is 10. The defaults.
fifteen = sum_num()

# returns 25 since num1 is 13 and num2 is 12
twenty_five = sum_num(13, 12)

# specify num1 (20) and use num2's default value (10)
thirty = sum_num(20)

But wait! How do I specify num2 alone? This question brings us to the concept of positional and named arguments.

Positional and Named (Keyword) Arguments

Let's start by defining a different version of sum_num say sum_num_v2.


# function with 1 positional required argument. 
# num1 and num2 are optional named/keyword arguments
def sum_num_v2(num1, num2 = 5, num3 = 10):
  return num1 + num2 + num3

You can use the return keyword in the same line as the calculation.

We can pass arguments to a function based on the position of the arguments or based on the names (keywords) of the arguments. The function sum_num_v2 has one positional argument num1 and two named arguments num2 and num2. The required position argument num1 must always be in the first position during the function call while the named arguments can either take position 2 or 3. For example

# num1, num2, num3 take their positions - 1,2 and 3 respectively
sum_num_v2(10, 20, 30)

# This is the same as using the positions above
sum_num_v2(10, num2 = 20, num3 = 30)

# The order of num2 and num3 have been switched
# We get the same result as above since
sum_num_v2(10, num3 = 30, num2 = 20)

# we could omit num2 and num3 since they
# have default values.
sum_num_v2(10)

Calling a function without its required arguments throws an error.

# sum_num_v2() # fails :(

In recent Python versions, you can be strict about the number and placement of positional and keyword arguments. For example, consider the describe_me function below:

def describe_me(name, age, city=None, zipcode=None):
  # do nothing
  pass

You can call the function in two ways:

  • with four positional arguments describe_me("Johnny Depp", 1020, "Caribbean", "123456")
  • with two positional and two keyword arguments describe_me("Johnny Depp", 1020, city="Caribbean", zipcode="123456")

What if you wanted to be very specific? You can use \ (positional) and/or * (keyword) to restrict the function's use to a single way like so:


def describe_me(name, age, /, *, city=None, zipcode=None):
  pass

# Fails
# describe_me("Peter Griffin", 48, "Quahog", "00093")
# TypeError: describe_me() takes 2 positional arguments but 4 were given

# works!
describe_me("Peter Griffin", 48, city="Quahog", zipcode="00093")

The first two arguments must be positional arguments while the last two must be keyword arguments. You can't call the function with four positional arguments.

Likewise, you can also restrict a function to use only keyword arguments like so:

def I_dont_take_positions(*, city=None, zipcode=None):
  pass


# Fails
# I_dont_take_positions() takes 0 positional arguments but 2 were given
# I_dont_take_positions("Quahog", "00093")

# works!
I_dont_take_positions(city="Quahog", zipcode="00093")

# works! the order does not matter remember?
I_dont_take_positions(zipcode="00093", city="Quahog")

Return Statement

Earlier, you saw the return keyword in the calculate_bmi, sum_num, and sum_num_v2. These functions did some calculations and used the return statement to give back the results.

# Store the calculation in the result variable
result = sum_num_v2(10, 20, 30)

print(result)

In other cases, you can return nothing (None) from a function if you use the return keyword alone. For example, the calculate_bmi function requires the weight and height parameters. What if they're absent? What if you give strings instead?

One way to defend your function is to return early if the parameters are not valid:


# helper function: check if parameter n is a number 
def is_number(n):
  if isinstance(n, int) or isinstance(n, float):
    return True
  
  return False

# A safer, better version of calculate_bmi

def calculate_bmi_v2(weight, height):
  # Do not calculate BMI if weight or height is not a number
  # return early
  if not is_number(weight) or not is_number(height):
    return 
  
  bmi = weight / height**2
  return bmi
# works well
print(calculate_bmi_v2(68, 1.61))

# returns None
print(calculate_bmi_v2("Hello", 1))

print(calculate_bmi_v2(1, "Hello"))

# returns None
print(calculate_bmi_v2("Hello", "World"))

Note that in the absence of a return statement, a function returns None implicitly.

You can return a single value or multiple values from a function. To do so, separate the return values with a comma. For example, the generate_123 function below returns three different values-1,2,3.


def generate_123():
  return 1, 2, 3

The result of the function call is a tuple containing the values.

one_two_three = generate_123()

print(one_two_three)

You could also unpack the return values individually.

# Use tuple unpacking
one, two, three = generate_123()

print(one, two, three)

You can use the return statement within an if-statement, a for loop, or a while loop. The function will exit. For example:


def contains_only_even_numbers(numbers):
  for num in numbers:
    # If it's an odd number return False
    if num % 2 != 0:
      return False
  
  # If we get here, the numbers parameter contains only even numbers
  return True

outcome = contains_only_even_numbers([2, 4, 6])
print(outcome)  # True

outcome = contains_only_even_numbers([1, 2, 4]) # False
print(outcome)  # False

Built-In Functions

Python provides many functions in its standard library to make development easier.

These functions allow you to perform common operations without writing them yourself. For example, you can replace the functions sum_num and sum_num_v2 with the sum function provided by Python.

numbers = [1, 2, 3, 4, 5]

total = sum(numbers)

print(total) # 15

The table below shows some common Built-In functions:

Function Name Description Example
int Convert a string/float to an integer int(4.8)
float Convert a string/integer to a float float("11.82")
str Convert any type to a string str(1)
type Check the type of a variable/literal type(5)
map Apply a function to every element of a sequence/collection map(your_function, collection)
filter Apply a predicate to a collection filter(your_function, collection)
any Check if any item in a collection is True. Use with map any(map(predicate, collection))
all Check if all item in a collection are True. Use with map all(map(predicate, collection))
enumerate Add indices to a sequence/collection enumerate(numbers)
zip Combine collections zip(numbers, letters)
min Get the minimum value in a sequence/collection min([1,2,3])
max Get the maximum value in a sequence/collection max("xab")
sorted Sort a sequence/collection in a customized way sorted([2, 1, 5], reverse=True)
reversed Reverse the content of a sequence list(reversed([2, 4, 5, 1]))
open Open a file for reading/writing/appending. open("my_file.txt", mode="r", encoding="utf8")
help Provide helpful message on variables, functions, etc. help(print)

A predicate function returns a boolean-True or False

Let's use some of the functions. Start by creating some collections names and numbers

# some names
names = ["John Doe", "Peter Griffin", "Ghost Busters", "Super Mario"]

# numbers 1 - 100
numbers = list(range(1, 101))

map: apply a function to every element of a sequence/collection/iterable (list, tuple, etc.)

Create two functions square and length. square raises a number to power 2. length gives the length of a string.

def square(num):
  return num**2

def length(name):
  return len(name)

Square all the numbers within the numbers list.

squared_numbers = map(square, numbers)

# squared_number is wrapped (a map object)
print(squared_numbers)

# Convert to a list/tuple to view the actual content
squared_numbers = list(squared_numbers)
print(squared_numbers)

Get the length of each name in the names list.

# length names are wrapped (a map object)
length_names = map(length, names)

# Convert to a tuple and view the content
print(tuple(length_names))

# CAREFUL HERE: # tuple is empty because we already used the content
# To avoid this scenario, save the content of the map object.
print(tuple(length_names)) 

The map function returns a map object, a collection that's not evaluated instantly. The operation runs when you use list or tuple on the map object. Note You shouldn't use list or tuple on the same map object twice. Else, the content of the second call will be empty.

Instead of storing and converting a map object, you can loop through its content. For example:

for length_of_name in map(length, names):
  print(length_of_name)

filter: apply a predicate function to each element of an iterable/sequence

Let's say you only want some names. For example, names that have 13 letters or less. Or names that start with the letter P. Use the filter function here.

def less_or_eq_13(name):
  return len(name) <= 13

def starts_with_p(name):
  return name.lower().startswith("p")
names_lte_13 = filter(less_or_eq_13, names)

pnames = filter(starts_with_p, names)

for name in names_lte_13:
  print(name)

# Just like `map`, `filter` returns a filter object that is used only once
# For multiple uses, save the content in a variable
print(list(names_lte_13))

any and all

def is_multiple_of_5(n): return n % 5 == 0

def is_odd(n): return n % 2 != 0

# check if any of the elements is a multiple of 5
mult_5 = any(map(is_multiple_of_5, numbers))
print(mult_5)

# Check if numbers contain only odd numbers
all_odds = all(map(is_odd, numbers))
print(all_odds)

enumerate

enumerate associates an index with each element of collection/sequence. enumerate returns an enumerate object that can be converted to a list of tuples.

indices_and_names = enumerate(names)

# enumerate object
print(indices_and_names)

# Convert to a list and print
print(list(indices_and_names))

Like map objects and filter objects, you can loop through an enumerate object. For example:


for index, name in enumerate(names):
  print(f"{name} is at position {index}")

zip

Using zip, you can combine sequences to create a zip object. Consequently, the zip object can be converted into a list of tuples or used in a for loop.

For example, you can combine the names list with the length_names to have both a name and its length side by side.

# Create a zipped object
names_length_zipped = zip(names, length_names)

# loop through
for name, length in names_length_zipped:
  print(f"{name} has {length} letters")

You can combine the zip step and the for loop.

# Do the above in a single step
for name, length in zip(names, length_names):
  print(f"{name} has {length} letters")

Detour: Implementing the Map and Filter Functions Yourself

The map and filter functions are similar to the map_ and filter_ defined below.

# many people prefer def map_(f, items)
# I chose to write mine in full for demo purposes
def map_(function, items):
  result = []
  for item in items:
    # Call the function and append its output to result
    result.append(function(item))

  return result


# many people prefer def filter_(f, items)
# I chose to write mine in full for demo purposes
def filter_(function, items):
  result = []
  for item in items:
    if function(item):
      result.append(item)

  return result

Note that these functions map_ and filter_ are evaluated immediately. Don't use in real code.

Lambda Functions

If the question "Do I have to define a function each time I use map and filter?" comes to your mind, the answer is NO!

With lambdas you can define a small function where you need it and forget it never existed. Lambdas also provide the following advantages:

  • Lambda functions are nameless. No need to put thought into naming such functions.
  • You won't have to litter your Python script with functions you'll only use once. For example, square, length, is_multiple_of_5, is_odd, less_or_eq_13, and starts_with_p ought to be lambdas.

Excited? How do I create a lambda function?

A lambda function has the following structure: lambda *0_or_more_parameters* : *function body*. No parenthesis or explicit return statement is required. Implicitly, Python returns the result of the expression in the function body.

Let's rewrite some of the lines above using lambdas. First, ditch the square and length functions.

# Initially, you used a square function.
# Replace with a lambda that does exactly the same thing
squared_numbers = map(lambda x: x**2, numbers)

# Convert to a list/tuple to view the actual content
squared_numbers = list(squared_numbers)
print(squared_numbers)

# No need for the length function you created above
length_names = map(lambda name: len(name), names)

# Convert to a tuple and view the content
print(tuple(length_names))

The filter function is next. Let's select only names where the length of the name is less than or equal to 13 using a lambda function.

names_lte_13 = filter(lambda name: len(name) <= 13, names)

pnames = filter(lambda name: name.lower().startswith('p'), names)

print(list(names_lte_13))
print(list(pnames))

How about the any and all?

# check if any of the elements is a multiple of 5
mult_5 = any(map(lambda n: n % 5 == 0, numbers))
print(mult_5)

# Check if numbers contain only odd numbers
all_odds = all(map(lambda n: n % 2 != 0, numbers))
print(all_odds)

An Example: Validate a Full Name

Imagine that your boss says that the name of a user of your application must meet the following requirements:

  • A space should separate first name and last name
  • First name and last name must be an alphabet
  • First name and last name must have at least three letters
  • The function should return True or False
  • The function must have two versions-one that uses a for loop and another that uses map

To get you started, your colleague creates two functions that must print OK! if your code is correct.


def assert_true(result):
  if result is True:
    print("OK!")
    return

  raise ValueError("incorrect!")


def assert_false(result):
  if result is False:
    print("OK!")
    return

  raise ValueError("incorrect!")

Next, your colleague adds the following calls/tests to prove your function works.


# Test for valid names using both versions 1 and 2

assert_true(valid_name("Mark Edosa"))
assert_true(valid_name("Jet Lis"))

assert_true(valid_name_v2("Mark Edosa"))
assert_true(valid_name_v2("Jet Lis"))


# Test for invalid names using both versions

assert_false(valid_name("a b"))
assert_false(valid_name("Mark"))
assert_false(valid_name("abc"))

assert_false(valid_name_v2("a b"))
assert_false(valid_name_v2("Mark"))
assert_false(valid_name_v2("abc"))

Solution

def valid_name(name):

  name_list = name.split()

  if len(name_list) != 2:
    return False
  
  for name in name_list:
    test = name.isalpha() and len(name) >= 3
    if not test:
      return False
    
  return True 


def valid_name_v2(name):
  name_list = name.split()

  if len(list_names) != 2:
    return False
  
  tests = map(lambda name: name.isalpha() and len(name) >= 3, list_names)
  return all(tests)
  

Conclusion

Functions help you organize your code. They also help you express your intentions through appropriate names.

In this article, you learned how to define and use your functions. You learned about function parameters and return statements. You also saw some Built-In functions in action. And you saw how to use lambda functions for one-time-only tasks. Finally, you (hopefully) created a function to meet the requirements of a "real-life" scenario.

Thank you for reading.

(0) (0)
python programming tutorial beginners

Related Posts


  • Introduction to Python Programming - A Word-counter Program sidebar thumbnail
    Introduction To Python Programming - A Word-counter Program
    06 Sep, 2023
  • Introduction to Python Programming - Control Flow sidebar thumbnail
    Introduction To Python Programming - Control Flow
    06 Sep, 2023
  • Introduction to Python Programming - Data Types and Operators sidebar thumbnail
    Introduction To Python Programming - Data Types And Operators
    06 Sep, 2023
  • Introduction to Python Programming - Getting Started sidebar thumbnail
    Introduction To Python Programming - Getting Started
    02 Sep, 2023

Recent Posts

  • Introduction to Python Programming - Function Basics sidebar thumbnail
    Introduction To Python Programming - Function Basics
    06 Sep, 2023
  • Introduction to Python Programming - A Word-counter Program sidebar thumbnail
    Introduction To Python Programming - A Word-counter Program
    06 Sep, 2023
  • Introduction to Python Programming - Control Flow sidebar thumbnail
    Introduction To Python Programming - Control Flow
    06 Sep, 2023

Popular Posts

  • Introduction to Python Programming - Data Types and Operators sidebar thumbnail
    Introduction To Python Programming - Data Types And Operators
    06 Sep, 2023
  • Introduction to Python Programming - A Word-counter Program sidebar thumbnail
    Introduction To Python Programming - A Word-counter Program
    06 Sep, 2023
  • Introduction to Python Programming - Getting Started sidebar thumbnail
    Introduction To Python Programming - Getting Started
    02 Sep, 2023

categories

  • Data Analysis 0
  • Data Visualization 0
  • Data Cleaning and Validation 0
  • Statistical Modeling 0
  • Machine Learning 0
  • Consultation and Training 1

series

  • python programming 1

follow us

tags

  • python
  • programming
  • tutorial
  • beginners
Statogale Logo

Welcome to our Statogale analtytics! We are a team of experts in the field of data analysis, who are dedicated to helping individuals and businesses make informed decisions based on data.

Quick Links

  • Home
  • About
  • Contact
  • Pricing
  • Blog
  • Case Studies

Services

  • consultation & training
  • data analysis
  • data cleaning & validation
  • data visualization
  • machine learning
  • statistical modeling
  • All services

Contact Info

You can reach us via email or phone. You can also engage with us via our social media handles.

  • Email: statogale.da@gmail.com
  • Contact: +2347064964053

© Copyright 2025 Statogale

  • Terms
  • Privacy
  • Support