Lecture 4:

  • Learn more about another useful data structure, dictionaries and some of their methods

  • Introduce special Python code blocks

  • Learn about "for" loops, "while" loops and "if" blocks

Dictionaries!

Dictionaries are denoted by { }. They are also somewhat like lists, but instead of integer indices, they use alphanumeric keys: I love dictionaries. So here is a bit more about them.

Here is one way to define one:

In [1]:
telnos={'lisa':46084,'lab':46531,'jeff':44707} # defines a dictionary of  telephone extensions
print (telnos)
        
{'lisa': 46084, 'lab': 46531, 'jeff': 44707}

To return the value associated with a specific key, use square brackets with the key name:

In [2]:
print (telnos['lisa'])
46084

To change a key's value:

In [3]:
telnos['lisa']=40684

To add a new key and value:

In [4]:
telnos['newguy']=48888
print (telnos)
{'lisa': 40684, 'lab': 46531, 'jeff': 44707, 'newguy': 48888}

Like the other containers we learned about in Lecture 3, dictionaries also have methods.

One useful one can generate a list of all the keys:

In [5]:
print(list(telnos.keys())) # returns an unordered list of the keys
['lisa', 'lab', 'jeff', 'newguy']

Or, for a sorted list of keys, you can use sorted.

In [6]:
print (sorted(telnos.keys()))
['jeff', 'lab', 'lisa', 'newguy']

Another one can be used to generate a list of all the values:

In [7]:
print (list(telnos.values()))
[40684, 46531, 44707, 48888]

There are other ways to create dictionaries. The dict( ) constructor can make a dictionary directly from a list containing key-value tuples:

In [8]:
print (dict([('jeff',44707),('lisa',46084),('lab',46531)]))
{'jeff': 44707, 'lisa': 46084, 'lab': 46531}

For a more complete description of dictionaries, see:

http://docs.python.org/tutorial/datastructures.html#dictionaries

Code blocks

We are about ready to start writing a "real" program. First we need to talk about the structure of a python program and the concept of the 'code block'.

Every programming language provides a way to group blocks of code together and execute them under certain conditions. Python uses indentation to define the code blocks and this also makes the code more readable.

A code block could start with a condition statement (if this is True) terminated with a ':'

A typical Python program looks like this:

program statement

block 1 condition statement:

block 1 statement

block 1 statement \

     Break in the indentation convention!

block 1 statement

block 2 condition statement:

    block 2 statement

    block 2 statement

    block 3 condition statement:

        block 3 statement

        block 3 statement

        block 4 condition statement: block 4 single line of code

    block 2 statement

    block 2 statement

block 1 statement

block 1 statement

program statement

Exceptions to the code indentation rules are:

  • Any statement can be continued on the next line with the continuation character $\backslash$ and the indentation of the following line is arbitrary. In Python 3, the backslash is not always required, but it is certainly recommended (by me) for clarity.

  • If a code block consists of a single statement, then that may be placed on the same line as the colon (see block 4 above).

  • The command "break" breaks you out of the code block. Use with caution!

  • There is a cheat that comes in handy when you are writing a complicated program and want to put in the code blocks but don't want them to DO anything yet: the command pass does nothing and can be used to stand in for a code block.

TIP: Use only spaces or only tabs to indent your code. Jupyter notebooks try to guess what you want and will indent for you, for example, after a statement terminating in a colon.

Whatever you do BE CONSISTENT because tabs are not the same as spaces in Python. Even if you can't tell the difference just by looking at it, Python knows and will complain about it!

Conditional statements

Conditions statements are statements like: "x is greater than y", which evaluate to either True or False.

In Python we would use a relational operator > for the "is greater than" test so the question "is x is greater than y?" is written: x>y

We already encountered a few relational operators in Lecture 2, but here is a more complete list of those that are frequently used in condition statements:

"==" means "equals"; A==B (Does A equal B?)

"!=" means "does not equal"; A!=B (Is A not equal to B?)

"<" means "less than"

"<=" means "less than or equal to"

">" means "greater than"

">=" means "greater than or equal to"

Conditions (like A==B) can be combined with and or or to make complex tests. For example ((A==B) and (C!=D)). Both have to be true for the condition to evaluate as True.
Alternatively for ((A==B) or (C!=D)), only one has to be true for the condition to evaluate as True.

"while" loops

The while loop executes a code block while some condition is True.

