University of Maryland GRADMAP
Winter Workshop Python Boot Camp

More Data Structures, Control Statements,
Functions, and Modules

Sets


In [1]:
{1,2,3,"bingo"}


Out[1]:
{1, 2, 3, 'bingo'}

In [2]:
type({1,2,3,"bingo"})


Out[2]:
set

In [3]:
type({})


Out[3]:
dict

In [4]:
type(set())


Out[4]:
set

In [5]:
set("spamIam")


Out[5]:
{'I', 'a', 'm', 'p', 's'}

Sets have unique elements. They can be compared, differenced, unionized, etc.


In [6]:
a = set("sp"); b = set("am"); print a ; print b


set(['p', 's'])
set(['a', 'm'])

In [7]:
c = set(["a","m"])

In [8]:
c == b


Out[8]:
True

In [9]:
"p" in a


Out[9]:
True

In [10]:
"ps" in a


Out[10]:
False

In [11]:
q = set("spamIam")
a.issubset(q)


Out[11]:
True

In [12]:
a | b


Out[12]:
{'a', 'm', 'p', 's'}

In [13]:
q - (a | b)


Out[13]:
{'I'}

In [14]:
q & (a | b)


Out[14]:
{'a', 'm', 'p', 's'}

Like lists, we can use as (unordered) buckets .pop() gives us a random element


In [15]:
# this is pretty volitile...wont be the same
# order on all machines
for i in q & (a | b):
    print i,


a p s m

In [16]:
q.remove("a")

In [17]:
q.pop()


Out[17]:
'p'

In [18]:
print q.pop()
print q.pop()


s
m

In [19]:
print q.pop()


I

In [21]:
# q.pop()

 

Dictionaries

denoted with a curly braces and colons


In [22]:
d = {"favorite cat": None, "favorite spam": "all"}

these are key: value, key: value, ...


In [23]:
print d["favorite cat"]
d[0]   ## this is not a list and you dont have a keyword = 0


None
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-23-4c140b3c911c> in <module>()
      1 print d["favorite cat"]
----> 2 d[0]   ## this is not a list and you dont have a keyword = 0

KeyError: 0

In [24]:
e = {"favorite cat": None, "favorite spam": "all", \
     1: 'loneliest number'}
e[1] == 'loneliest number'


Out[24]:
True

dictionaries are UNORDERED*.

You cannot assume that one key comes before or after another

* you can use a special type of ordered dict if you really need it:

http://docs.python.org/whatsnew/2.7.html#pep-372-adding-an-ordered-dictionary-to-collections

4 ways to make a Dictionary


In [25]:
# number 1...you've seen this
d = {"favorite cat": None, "favorite spam": "all"}

In [26]:
# number 2
d = dict(one = 1, two=2,cat = 'dog') ; print d


{'cat': 'dog', 'two': 2, 'one': 1}

In [27]:
# number 3 ... just start filling in items/keys
d = {}  # empty dictionary
d['cat'] = 'dog'
d['one'] = 1
d['two'] = 2
d


Out[27]:
{'cat': 'dog', 'one': 1, 'two': 2}

In [28]:
# number 4... start with a list of tuples
mylist = [("cat","dog"), ("one",1),("two",2)]
print dict(mylist)


{'one': 1, 'two': 2, 'cat': 'dog'}

In [29]:
dict(mylist) == d


Out[29]:
True

 

Dictionaries: they can be complicated (in a good way)


In [30]:
d = {"favorite cat": None, "favorite spam": "all"}

In [31]:
d = {'favorites': {'cat': None, 'spam': 'all'}, \
     'least favorite': {'cat': 'all', 'spam': None}}
print d['least favorite']['cat']


all

remember: the backslash () allows you to across break lines. Not technically needed when defining a dictionary or list


In [32]:
phone_numbers = {'family': [('mom','642-2322'),('dad','534-2311')],\
                     'friends': [('Sylvia','652-2212')]}

In [33]:
for group_type in ['friends','family']:
        print "Group " + group_type + ":"
        for info in phone_numbers[group_type]:
             print " ",info[0], info[1]


Group friends:
  Sylvia 652-2212
