How To Create and Use Python Functions

Python Functions
(Image credit: Pexels)

Functions are incredibly powerful. We use them every day of our lives. When our parents said “clean your room!” We knew what had to be done. Functions are blocks of code that are executed when we call their name. But they can do much more than that. Functions can have arguments (parameters) passed to them, so we could pass a function the latest temperature from a sensor and use the function to trigger a fan to turn on. We could use a function to read the contents of a dictionary and work on the data stored within it.

In this how to. we will introduce the concept of functions and a few of its most powerful features. We will also build a project to read the current status of our PC and provide the data to the Python Shell.

To demonstrate how to use functions in Python, we will use Thonny, a free, easy to use and cross platform Python editor. 

Before you start, Install Thonny if you don’t have it already. You can download the release for your system on the app’s official site.

Alternatively, you can install the official Python release using this guide. Note that this guide covers installation on Windows 10 and 11.

How to Create a Function in Python

(Image credit: Tom's Hardware)

Functions are “defined” using the “def” keyword. When the function name is called, the contents of the function are run and the output is sent to the Python Shell.

1. Create a function called hello. As is tradition in programming, we will use “Hello World” as a quick and simple demonstration of using a function.

def hello():

2. Add a for loop that will iterate (loop) ten times. For loops are an easy way to repeat actions in any programming language. Here we are using a range to set the number of loops, but for loops can also iterate through objects in lists, dictionaries or tuples.

   for i in range(10):

3. Use print to output “Hello World!” to the Python Shell. Print is a built-in function for Python. Its role is to print objects. The message that we want to print is called an “argument” or “parameter” and we will cover this later in the how to.

   print("Hello World!")

4. Save the code as hello_world.py and click Run >> Run Current Script, or press the green run button. What happens? Here is where we make a mistake to reinforce how functions work. Our function has been created, but we have not called the function, so Python is waiting for a command.

5. On a new line, not inside the for loop or function, call the function by its name. Remember to include the parenthesis at the end of the function name.

hello()

6. Click Run >> Run Current Script, or press the green run button. The Python Shell will see “Hello World!” printed ten times.

(Image credit: Tom's Hardware)

Complete Code Listing: A Simple Function

def hello():
    for i in range(10):
        print("Hello World!")
hello()

How to Create a Function With Arguments

(Image credit: Tom's Hardware)

Arguments, sometimes called parameters, are extra instructions to an object. Python’s functions can use arguments, we just need to add them into the parentheses. By default, Python will not look for an argument in a function, we need to set a template / expectation for the function. 

In this section we will alter our “Hello World!” function to accept two arguments. The first is for the number of iterations in a for loop, the second will be for the phrase that we wish to repeat. When specifying arguments we need to ensure that we pass the correct number. If the function specifies two arguments, then we need to pass it two. Failure to do this will cause the function call to error.

1. Create a function called hello and pass it two arguments, x and phrase. We use x as a placeholder for the number of loops, “phrase” is used to represent the message that we want to print.

def hello(x, phrase):

2. Add a for loop that will iterate x times. The number of times that the loop will iterate is controlled using the x argument.

   for i in range(x):

3. Use print to output the “phrase” argument to the Python Shell. Remember, the phrase is set when we call the function.

    print(phrase)

4. On a new line, not inside the for loop or function, call the function by its name and pass the two arguments. The number of times to loop (x) and the message to print. We’ve chosen to loop five times and print Tom’s Hardware. It's not original, but it illustrates the goal of the project.

hello(5, "Tom's Hardware")

5. Save the code as hello_world.py and click Run >> Run Current Script, or press the green run button. The phrase will be printed to the Python Shell for the X number of times that you specified as an argument. 

Complete Code Listing: Functions With Arguments 

def hello(x, phrase):
    for i in range(x):
        print(phrase)
hello(5, "Tom's Hardware")

How To Create a Function With Default and Keyword Arguments

(Image credit: Tom's Hardware)

We’ve passed arguments to our functions, but we can also set a default argument. The default will be accepted and used if the function is passed without a user set argument. Here is a quick example which has a default argument of name. The default name is my own, and it is used in the function to greet the user. All we need to do is pass the name argument to create a new named greeting.

1. Create a function with a default argument of name. Obviously change the name to your choosing.

def whoareyou(name = "Les"):

2. Using the name argument, print a greeting to the user. Here we use Python’s string format method to insert the name argument as a string.

   print("Hello {:s}!".format(name))

3. Call the function with no argument. This should show that the default name is used.

whoareyou()

4. Call the function and pass a new name as an argument. Calling the function happens outside of the function itself.

whoareyou("Dave")

5. Save the code as name.py and click Run >> Run Current Script, or press the green run button. We can see that the code outputs two greetings. One for the default, the other for “Dave”.

Complete Code Listing: Functions With Default Argument

def whoareyou(name = "Les"):
    print("Hello {:s}!".format(name))
whoareyou()
whoareyou("Dave")

(Image credit: Tom's Hardware)

Keyword arguments are useful when we have multiple arguments to pass. In this example we use the classic Mad Libs structure to create a sentence with a noun, verb and thing. The order of the arguments doesn’t matter as we provide the key = value structure.

1. Create a function and configure it to accept three arguments.

def madlibs(noun, verb, thing):

2. Create a sentence that will print the noun, verb and thing to the Python shell. Again we use Python’s excellent string format method to drop the arguments into the sentence.

   print("The {:s} {:s} over the {:s}.".format(noun, verb, thing))

3. Save the code as madlibs.py and click Run >> Run Current Script, or press the green run button.

4. In the Python Shell, call the function and pass the three arguments. Remember to use the key, otherwise the order will be incorrect. Press Enter to run the code. You will see the sentence appear using your custom keywords.

madlibs(noun = "rabbit",verb = "jumped",thing ="gate")

Complete Code Listing: Functions With Multiple Arguments

def madlibs(noun, verb, thing):
   print("The {:s} {:s} over the {:s}.".format(noun, verb, thing))

Using Functions to Get PC Performance Data

To illustrate how to use functions we are going to create a quick Python project that will get live CPU and RAM data using the psutil (process and system utilities) Python module.This module can get data on CPUs, RAM, disks, networks and other sensors, all using Python.

Before we can write any code, we need to install the psutil module.

1. In Thonny, click on Tools >> Manage Packages.

Python Functions

(Image credit: Tom's Hardware)

2. Search for psutil and click Search on PyPi.

(Image credit: Tom's Hardware)

3. Select psutil from the returned results.

(Image credit: Tom's Hardware)

4. Install psutil then close the dialog box when it is complete. We have already installed psutil so our dialog looks a little different.

(Image credit: Tom's Hardware)

5. Create a new file in Thonny and import the psutil module.

import psutil

6. Create a function, cpu(). This function will get the current CPU utilization and store it in a variable. We then print the value to the Python Shell using a string format.

def cpu():
   cpu = str(psutil.cpu_percent())
   print("Current CPU usage is {:s}%".format(cpu))

7. Create a new function, ram(). Use a print statement, along with some math to print a title with ten * either side.This function will handle all of the steps necessary to get the current amount of available memory.

def ram():
   print("*"*10,"RAM Stats","*"*10)

8. Get the current memory stats and store them in a variable called “memory”.

   memory = psutil.virtual_memory()

9. Extract the current amount of available RAM and store it in the variable. The memory object initially returns the total, available, percent, used and free memory. The returned object is a list, and we need the second value in the list, which is [1].

   memory = memory[1]

10. Convert the amount of memory into Megabytes and round the value for ease of reading.

   memory = round(memory / 1024 / 1024)

11. Print the amount of available memory to the Python Shell.

   print("There is {:n}MB of available RAM".format(memory))

12. Create a function called cores(). This function will return the physical core count and the number of threads our CPU has.

def cores():

13. Create objects to store the physical number of CPU cores, and the number of threads. Setting the logical=False argument will force psutil to only return the physical cores.

   physical = psutil.cpu_count(logical=False)
   threads = psutil.cpu_count()

14. Print the physical core count and thread to the Python Shell.

   print("This CPU has {:n} cores and {:n} threads".format(physical, threads))

15. Create a new function, cpuspeed(). Use a print statement, along with some math to print a title with ten * either side.

def cpuspeed():
   print("*"*10,"CPU Stats","*"*10)

16. Store the current CPU speed data to an object called speed. Then extract the current speed and update the object. Initially we get a list which contains a tuple with three values, current speed, min, and max speed. So we need to get data from the first entry in the list [0], then get the first entry in the tuple [0].

   speed = (speed[0][0])

17. Print the speed to the Python Shell.

   print("The CPU speed is {:n} MHz".format(speed))

18. Create a function called all() and use it to call all of the previous functions. Functions can call other functions.

def all():
   cpuspeed()
   cores()
   cpu()
   ram()

19. Create a try / except handler and use while True: to run our code. This section will try to run our code.

try:
   while True:

20. Create an object, stat, and use it to store the user’s choice. We use an input() function to capture keyboard input from the user. We can also create a prompt asking the user for their choice.

       stat = input("Please type 'cpu', 'ram', 'cores', 'cpuspeed' or press ENTER to show all stats: ")

21. Use conditional tests to check the value stored in stat and route the code to the correct option.

       if stat == "cpu":
           cpu()
       elif stat == "ram":
           ram()
       elif stat == "cores":
           cores()
       elif stat == "cpuspeed":
           cpuspeed()

22. Use else as a catch all option that will call the all() function and show every stat that we have a function for.

       else:
           all()

23. Create an exception to handle the user pressing CTRL+C to end the code. This will print Exiting to the Python Shell.

except KeyboardInterrupt:
   print("Exiting")

24. Save the code as performance.py  and click Run >> Run Current Script, or press the green run button. You will see the Python Shell ask for your input. Follow the guidance and your requested data will display in the Shell.

(Image credit: Tom's Hardware)

Complete Code Listing: Using Functions to Get PC Performance Data

import psutil
def cpu():
   cpu = str(psutil.cpu_percent())
   print("Current CPU usage is {:s}%".format(cpu))
def ram():
   print("*"*10,"RAM Stats","*"*10)
   memory = psutil.virtual_memory()
   memory = memory[1]
   memory = round(memory / 1024 / 1024)
   print("There is {:n}MB of available RAM".format(memory))
def cores():
   physical = psutil.cpu_count(logical=False)
   threads = psutil.cpu_count()
   print("This CPU has {:n} cores and {:n} threads".format(physical, threads))
def cpuspeed():
   print("*"*10,"CPU Stats","*"*10)
   speed = psutil.cpu_freq([1])
   speed = (speed[0][0])
   print("The CPU speed is {:n} MHz".format(speed))
def all():
   cpuspeed()
   cores()
   cpu()
   ram()
try:
   while True:
       stat = input("Please type 'cpu', 'ram', 'cores', 'cpuspeed' or press ENTER to show all stats: ")
       if stat == "cpu":
           cpu()
       elif stat == "ram":
           ram()
       elif stat == "cores":
           cores()
       elif stat == "cpuspeed":
           cpuspeed()
       else:
           all()
except KeyboardInterrupt:
print("Exiting")

More Python Tutorials

Les Pounder

Les Pounder is an associate editor at Tom's Hardware. He is a creative technologist and for seven years has created projects to educate and inspire minds both young and old. He has worked with the Raspberry Pi Foundation to write and deliver their teacher training program "Picademy".

TOPICS
  • Li Ken-un
    Not 100% the same, but much terser while not overly dense: 🙂

    from operator import call
    from psutil import cpu_count, cpu_freq, cpu_percent, virtual_memory

    funcs = {
    'cpuspeed': lambda: f"The CPU speed is {cpu_freq():,} MHz.",
    'cores': lambda: f"This CPU has {cpu_count(False):,} cores and {cpu_count():,} threads.",
    'cpu': lambda: f"Current CPU usage is {cpu_percent():,}%.",
    'ram': lambda: f"There is {round(virtual_memory() / 1024 ** 2):,} MB of available RAM."
    }
    combined_funcs = lambda: '\n'.join(call(func) for func in funcs.values())
    try:
    while True:
    func_to_call = funcs.get(input("Please type 'cpu', 'ram', 'cores', 'cpuspeed' or press ENTER to show all stats: "), combined_funcs)
    print(call(func_to_call))
    except KeyboardInterrupt:
    print("Exiting…")
    Reply
  • bit_user
    Another Python article; more missed opportunities. This time:
    storing & passing functions as variables & parameters
    lamdas (as @Li Ken-un demonstrated)
    packed argument lists
    higher-order functions: filter(), map()
    member functions & static member functions (though, I don't know if you've yet introduced objects)
    curring (i.e. function argument binding)
    Here's a simple example demonstrating several of those techniques:
    add = lambda x, y: x + y
    print( "add( 7, 9 ) =", add( 7, 9 ), "\n" )

    def curry_first( f, first ):
    return lambda *args: f( first, *args )

    add_1 = curry_first( add, 1 )
    for i in map( add_1, ):
    print( i )
    Output:
    add( 7, 9 ) = 16

    2
    3
    4
    Explanation:
    lambda is used to define an unnamed function. In this case, a lambda with 2 arguments is defined which simply adds them.
    The variable add is defined to hold this lambda, which effectively turns it into a function.
    To demonstrate this, it's used to add 7 and 9.
    Next, the curry_first() function is used to bind a value of 1, for the first argument of add. The resulting function takes only a single argument and adds 1 to it.
    Now, we use the map() builtin function to apply add_1() to each element in the list .
    This is done in a for loop, so the resulting value can be printed. I could've used a list comprehension to print the result in one shot, but I figure the example is already terse enough.
    Reply
  • Li Ken-un
    bit_user said:
    def curry_first( f, first ):
    return lambda *args: f( first, *args )
    curry_first is just partial from functools. 😉

    from operator import add
    from functools import partial

    add_1 = partial(add, 1)

    print(f"add( 7, 9 ) = {add( 7, 9 )}\n" )
    for i in map(add_1, ):
    print(i)from operator import add
    from functools import partial
    from toolz import compose

    add_1 = partial(add, 1)

    print(f"add( 7, 9 ) = {add( 7, 9 )}\n" )

    add_1_and_print = compose(print, add_1)

    for i in :
    add_1_and_print(i)

    There are some additional imports that go very well with the stuff in functools, including itertools and operators. I recommend toolz which provides even more constructs like compose and pipe without having to define them yourself in every project/script.
    Reply
  • bit_user
    Li Ken-un said:
    curry_first is just partial from functools. 😉
    I figured there must be a module for doing it, but I thought it was more instructive to see a trivial example of how to actually implement it.

    For real world use, I'd definitely recommend people use functools or whatever seems the most polished implementation.
    Reply