This post follows on from my earlier posts Coding 101 (part 1) and (part 2), and is my responses and learnings from the highly-recommended Python programming book and course by Charles Severance (see References below).
Functions:
Functions are sections of code (a sequence of executable steps) which we want to be able to use and re-use at many points in our program. It may be that we want to read and process a whole range of data over and over (but the process done to all the data is the same) or maybe there are a number of inputs required from the user which all need to be processed the same way. Rather than rewriting the same lines of code again and again in our program, we can give that section of code a name (known as ‘defining the function’). We can then ‘call’ that named function, that is, ask Python to execute the defined sequence of steps, at any future point within our program, and as many times as we want. (In other programming languages this same functionality may be referred to as sub-programs or sub-routines.)
To define a function, we use the reserved word def. and we can name the function anything we wish as long as it’s not a reserved word (we should also bear in mind earlier points about sensible naming conventions). The required syntax to define a function is:
def function_name():
- x = x + 1
- print x
Note the ‘define’ command ends with the colon and that Python also requires us to indent the sequence of steps we wish to define under the label function_name. All the steps indented after the def command will be recorded as the sequence of steps within that named function. When we call that function later in the program, all those indented steps will be executed. To call the function, the correct syntax is:
function_name()
Built-in functions:
Python includes a number of built-in functions which we can include in our program as one-line commands but which Python recognises as pre-defined executables; these are sub-programs that have already been written into Python itself. Some examples that we’ve already seen are the type functions such as float(), type(), int() and the input function raw_input(). Python also includes a number of the common mathematical functions, e.g. the square root function, sqrt().
Documentation on built-in functions is available here: https://docs.python.org/2.7/library/functions.html.
Function arguments:
We may define a function to perform some executable code or other computation (the sequence of code indented after the def command). We may also wish to specify arguments for the function within the parentheses – these are values which get passed to the function as inputs which will undergo some kind of computation as the function is executed. We can think of the argument as the input, the function itself is some kind of process being run on that input, and the result is the output from the function.
def function_name(‘argument’):
- #this is the first line of the function
- #this is the second line of the function
Multiple arguments:
We can define a function to take any number of arguments, simply by separating them with commas in the parenthesis.
def function_name(‘argument1′,’argument2’):
- #this is the first line of the function
- #this is the second line of the function
Evaluation and assignment of functions:
The built-in functions can be used both for evaluation (evaluate an argument using the function) and for assignment (assigning the outcome/result of the function evaluation to some named variable):
largest = max(‘Hello world’)
print largest
smallest = min(‘Hello world’)
print smallest
In the example above the built-in functions max and min have both been applied to the string argument ‘Hello world’ and the output from the evaluation of each function has been assigned respectively to the variables called ‘largest’ and ‘smallest’.
Note that, since the argument is a string not a numeric, the functions max and min will evaluate the argument for the character within the string carrying the highest/lowest value alphabetically.
Function parameters:
Passing arguments as inputs into a function is a useful tool, as it allows us to define a function once, then call that function over and over again while passing in different arguments – i.e. the same process will be executed but each time using different inputs, giving a different output each time. The way to do this is using a parameter.
A parameter is a variable which we can specify when defining the function which allows us to pass in various different arguments into that parameter. Then each argument (input) will be computed by the function leading to a different output. Effectively, this is setting up the function to contain a variable, making it far more flexible. For example:
def payment(payment_type):
- if payment_type == ‘inv’:
-
- print ‘Invoice’
- elif payment_type == ‘cc’:
-
- print ‘Credit Card’
- else:
-
- print ‘Cash’
payment(‘inv’)
Here we defined and called the function ‘payment’ with the argument ‘inv’ plugged into the parameter ‘payment_type’. This resulted in the function returning the output ‘Invoice’. Note that we can pass in any argument into the parameter ‘payment_type’ and the function will execute according to the argument passed in.
Function return:
We can set the function to ‘return’ the value it has just evaluated, using the reserved word return in the function definition. In this case, when we call the function, it evaluates it and returns that evaluated value at that point in the program where the function has been executed. This allows the returned value to be further combined within other expressions at that point. The returned value can either be a string or a numeric, dependent on the arguments and function being executed.
def payment(payment_type):
- if payment_type == ‘inv’:
-
- return ‘Invoice’
- elif payment_type == ‘cc’:
-
- return ‘Credit Card’
- else:
-
- return ‘Cash’
print ‘Payment type:’, payment(‘inv’)
(This outputs the string ‘Payment type: Invoice’.)
Multiple parameters:
Just as we can pass more than one argument into a function, so too can we define a function to take any number of parameters, into which we will later pass the corresponding number of multiple arguments. Again, we separate the different paratemeters with commas in the parenthesis. The number and order of parameters and the number and order of arguments being passed into them must correspond.
def addthem(‘parameter1′,’parameter2’):
- sumofparameters = parameter1 + parameter2
- return sumofparameters
x = addthem(6,9)
print x
(This outputs the value of x, 15 [6+9].)
Looping the loop:
We’ve already seen a few different programming structures which allow us to do deal with conditional problems, where we can perform different actions or computations dependent on the answer of a given question. Now we want to look at loops, another very useful programming structure which lets us perform some kind of action over and over again, until we reach some kind of end condition. Computers don’t get bored the way we do, so it’s a great way to use computers to do the really boring, repetitive stuff.
Loops are constructed using the reserved word while, and are similar to a conditional if/else, in that there is some kind of variable (called the iteration variable) which gets tested at each entry point to the loop. If the variable condition is met (YES or TRUE) then some sequence of code is performed, and the loop repeats itself coming back to the start of the loop each time. So long as that variable condition continues to be met, so the loop will keep on performing over and over. As soon as the variable condition is no longer met (NO or FALSE) the loop ends and the rest of the program continues on.
Think of it like eating a tub of icecream with icecream being the iteration variable. While there’s icecream in the tub we just keep on digging our spoon in and scooping out that yummy dessert, until there’s no more icecream left at which point we’ll just have to stop eating.
As with conditionals, Python syntax requires the while statement to be suffixed with a colon, and for the loop section to be highlighted using indenting. The form of the looping structure looks like this:
vol = 100
print ‘Yummy, icecream’
while vol > 0 :
- print ‘Eat icecream!’
- vol = vol – 10
print ‘All gone! Boo-hoo!’
By setting the iteration variable to a numerical variable, and subtracting some amount from it each time it passes through the loop – with the condition at the start of the loop being dependent on the iteration variable either meeting some numerical condition or not – allows us to construct a loop which happens for a while, but will stop at some point when the variable gets to zero (e.g. when vol = 0, representing all the icecream eaten up).
Breaking the loop:
We may want to set up some additional condition which allows us to break the loop, to stop it running, even through it might otherwise have continued on. To continue our above example, we may get full up and just can’t eat any more icecream, even though we haven’t eaten the whole tub yet. We can set a further conditional command inside the loop which allows us to test some other variable; it may even be a user-entered response to the question “Do you wish to continue?”
vol = 100
while vol > 0 :
- full = raw_input(‘full or not full?’)
- if full == ‘full’ :
-
- break
- print ‘Eat icecream!’
- vol = vol – 10
print ‘That is all!’
Infinite loops with break conditions:
An alternative way to construct a loop is to automatically make it run indefinitely (to make it an infinite loop) using the expression:
while true :
Here then we absolutely need to add some way to break out of the loop or stop it running. So we can use the break construct we saw above; this will cause the loop to run indefinitely unless or until the break condition is met. The break construct above used a raw_input to get some kind of user input and test it, but the input could be read in through other means (which we’ll delve into more later).
Continue:
We might want to use a break function which just stops this one iteration from happening, but doesn’t throw us out of the loop altogether. For this we use the continue command. Working this into our icecream example might be, we need to stop temporarily and answer the ‘phone, but we don’t want to stop eating icecream altogether.
vol = 100
while vol > 0 :
- phone = raw_input(‘phone or no phone?’)
- if phone == ‘phone’ :
-
- continue
- full = raw_input(‘full or not full?’)
- if full == ‘full’ :
-
- break
- print ‘Eat icecream!’
- vol = vol – 10
print ‘That is all!’
Definite vs. indefinite loops:
All three kinds of loop above are known as indefinite loops, that is a loop which is will continue to run unless some condition is met which stops them. In the first case, the end condition was instigated by using an iteration variable which decreased in number forcing the loop to be executed for x number of times only and then stopping. In the second case, a break clause was added to the loop, such that another variable was tested and, when it met a certain condition, the loop was exited out of. In the third case, a continue clause was introduced, which again had some test variable and test condition, which when met caused the program to jump out of that iteration and go back to the start of the loop and carry on.
We can also construct a definite loop, a loop which runs a pre-defined number of times (iterations) based on some pre-defined set of entrants into the loop. An example might be where we enter a list of data with say 10 items in that list. The loop executes on each piece of data in the list, so it executes for 10 iterations, and then stops. Alternatively, we might be entering data from a file and have the loop execute some code on each of those data items entered from the file.
A definite loop is constructed using the reserved word for, lists which are denoted using square brackets with each item in the list separated by a comma. As before, we need an iteration variable, which takes successive values from the given list and, for each value of the iteration variable, the loop is run until the list is exhausted and there are no more values left which the variable can take.
for x in [1, 2, 3] :
- print x
print ‘The end’
The construct is “for {iteration variable} in {list}” where in is the reserved word which causes the loop to move sequentially through the list (the list can be thought of as an ordered set in mathematical terms).
A brief intro to lists:
Using for to loop through all the elements in a list is very powerful. It can handle either numeric and string data points. We might want to construct the list first and give it a name, and then run the for loop on that named list. Here the example handles a list of strings (note each string needs to be contained in single quotes, but all other list syntax is the same as with numerics) which it calls word_list. The iteration variable in the for loop is word, and word scrolls through all the strings in word_list and the loop is executed for each one before ending.
word_list = [‘first’, ‘second’, ‘third’]
for word in word_list :
- print word
print ‘The end’
Applications of loops:
We might have any number of different functions we want to be able to do (as related to a list of items), like searching/filtering/sorting, finding the largest or smallest item, counting number of items, summing or averaging all the items, finding a specific item from a list, or any other kind of repetitive task applied to a list. In each case there’s a sequence of code which the program will need to execute over and over – the internal workings of the loop – which we don’t need to see, but which needs to happen for us to get the required result out at the end.
Special variables and operators:
There are a couple of useful special variables and operators we can employ in Python to help make more complex sorting, grading or sizing loops more elegant and less prone to errors. For example, we might use an initial placeholder value as our ‘largest’ variable, then scroll through all the items in the list comparing them to the original placeholder variable to see which is largest, and if so setting that new value as the largest. But if we’re not sure what the smallest value in the list is, how will we know which value is safe to set as our initial placeholder value for the variable ‘largest’?
To overcome this we can use the special variable None, which is neither a string nor an integer type, but rather it’s own special type which effectively means null or empty (i.e. there is nothing in the variable ‘largest’ at the start). We can then sort and categories accordingly. The None variable can be similarly employed when sorting through a list to find the smallest value, by setting the initial value in the variable ‘smallest’ as None (i.e. there is nothing in the variable ‘smallest’ at the start). (Note that None is always capitalised in Python.)
To assign the value None to the variable, use the standard assignment statement:
largest = None
You can test at any relevant point if the value in a variable is None or not, you would use one of the special operators is or is not. For example:
largest = None
if largest is None :
- print ‘There is no value in the variable largest’
elif largest is not None :
- print ‘The variable largest does contain some value’
You would use is and is not in specific cases when checking if the value in a variable is a special variable like None, or one or the two Boolean variables: True or False. It can be taken to mean “is the type and value the same as”; because it is checking both the value and the type (string, integer, special) it is a stronger equality statement than the normally-used “x == 4”.
References
Book: Programming for Informatics – Exploring Information by Charles Severance
Course: Programming for Everybody (Getting Started with Python) by Univ. of Michigan. Part of the Python for Everybody specialisation.