Group family:
  mom 642-2322
  dad 534-2311

In [34]:
# this will return a list, but you dont know in what order! 
phone_numbers.keys()


Out[34]:
['friends', 'family']

In [35]:
phone_numbers.values()


Out[35]:
[[('Sylvia', '652-2212')], [('mom', '642-2322'), ('dad', '534-2311')]]

 

.keys() and .values(): are called methods on dictionaries


In [36]:
for group_type in phone_numbers.keys():
        print "Group " + group_type + ":"
        for info in phone_numbers[group_type]:
             print " ",info[0], info[1]


Group friends:
  Sylvia 652-2212
Group family:
  mom 642-2322
  dad 534-2311

we cannot ensure ordering here of the groups


In [37]:
groups = phone_numbers.keys()
groups.sort()
for group_type in groups:
        print "Group " + group_type + ":"
        for info in phone_numbers[group_type]:
             print " ",info[0], info[1]


Group family:
  mom 642-2322
  dad 534-2311
Group friends:
  Sylvia 652-2212

.iteritems() is a handy method, returning key,value pairs with each iteration


In [38]:
for group_type, vals in phone_numbers.iteritems():
        print "Group " + group_type + ":"
        for info in vals:
             print " ",info[0], info[1]


Group friends:
  Sylvia 652-2212
Group family:
  mom 642-2322
  dad 534-2311

Some examples of getting values:


In [39]:
phone_numbers['co-workers']


---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-39-92d1a5b9b960> in <module>()
----> 1 phone_numbers['co-workers']

KeyError: 'co-workers'

In [40]:
phone_numbers.has_key('co-workers')


Out[40]:
False

In [41]:
print phone_numbers.get('co-workers')


None

In [42]:
phone_numbers.get('friends') == phone_numbers['friends']


Out[42]:
True

In [43]:
print phone_numbers.get('co-workers',"all alone")


all alone

 

 

setting values

you can edit the values of keys and also .pop() & del to remove certain keys


In [44]:
# add to the friends list
phone_numbers['friends'].append(("Jeremy","232-1121"))
print phone_numbers


{'friends': [('Sylvia', '652-2212'), ('Jeremy', '232-1121')], 'family': [('mom', '642-2322'), ('dad', '534-2311')]}

In [45]:
## Sylvia's number changed
phone_numbers['friends'][0][1] = "532-1521"


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-45-a8ebfb5d27fd> in <module>()
      1 ## Sylvia's number changed
----> 2 phone_numbers['friends'][0][1] = "532-1521"

TypeError: 'tuple' object does not support item assignment

In [46]:
phone_numbers['friends'][0] = ("Sylvia","232-1521"); 
print phone_numbers['friends']


[('Sylvia', '232-1521'), ('Jeremy', '232-1121')]

In [47]:
## I lost all my friends preparing for this Python class
phone_numbers['friends'] = [] # sets this to an empty list

In [48]:
## remove the friends key altogether
print phone_numbers.pop('friends')


[]

In [49]:
print phone_numbers


{'family': [('mom', '642-2322'), ('dad', '534-2311')]}

In [50]:
del phone_numbers['family']

In [51]:
print phone_numbers


{}

 

.update() method is very handy, like .append() for lists


In [52]:
phone_numbers.update({"friends": [("Sylvia's friend, Dave", "532-1521")]})
print phone_numbers


{'friends': [("Sylvia's friend, Dave", '532-1521')]}

 

Loops and branches in python

Python has the usual control flow statements:

  • if, else, elif
  • for loops
  • while loops
  • break, continue, pass

Indentation in Python defines where blocks begin and end.


In [53]:
x = 1
    print x


  File "<ipython-input-53-4427069bca8c>", line 2
    print x
    ^
IndentationError: unexpected indent

IPython Notebook automatically converts tabs into spaces, but some programs do not. Be careful not to mix these up! Be consistent in your programming.

If you're working within the Python interpreter (not the IPython Notebook), you'll see this:

>>> x = 1
>>> if x > 0:
...     print "yo"
... else:
...     print "dude"
... print "ok"
...
yo
ok

