Review

  • Conditional statements execute code if certain conditions are true.
  • There are three basic forms of conditional code.

This is a plain if statement:

if user == 'Mike' : 
  print "Welcome Instructor."

This is an if/else statement:

if user == 'Mike' :
  print "Welcome Instructor."
else:
  print "Welcome Student."

This is a ladder:

if user == 'Mike' :
  print "Welcome Instructor."
elif user == 'Dan' : 
  print "Welcome Instructor's Brother"   
else:
  print "Welcome Student."

The else is always optional:

if user == 'Mike' :
  print "Welcome Instructor."
elif user == 'Dan' : 
  print "Welcome Instructor's Brother"   
  • In and if/elif/else construction only one of the alternatives is ever run.
  • If there's no else none of the alternatives may be chosen.
  • You can use any Python statements inside of an if block
  • You can use any Python statements in the conditional of an if block.

Using a function as an if conditional:

def is_superuser(username) : 
  if username == 'Mike' : 
    return True
  else:
    return False 
 
def main() :
  program, user = sys.argv 
  if is_superuser(user) : 
    print ('Welcome Administrator')
  • You can combine statements that are logically True or False using logical operators
    • and is True when both inputs are True
    • or is True when either input is True
    • not reverses True and False

Here's an example of using a logical operator in an if statement:

if user == 'Mike' or user == 'root' : 
  print 'Welcome admin.' 

Lists

Here's how to declare a list:

list_var = ['value1', 3, 'Elephant', 'Mike', False, 10.3]
  • Lists can contain any type of variable in Python
    • Including other lists!

Here's a list of lists:

list_of_lists = [ [1, 2, 3], ['Mike', 'Bob', 'Sandy'], ['Lion', 'Tiger', 'Bear'] ] 
  • There are a few important operations on lists
    • We'll talk more about them next week.
    • The append() function adds a value to the back of the list.
    • The pop() function does the opposite of append()
    • The clear() function deletes the contents of the list.
    • The len() function takes a list as an argument and returns the number of elements in the list.

Here's a few examples of list manipulation:

>>> my_list = []
>>> my_list 
[]
>>> my_list.append('Lion') 
>>> my_list 
['Lion']
>>> my_list.append('Tiger')
>>> my_list.append('Bear')
>>> my_list
['Lion', 'Tiger', 'Bear']
>>> my_list.pop()
'Bear'
>>> my_list 
['Lion', 'Tiger']
>>> len(my_list) 
2
>>> my_list.clear()
>>> len(my_list) 
0
  • Strings can be treated as lists of letters.
  • This is useful sometimes when you want to analyze what's in a string.
>>> str = "Hello World" 
>>> str[0] 
'H'
>>> str[1]                                                                                                           
'e'
>>> str[-1]
'd'
  • You can also make lists out of string using the split function.
  • split is a function of a string and takes a delimiter as an argument
    • Without an argument split splits on white space.
  • The delimiter is a letter or string that separates words.

Here's an example of splitting a sentence into words:

>>> "Mary had a little lamb.".split() 
['Mary', 'had', 'a', 'little', 'lamb.']

Here's an example that uses a delimiter:

>>> names = input('Enter names separated by commas: ')
Enter names separated by commas: Mike Matera, Jane Anderson, Rex Tillerson 
>>> names.split(',') 
['Mike Matera', ' Jane Anderson', ' Rex Tillerson ']

Watch out for Whitespace!

Notice that when you split on a delimeter like a comma the list elements contain whitespace. The strip() function will get rid of the whitespce. For example:

>>> list = names.split(',') 
>>> list[1]
' Jane Anderson'
>>> list[1].strip() 
'Jane Anderson'
  • The opposite function of split is join
  • The join function also works on strings, and is a bit counter intuitive.
  • join joins a list using a delimeter.
  • The delimeter is used as the base of the join function.

For example, to join a list with spaces.

>>> list = ['me@me.com', 'you@you.com', 'bob@bob.com'] 
>>> ' '.join(list) 
'me@me.com you@you.com bob@bob.com'
>>> '; '.join(list) 
'me@me.com; you@you.com; bob@bob.com'

Notice that join is a function of string.

The for Loop

  • Lists are interesting to know but you can't really use them until you understand loops.
  • Loops are structures that repeat a block of statements.
  • Loops look a bit like if statements.
  • There are two kinds of loops:
    • Definite loops repeat a known number of times.
    • Indefinite loops repeat an unknown number of times.
  • The for loop is the definite loop in Python.
  • The for loop is perfect for doing something for every item in a list.

Here's a loop that prints the contents of a list:

animals = ['Lion', 'Tiger', 'Bear'] 
 
for animal in animals : 
  print (animal + 's')
 
print ('Oh my!')