TIP: Be VERY CAREFUL with these as they will go on and on and on and on if the condition stays True. For example the statement while 1: will always be True and would be a very dangerous condition statement to make. If that happens to you, just save your notebook and select "Close and Halt" under "File" and restart your notebook.

Let's practice making a code block using a while loop. We will set a variable $N$ to some number (100) and decrement $N$ by 1 until it reaches a threshold (90). When $N$ is no longer greater than the threshold, the code block terminates.

In [9]:
N=100 # define the variable N to be 100
threshold=90 # define some threshold to be 90

# while the condition in the () is True, the program will continue
while (N > threshold):  # is N greater then threshold?  if so, execute the indented code block
    print (N)  # what it says
    N-=1  # decriment N by one
print ('and the final value is: ',N) # now we're done we'll see what is left of N.
100
99
98
97
96
95
94
93
92
91
and the final value is:  90

"if" statements

In an if statement, the code-block is executed (once) if the condition is true.

Here is a simple if statement:

In [10]:
# We can re-use N which was used in an earlier script:
if (N < 100): # Is N less than 100?  
    print ("where did N go?") # if so, print this.   
# if not - you need to re-execute the while loop above this one.  
 
where did N go?

There are additional conditions that you can include in the if statements. In Python these are: elif (short for "else if") which means if the first if statment is False, but the statement following elif is True, then do something. Another is else, which means "otherwise".

Consider these examples:

In [14]:
latitude  = 32.7 # define a variable 'latitude'

if (latitude < 24): 
    print("Tropical region")
elif (latitude> 24 and latitude < 66):
    print("Temperate region")
else:
    print("Polar region")
Temperate region

in is a Python reserved word (remember from Lecture 2) that checks if a particular value is "in" a list (or tuple or set):

In [11]:
mylist=['jane','josh','sid','geoff'] # define a list
if 'susie' in mylist:  # if the string "susie" is in the list, then 
    pass # don't do anything
if 'susie' not in mylist:
    print ('call susie and apologize!')
    mylist.append('susie')
elif 'george' in mylist: # if first statement is false, try this one
    print ('susie and george both in list') 
else: # if both statements are false, do this:
    print ("susie in list but george isn't")
call susie and apologize!

"for" loops

The for loop allows you to step through a list (or tuple, among other things) sequentially. It assigns the first element to a variable name, say, $x$, perform some operation on it and then return to the top of the loop and assign the next element to the same variable name.

For example, if we have a list $L = [1,2,3]$, this loop will assign each element in $L$ to the variable $x$, square it, and then print the result.

In [1]:
L = [1,2,3] # define the list 'L'


# step through the list assigning each element to the variable, x
for x in L: # x is assigned to each element in turn
    print (x, x*x ) # or we could have written print (x**2)
1 1
2 4
3 9

As a second example, we can use the list generated by the dictionary method dict.keys():

In [14]:
# print out the list generated
print ('List of keys in telnos: ',list(telnos.keys() )) # here you need the list() function
# notice the slightly fancier form of the print statement above.

# now step through that list, 
   # assigning each element to the variable key
for key in telnos.keys():  # just use the list generator (we don't need the list() function)
    print (key) # print out the variable, key
List of keys in telnos:  ['lisa', 'lab', 'jeff', 'newguy']
lisa
lab
jeff
newguy

What just happened? The for statement assigned each element in the list generated by the method telnos.keys( ) to the variable key and then printed each element out. The for statement loops through the entire list one element at a time.

Nested loops

You can build a series of loops within loops (nested loops).

Remember that everything within an indented code block is executed completely before moving on to the next code block.

In [5]:
# define a dictionary of telephone extensions:
telnos={'lisa':46084,'lab':46531,'jeff':44707}
keys=telnos.keys() # make a list generator of the dictionary keys
busy=True # define the boolean 'busy' as True
# step through the list generator of the dictionary keys, 
# assigning each key to the variable 'key'
for key in keys:
    print (key) # print the variable 'key' (the name)
    num=telnos[key] # assign the value of the key (the telephone number) to 'num'
    if num == 46084: # conditional statement, if the number is 46084, then
        # print the message identifying the key that this value belongs to
        print (key,"'s number") 
        while busy: # If 'busy' is still 'True', then print the message "she's on the phone"
            print ("she's on the phone")
            busy=False # set 'busy' to 'False'
            
lisa
lisa 's number
she's on the phone
lab
jeff