#!/usr/bin/env python # coding: utf-8 # ### 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! # # Our next container is the Python **dictionary**. These are denoted by \{ \}. They are somewhat like lists, but instead of integer **indices**, they use alphanumeric (letters and numbers) **keys**: # I love dictionaries. So here is a bit more about them. # # One way to define a **dictionary** is with the curly braces, keys and values syntax like this: # # In[1]: telnos={'lisa':46084,'lab':46531,'jeff':44707} # defines a dictionary of telephone extensions print (telnos) # The keys are 'lisa', 'lab', and 'jeff' and the values are 46084, 46531, and 44707. To return the value associated with a specific key, use square brackets with the key name: # In[2]: print (telnos['lisa']) # 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) # 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 # Or, for a _sorted_ list of keys, you can use **sorted**. # In[6]: print (sorted(telnos.keys())) # Another **list** generator called **values** can be used to generate a list of all the values (duh): # In[7]: print (list(telnos.values())) # 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)])) # 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 common form for a code block starts with a _condition_ statement (if this is _True_) terminated by a colon (:). Most often, this condition statement would be followed by an indented code block that is executed, if the statement is _True_. # # 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: # # - Statements 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. OH, and then take the statement OUT! # # 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 will terminate. # # # 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. # ### "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 (assuming it was run!): 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. # 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[11]: 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") # **in** is another Python _reserved word_ (remember from Lecture 2) that checks if a particular value is "in" a **list** (or **tuple** or **set**): # In[12]: 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 the last if 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") # ### "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[13]: 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) # As a second example of a **for** loop, 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 # 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[15]: # 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'