Notice some important things about the for loop:

  • The loop runs once for each element in the animals array.
  • The animal variable is created to give access to the element in animals
  • The range() function gives you a range of numbers
  • range() is great when combined with for loops.
for number in range(0, 1) : 
  print ('The number is:', number) 
  • The range() function starts at the first argument.
  • It ends at the last argument minus one.
  • So… range(0, 5) is…
    • [0, 1, 2, 3, 4]
  • For loops are much more convenient in Python than other languages.
    • In most other languages for loops use a numerical index.
    • You can do that in Python too if you like.

Here's an example of how you can use the range() function to make Python's for loop a bit more like C++ or Java:

my_list = ['one', 'two', 'three'] 
 
for i in range(0, 3) : 
  print (f"my_list[{i}] = {my_list[i]}") 

Wait! That code has a problem. Can you spot it? What happens if the list contains more elements? You should make sure you always loop through ever element of the list. You can do that like this:

my_list = ['one', 'two', 'three', 'four'] 
 
for i in range(0, len(my_list)) : 
  print (f"my_list[{i}] = {my_list[i]}") 

That's better. But, there's an easier way in Python to get indexes for lists.

for i, value in enumerate(my_list) : 
  print (f"my_list[{i}] = {value}") 
  • There are many clever uses of a for loop in Python
  • Any function that returns a list can be given to a for loop.
    • For example the readlines() (notice the s!) function on a file returns list of lines
    • Functions like readlines() are very efficient because they don't read the whole file into memory

Here's an example of a function that tests to see if a word is in the dictionary:

def is_word(word) : 
    with open ('/usr/share/dict/words') as d : 
        for dict_word in d.readlines() : 
            if word == dict_word.strip() :
                return True
    return False

The while Loop

  • A while loop is an indefinite loop.
  • Use it when you don't know how many times your loop should run
  • The while loop continues so long as a condition is True
  • When the condition is False the while loop terminates.
  • Your code will have fewer while loops than for loops.
    • But they're still essential.

Here's an example of using a while loop to validate user input:

def get_number() : 
    '''Make the user pick a number between 1 and 100, do not allow invalid numbers.''' 
    number = 0
    while not (number > 1 and number < 100) : 
        number = int(input('Pick a number between 1 and 100: '))
 
    print ('Thanks!')
    return number

The get_number() function won't return until the user chooses a valid number. Here's an example of how it works:

$ python3.6 ./examples.py 
Pick a number between 1 and 100: 0
Pick a number between 1 and 100: -1
Pick a number between 1 and 100: 100
Pick a number between 1 and 100: 99
Thanks!

This code can still fail. How could you add a try/except block to catch the case where the user types something that's not a number?

  • One other common use of a while loop is when you want to do something forever (an infinite loop).
  • Infinite loops are at the heart of every game
  • The will obviously not run forever, but it waits for the user to tell it to exit.

Here's an example of a “game” that uses an infinite loop:

def dice() : 
    while True : 
        command = input('Type "roll" to roll the dice or "quit" to exit: ')
        if command == 'roll' : 
            die1 = random.randint(1, 6)
            die2 = random.randint(1, 6)
            if die1 == 1 and die2 == 1 : 
                print ("The dice say snake eyes!")
            else:
                print (f"The dice say {die1} and {die2}")
        elif command == 'quit' :
            return

List Comprehensions

  • Python has a cool syntax for applying an operation to all members of a list.
  • The syntax is called a list comprehension.

Example: Here's how you would strip whitespace from list elements using a for loop:

names = input('Input a list of names, separated by comma: ')
name_list = names.split(',')
 
for index, name in enumerate(name_list) :
    name_list[index] = name.strip()

A list comprehension gives you a simpler way that's almost as readable:

names = input('Input a list of names, separated by comma: ')
name_list = names.split(',')
 
name_list = [name.strip() for name in name_list]

The form of the list comprehension is:

[ what-to-do-to-each-element for element-name in list-variable ]

  • List comprehensions should be used for simple cases (like stripping whitespace)
  • You can only preform a single operation in a list comprehension
    • More would make them unreadable.

Using ''map()''

  • The map() function is an alternative to using a list comprehension.
  • The use of map() is generally discouraged in favor of list comprehensions
  • The map() function calls a function on every member of a list.

Here's how you would write the code with map:

def my_func(word) :
    return word.strip() 
 
name_list = map(my_func, name_list)
  • This use of map() isn't very useful because you can already strip() easily.
  • map() works best if you want to do something complex enough to warrant a whole new function
  • You can make the map() syntax more complex with a lambda function.
  • Lambda functions are simple functions that can be defined in one line.

Here's an example of map() that's simplified with a lambda function:

name_list = map(lambda name : name.srip(), name_list)

The lambda function is defined as taking an argument x. The code after the colon is the body of the function.