In [54]:
# You can mix indentations between different blocks ... but this is ugly and people will judge you

x = 1
if x > 0:
    print "yo"
else:
        print "dude"


yo

In [55]:
# You can put everything on one line

print "yo" if x > 0 else "dude"


yo

In [56]:
# Multiple cases

x = 1
if x < -10:
    print "yo"
elif x > 10:             # 'elif' is short for 'else if'
    print "dude"
else:
    print "sup"


sup

In [57]:
for x in range(5):
    print x**2


0
1
4
9
16

In [58]:
for x in ("all","we","wanna","do","is","eat","your","brains"):
    print x


all
we
wanna
do
is
eat
your
brains

In [59]:
x = 0
while x < 5:
    print pow(2,x)
    x += 1             # don't forget to increment x!


1
2
4
8
16

In [60]:
# Multiple levels
for x in range(1,10):
    if x % 2 == 0:
        print str(x) + " is even."
    else:
        print str(x) + " is odd."


1 is odd.
2 is even.
3 is odd.
4 is even.
5 is odd.
6 is even.
7 is odd.
8 is even.
9 is odd.

In [61]:
# Blocks cannot be empty

x = "fried goldfish"
if x == "spam for dinner":
    print "I will destroy the universe"
else:
    # Nothing here.


  File "<ipython-input-61-1b3c12403da9>", line 7
    # Nothing here.
                   ^
IndentationError: expected an indented block

In [62]:
# Use a 'pass' statement, which indicates 'do nothing'

x = "fried goldfish"
if x == "spam for dinner":
    print "I will destroy the universe"
else:
    pass

In [63]:
# Use a 'break' statement to escape a loop

x = 0
while True:
    print x**2
    if x**2 >= 100:
        break
    x +=1


0
1
4
9
16
25
36
49
64
81
100

In [ ]:

What is a Function?

  • A block of organized, reusable code that is used to perform a single, related action.
  • Provides better modularity for your application and a high degree of code reusing.
  • You can name a function anything you want as long as it:
    1. Contains only numbers, letters, underscore
    2. Does not start with a number
    3. Is not the same name as a built-in function (like print).

Basic Synthax of a Function

An Example


In [64]:
def addnums(x,y):
    return x + y

In [65]:
addnums(2,3)


Out[65]:
5

In [66]:
print addnums(0x1f,3.3)


34.3

In [67]:
print addnums("a","b")


ab

In [68]:
print addnums("cat",23232)


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-68-6e40a78d2444> in <module>()
----> 1 print addnums("cat",23232)

<ipython-input-64-a063d692eafe> in addnums(x, y)
      1 def addnums(x,y):
----> 2     return x + y

TypeError: cannot concatenate 'str' and 'int' objects

Scope of a Function


In [69]:
def numop(x,y):
    x *= 3.14
    return x + y
x = 2
print numpop(x, 8)
print x


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-69-1062d331c016> in <module>()
      3     return x + y
      4 x = 2
----> 5 print numpop(x, 8)
      6 print x

NameError: name 'numpop' is not defined
Python has it’s own local variables list. x is not modified globally ...unless you specify that it’s a global variable

In [70]:
def numop(x,y):
    x *= 3.14
    global a
    a += 1
    return x + y, a

a = 2
numop(1,1)
numop(1,1)


Out[70]:
(4.140000000000001, 4)

Pass by reference vs value

All parameters (arguments) in the Python language are passed by reference. It means if you change what a parameter refers to within a function, the change also reflects back in the calling function.

In [71]:
def changeme_1( mylist ):
   mylist = [1,2,3,4]; # This would assig new reference in mylist
   print "Values inside the function changeme_1: ", mylist
   return

def changeme_2( mylist ):
   mylist.append([1,2,3,4]);
   print "Values inside the function changeme_2: ", mylist
   return

mylist1 = [10,20,30];
changeme_1( mylist1 );
print "Values outside the function: ", mylist1
print

mylist2 = [10,20,30];
changeme_2( mylist2 );
print "Values outside the function: ", mylist2


Values inside the function changeme_1:  [1, 2, 3, 4]
Values outside the function:  [10, 20, 30]

