Session 6: Decision Time#

You will have realised that there has been something a bit awkward in the scripts you have written so far to load data from files into your Python programs - the need to put that extra space character after the item on the last line of the file. You had to do this because in your code you discard the last character in each line as you read it in, because in all but the last line this is the so-called “newline” character (“\n”).

Clearly a better solution would be to write code that checks to see if the line of text ends with a “\n” character, and only strips it off if it does - so in other words, we need to learn how to write Python code that checks a situation, and then makes a decision about what to do, depending on the result. The focus of this session is exactly that.

Task 1#

  1. In a terminal window, navigate to your PHAR2062/Session 6 - Decision Time folder.

  2. Start a Jupyter Notebook session, and create a fresh, empty, notebook.

  3. Copy the following code into it, and then run it:

line = 'Hello\n'
if line[-1] == '\n':
    line = line[:-1]
print(line)

Analysis#

The first line is a simple assignment statement - you know all about these. You have created a string variable called line that has the value ‘Hello\n’.

The second line is new stuff, I’m sure you can easily work out what it’s doing, but let’s pull it apart.

Firstly it starts with if - this is another of the reserved words in Python (remember for ?). Everything after the if up to the colon (:) at the end is an expression. In the middle of the expression is the == symbol - this is another of the operators that you were introduced to in the last session (you met +, -, *, and /). So like those other operators, == takes the thing to its left (line[-1]) and its right ('\n') and does something with them, to create something that has a type, and a value.

The == operator is a binary operator: specifically, a logical comparison operator - it compares the two things and decides if they have the same value, or not. Logically, it can only return something that can take one of two values: either it is “True”, or it is “False”. In Python, the thing that logical operators return is called a Boolean - it has a type called bool, and can only have one of two values, either True or False.

Very importantly, be aware that True and False are two more Python reserved words - they are the two Boolean literals. The capitalization is critical - e.g. True is a reserved word and Boolean literal, but “true” or “TRUE” have no special meaning and could, for instance, be used validly in assignment statements.

We met lines of Python code that ended with : before - in iteration loops. They introduced blocks of code below them that were indented, to signal that they would be executed several - maybe many - times before moving on tho the following lines of unindented code. Here, following if rather than for, the colon introduces one or more lines of intented code that are only executed if the expression has a Boolean value of True; otherwise the program jumps straight to the first unindented line below. These lines of indented code are often called if blocks.

The third line is the only indented line. You can see it’s a simple assignment statement, but of the sort that you have only met a couple of times before, where the same variable appears on both sides of the =. In these situations, the ‘old’ variable is ‘overwritten’ by a new one with the same name, but with a new value.

The fourth line is unindented, so it will be executed whether or not line 2 evaluated to True or False.

Important

Notice that == and = are two very different things in Python! One of the most common errors coders make is to write things like if letter = 'A': when they mean if letter == 'A':


Task 2#

To better appreciate some of the ideas you have just been introduced to, edit the cell of code to look lke this, and re-run:

line = 'Hello\n'
ends_with_newline = line[-1] == '\n'
print(type(ends_with_newline))
print(ends_with_newline)
if ends_with_newline:
    line = line[:-1]
print(line)

Analysis#

In line 2 you see the explicit assignment of the result of a logical comparison to a variable. In line 3 you see that this variable is of type bool, and in line 4 you see how print() displays the value of a Boolean variable - like the corresponding literal. In line 5 you can see how the if word just needs to be followed by something that is, or evaluates to, a bool, in order to work.

Try editing the first line (e.g. to line = 'Hello') and re-running, to see the effect.


Task 3#

Copy the following code into a fresh cell in your notebook, then run it.

mass = 12.0
identity = 'unknown'
if mass == 12.0:
    identity = 'Carbon'
print(identity)

Then try editing the first line to set mass to other values, and re-running it.

Analysis#

You see that the ‘==’ operator can work with operands that are floats as well as strings, and indeed it works with ints too.


Task 4#

Once we are dealing with numbers, other types of logical comparison become relevant - is one thing bigger or smaller than the other?

Edit the code in the cell to match this, and re-run:

mass = 12.0
identity = 'Carbon or lighter'
if mass > 12.0:
    identity = 'Heavier than carbon'
print(identity)

From this is should be fairly obvious what the logical comparison operator > does - play around with editing the value of mass in the first line, to check.


Programming Challenge

Once you feel confident, edit the third line, replacing the > operator with the < operator. You can probably guess what this does, in which case you will have worked out that for it to give correct and useful output, you are going to need to edit the messages in lines 2 and 4 as well. Can you make it work right, whatever number you set mass to?

Once you have cracked this, try to repeat with the logical comparison operators >=, <=, and finally !=.


Task 5#

Programming logic often involves not just doing or not doing something depending on the situation, but on doing one thing in one case, but another thing otherwise. Copy the code below into a fresh call and run it:

mass = 12.0
if mass == 12.0:
    identity = 'Carbon'
else:
    identity = 'unknown'
print(identity)

Analysis#

If line 2 evaluates to True the code in the if block is run, otherwise the code in the else block is run. Notice that this code does exactly the same job as the code in Task 3 - but from a design viewpoint it is more elegant, and maybe easier to understand, because it doesn’t involve first creating a a variable identity with a “guessed” value (of ‘unknown’) and then changing it if neccessary, but rather works out exactly what it should be, and only then creates it.


Task 6#

The code above would be a bit more useful if it could respond to a number of different possible conditions, not just to if one condition was true or not. Edit the code in the current cell as follows to see how:

mass = 12.0
if mass == 1.0:
    identity = 'Hydrogen'
elif mass == 12.0:
    identity = 'Carbon'
elif mass == 16.0:
    identity = 'Oxygen'
else:
    identity = 'unknown'
print(identity)

Analysis#

Here you see how elif blocks work. Importantly, only one of the if, elif or else blocks will ever be run - the first of the if or elif ones whose expression evaluates to True, or otherwise the else block.


Task 7#

To understand the significance of this, edit the code in the curent cell as follows:

mass = 12.0
if mass == 1.0:
    identity = 'Hydrogen'
elif mass == 12.0:
    identity = 'Carbon'
elif mass > 1.0:
    identity = 'Heavier than Hydrogen'
else:
    identity = 'unknown'
print(identity)

Analysis#

Notice that even though the statement in line 6 will evaluate to True, line 7 does not get run - because the statement in line 4 also evaluated to True, and it was tested first. Explore what happens when you change the value of mass in line 1 to make sure you have a full understanding of the logic here.


Programming Challenge 1

Update the program ‘analyze.py’ that you wrote in the last session, so that it no longer requires the last number in the file ‘numbers.txt’ to have a space character after it.

In addition to getting the program to print out the sum of the numbers in the file, write extra code to get it to print out the mean as well.

Stretch Challenge

Mental Floss gives a suggestion for the age ranges that define Gen Z, Millenials, etc. Write a standalone Python program that askes the user to input their age, and then tells them which group they belong to.

Summary#

In this session you have:

  • seen how you can add flow control to a program though the use of if-elif-else blocks.

  • been introduced to a new data type - the Boolean (or bool) that can only be True or False.

  • been introduced to the logical comparison operators ==, <, <=, >=, >, and !=