8.2 Functions in Python
We left variables (Chapter 7) in the Python example so let’s pick up there by adding a function.
First, our test should be passing so check that now.
1poetry run pytest
Once we have passing tests we are ready to refactor our code to introduce a function (remember that during refactoring we are aiming to improve our code without changing what it does; in other words we don’t need new tests, but all existing tests must continue to pass).
Modify the convert.py code as follows.
1import sys 2 3name = sys.argv[1] 4greeting_message = f"Hello {name}!" 5 6 7def display_greeting(greeting): 8 print(greeting) 9 10 11display_greeting(greeting_message)
Once you have saved these changes, rerun the tests to make sure we have broken nothing.
1poetry run pytest
What has this change achieved?
Firstly, and most obviously, it shows the basic form of a function in Python. On line 7 we use the def
keyword1 to tell Python we are about to declare a function. Next we tell Python that we want to label this function display_greeting and this is
followed by a list of parameters this function expects (in this case we expect just one and we tell Python that any value provided for this parameter should be labelled greeting). The function declaration is ended with a colon character.
Following the function declaration we provide the code that is to be labelled display_greeting. In Python the function’s code is indented with respect to the declaration. In this example the function contains a single line of code, line 8. This is just the print
statement from our previous version of the convert.py program but we have replaced
the greeting_message variable with the parameter label greeting.
So that’s the function defined. Defining the function will not print any message though, to do this we must ‘call’ the function, which is what we do on line 11. When we call the display_greeting function we ‘pass’ the content of variable greeting_message as the argument (in Python arguments appear as a comma separated list between parentheses immediately after the name of the function we want to call). This argument value is
assigned to the parameter greeting (just as we might assign a variable, in fact when display_greeting is executed the parameter greeting is a variable within the function code). The code within the function is run and the print
statement outputs the value in variable greeting.
That may seem like a lot of work and all we seem to have done is make our code longer and more complex. However we have added some useful information, specifically that the print
statement is not simply a generic ‘output this string’ but in fact is more specifically displaying a greeting (as indicated by our function’s name display_greeting). In a short program like this
example this may seem unnecessary but trust me this sort of clarity in our code will be vital later.
We can go further. We are currently creating our message using a format string on line 4, which is fine but we can do better. What is this line really doing within our program? It is ‘composing’ the greeting, so let’s make this clear by putting it into a function. Once again, edit convert.py to contain the following.
1import sys 2 3name = sys.argv[1] 4 5 6def compose_greeting(name): 7 return f"Hello {name}!" 8 9 10def display_greeting(greeting): 11 print(greeting) 12 13 14greeting_message = compose_greeting(name) 15display_greeting(greeting_message)
Examples
We are working with examples that emphasis particular coding features! We will be learning how to write better code when we start ‘programming’.
As always, rerun the tests to ensure we have broken nothing.
1poetry run pytest
The new compose_greeting function shows how Python functions can return values using the return
keyword. When compose_greeting is called it will return a value (the greeting string), behaving a little like a variable.
There is one more thing we could do to tidy up our program using functions. Edit convert.py as follows.
1import sys 2 3 4def compose_greeting(name): 5 return f"Hello {name}!" 6 7 8def display_greeting(greeting): 9 print(greeting) 10 11 12def main(command_line_arguments): 13 name = command_line_arguments[1] 14 greeting_message = compose_greeting(name) 15 display_greeting(greeting_message) 16 17 18main(sys.argv)
Hopefully you are now getting used to this next step; rerun the tests to ensure we have broken nothing.
1poetry run pytest
The new main function gathers together all of the code for our new program. The name main is a common convention across programming languages, so if you are looking at unfamiliar code for the first time looking for main is a good starting point2.