Values inside the function changeme_2:  [10, 20, 30, [1, 2, 3, 4]]
Values outside the function:  [10, 20, 30, [1, 2, 3, 4]]

Function Arguments

You can call a function by using the following types of formal arguments:

  • Required arguments (arguments passed to a function in correct positional order. Here, the number of arguments in the function call should match exactly with the function definition)
  • Keyword arguments (identified by parameter names)
  • Default arguments (assume default values if values are not provided in the function call for those arguments)
  • Variable-length arguments (are not explicitly named in the function definition)

Keyword Arguments


In [ ]:
def numop1(x,y,multiplier=1.0,greetings="Thank you for your inquiry."):
    """ numop1 -- this does a simple operation on two numbers.
     We expect x,y are numbers and return x + y times the multiplier
     multiplier is also a number (a float is preferred) and is optional.
    It defaults to 1.0.
     You can also specify a small greeting as a string. """
    if greetings is not None:
       print greetings
    return (x + y)*multiplier

In [ ]:
help(numop1)

In [ ]:
numop1(1,1)

In [ ]:
numop1(1,1,multiplier=-0.5,greetings=None)

Unspecified args and keywords


In [ ]:
def cheeseshop(kind, *arguments, **keywords): 
    print "-- Do you have any", kind, "?"
    print "-- I'm sorry, we're all out of", kind 
    for arg in arguments: 
        print arg
    print "-" * 40
    keys = keywords.keys()
    keys.sort()
    for kw in keys: 
        print kw, ":", keywords[kw]

In [ ]:
cheeseshop("Limburger", 
           "It's very runny, sir.", 
           "It's really very, VERY runny, sir.",
           shopkeeper='Michael Palin',
           client="John Cleese",
           sketch="Cheese Shop Sketch")

What is a Module?

  • A Python object with arbitrarily named attributes that you can bind and reference.
  • A file consisting of Python code.
  • Allows you to logically organize your Python code.
  • Makes the code easier to understand and use.
  • Can define functions, classes and variables.
  • Can also include runnable code. </UL>
  • Any file ending in .py is treated as a module.
    
    
    In [ ]:
    import math
    
    
    
    In [ ]:
    math.cos(0)
    
    
    
    In [ ]:
    math.cos(math.pi)
    
    
    
    In [ ]:
    math.sqrt(4)
    
    
    
    In [ ]:
    from datetime import datetime
    
    
    
    In [ ]:
    now = datetime.now()
    
    
    
    In [ ]:
    print now.year, now.month, now.day
    
    
    
    In [ ]:
    from math import acos as arccos
    
    
    
    In [ ]:
    arccos(1)
    

    Import Statements

    from module_name import name as my_name from module_name import function_name from module_name import variable from module_name import variable, function_name1, function_name2, ... from module_name import *

    Built-In-Modules

    • sys: exposes interpreter stuff & interactions
    • os: exposes platform-specific OS functions
    • math: basic mathematical functions & constants
    • argparse: command line parser
    • datetime: supplies classes for manipulating dates and times
    
    
    In [ ]:
    
    

    Breakout exercise: Let's play Battleship!

    We're going to build the game Battleship in Python! How? First what do we need to play Battleship?

    1. The Board

    2. The enemy ship

    3. A means of guessing

    4. The rules!

    Specifically, what restrictions do we have on the guess?

    1. Make the game last more than one turn

    2. Game over conditions?

    Extra Credit: More than one ship? Ship takes more than one space? Subtleties in doing this?

    
    
    In [ ]:
    
    

    More Module Practice!

    1. Create and edit a new file called age.py
    2. Within age.py, import the datetime module
      • use datetime.datetime() to create a variable representing when you were born
      • subtract the two, forming a new variable, which will be a datetime.timedelta() object. Print that variable.
        1. How many days have you been alive? How many hours?
        2. What will be the date in 1000 days from now?
    3. Create and edit a new file called age1.py
      When run from the command line with 1 argument, age1.py should print out the date in days from now.
      If run with three arguments print the time in days since then.

      ./age1.py 1000
      ./age1.py 1980 1 8
    
    
    In [ ]: