Week 13: dictionaries
Monday
The video from today’s lecture (Monday, April 27, 2020):
And here are the announcements:
-
Lab 11 is up and due Saturday (May 2)
-
Quiz 6 is next week
-
I will send out grade reports on Wednesday
This week we are finishing objects, learning a little about dictionaries, and wrapping up the class! :(
the Contact
object
Last time we wrote a Contact
object:
class Contact(object):
"""Contact Class"""
def __init__(self):
"""constructor for empty contact objects"""
self.last = "" # last name
self.first = "" # first name
self.email = ""
self.phone = ""
def __str__(self):
"""should return a string..."""
s = "%s, %s -- %s, %s" % (self.last, self.first,
self.email, self.phone)
return s
def setLast(self, lastname):
"""setter for last name"""
self.last = lastname
def setFirst(self, firstname):
"""setter for first name"""
self.first = firstname
def setEmail(self, email):
"""setter for email"""
self.email = email
def setPhone(self, phone):
"""setter for phone"""
self.phone = phone
What happens if we try to sort()
a list of Contact
objects?
>>> from contact import * >>> c1 = Contact("Jeff Knerr") >>> c2 = Contact("Lisa Meeden") >>> c3 = Contact("Aline Normoyle") >>> clist = [c1,c2,c3] >>> clist.sort() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: '<' not supported between instances of 'Contact' and 'Contact'
Looks like the built-in python sort()
list method doesn’t know
how to compare our Contact
objects! We need the "less-than" operator
for our objects. How do we want to say one object is less than another?
One way is by comparing last names:
# add a < operator
def __lt__(self, other):
"""add in ability to compare with < operator"""
return self.last < other.last
By adding this special method to our class we are telling python
how to know one object is less than another (using the self.last
instance
variable). And just by adding that method, the sort now works!
python’s sorted()
function
At the bottom of contacts.py
is a website with
python sorting
documentation. Another option for sorting a list of
objects is to use attrgetter
and the sorted()
function:
from operator import attrgetter
byfirst = sorted(contacts, key=attrgetter('first'))
byphone = sorted(contacts, key=attrgetter('phone'))
The sorted()
function returns a new list. The above two lines are
sorting the contacts
list, which is a list of Contact
objects.
The first line sorts the list by the self.first
attribute (or instance
variable), and the second sorts it by self.phone
.
python dictionaries
A dictionary in python is a data structure for storing key:value pairs. Examples of these might be: key=word, value=definition, or key=social security number, value=info about the person with that SSN, or key=phone number, value=full name of person with that phone number. The key is unique, and you use the key to look up/access the value in the dictionary.
dictionary syntax
Here’s a quick look at the syntax for dictionaries:
>>> e2s = {"man":"hombre", "bye":"adios", "yes":"si"} >>> print(e2s) {'man': 'hombre', 'bye': 'adios', 'yes': 'si'} >>> e2s["yes"] 'si' >>> e2s["bye"] 'adios' >>> e2s["hello"] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'hello' >>> e2s["hello"] = "hola" >>> print(e2s) {'man': 'hombre', 'bye': 'adios', 'yes': 'si', 'hello': 'hola'} >>> len(e2s) 4 >>> "man" in e2s True >>> "thanks" in e2s False
On the first line I manually define a dictionary (e2s
) with a few key:value
pairs. I then use the e2s[key]
syntax to get the values back for certain
keys. A KeyError
results if the key I try is not found in the dictionary.
I can also add new key:value pairs with the e2s[newkey]=value
syntax.
Using an existing key would overwrite the current value. And finally, the
in
operator works for testing if a key is in the dictionary.
morse code example
Want to convert alphabetic characters into morse code? Here’s a dictionary for that:
morse = {
'a': '.-',
'b': '-...',
'c': '-.-.',
'd': '-..',
'e': '.',
'f': '..-.',
'g': '--.',
'h': '....',
'i': '..',
'j': '.---',
'k': '-.-',
'l': '.-..',
'm': '--',
'n': '-.',
'o': '---',
'p': '.--.',
'q': '--.-',
'r': '.-.',
's': '...',
't': '-',
'u': '..-',
'v': '...-',
'w': '.--',
'x': '-..-',
'y': '-.--',
'z': '--..' }
With the above dictionary we can look up any lowercase alphabetic character and
get back the morse code equivalent (see morse.py
file in the w13
directory).
Wednesday
The video from today’s lecture (Wednesday, April 29, 2020):
-
-
finished Q5 grading
-
lab 8 almost done
-
will send grade progress emails later today
-
review of dictionaries:
d = {} # create emtpy dictionary d[key] = value # add key:value pair to dictionary
d = {1:"Lisa", 2:"Aline", 3:"Jeff"} # create dictionary with key:value # pairs already given
d[key] # will get value for that key # (and give error if no such key)
key in d # "in" operator works for keys (returns True if key present)
len(d) # returns how many keys in dictionary
d.keys() # returns iterator on keys # (something we can use in a for loop)
for key in d.keys(): print(key, d[key]) # would print out all key:value pairs
compare vs list-of-lists
Could use either of these in our duolingo program:
LOL = [['the milk', 'la leche'], ['the girl', 'la nina'], ['the apple', 'la manzana'], ['the boy', 'el nino'], ['i eat bread', 'yo como pan'], ['man', 'hombre'], ['woman', 'mujer'], ['you are', 'eres'], ['i am', 'soy'], ['the man drinks water', 'el hombre bebe agua'], ['he eats apples', 'el come manzanas'], ['i drink', 'yo bebo'], ['you drink', 'tu bebes'], ['he drinks', 'el bebe'], ['thanks', 'gracias'], ['bye', 'adios'], ['good night', 'buenas noches'], ['hello', 'hola'], ['nice to meet you', 'mucho gusto'], ['yes', 'si'], ['you are welcome', 'de nada'], ['good morning', 'buenos dias']]
dictionary = {'the milk': 'la leche', 'the girl': 'la nina', 'the apple': 'la manzana', 'the boy': 'el nino', 'i eat bread': 'yo como pan', 'man': 'hombre', 'woman': 'mujer', 'you are': 'eres', 'i am': 'soy', 'the man drinks water': 'el hombre bebe agua', 'he eats apples': 'el come manzanas', 'i drink': 'yo bebo', 'you drink': 'tu bebes', 'he drinks': 'el bebe', 'thanks': 'gracias', 'bye': 'adios', 'good night': 'buenas noches', 'hello': 'hola', 'nice to meet you': 'mucho gusto', 'yes': 'si', 'you are welcome': 'de nada', 'good morning': 'buenos dias'}
Why use a dictionary? Think about the lookup time for finding "hello" in the list-of-lists:
-
LOL lookup is O(N) or O(logN) if binary search
-
dictionary lookup is O(1)
A dictionary uses a hash function of the key:
>>> hash("jeff") -8564366796957863749 >>> hash("Jeff") -2663725661851044896 >>> hash("hello") 6799624814673269992
Given the key (e.g., "jeff"), we compute the hash(key) and that tells us where to find the value in the data structure. Very much like indexing: given an index, that tells us where to find the item in the list. Indexing is also O(1). But if you just have a word (like "hello"), looking that up in a list-of-lists requires O(N) or O(logN).
example
Add code to eng2spanish.py
program to make the lookup and add
options work:
$ python3 eng2spanish.py [l] lookup [a] add/change [q] quit Your choice? l Word to look up? man --> hombre [l] lookup [a] add/change [q] quit Your choice? l Word to look up? bye --> adios [l] lookup [a] add/change [q] quit Your choice? l Word to look up? hello Hmmm...I don't know that word. [l] lookup [a] add/change [q] quit Your choice? a English word to add: hello Spanish for hello: hola [l] lookup [a] add/change [q] quit Your choice? l Word to look up? hello --> hola [l] lookup [a] add/change [q] quit Your choice? q
word counts
What are the most-used words in Romeo and Juliet?
The file "/usr/local/doc/romeoandjuliet.txt" contains Shakespeare’s "The Tragedy of Romeo and Juliet". Can you read in all words from that file and show the top 20 most-used words?
See wordcount.py
for a start…
Jul. O Romeo, Romeo! wherefore art thou Romeo? Deny thy father and refuse thy name! Or, if thou wilt not, be but sworn my love, And I'll no longer be a Capulet.
Friday
The video from today’s lecture (Friday, May 1, 2020):
-
Last Class! :(
-
Lab 11 due Saturday
-
Quiz 6 Study Guide coming (quiz is May 7-12)
-
Will get Labs back to you next week
matplotlib
Learn some matplotlib
-
simple graph:
simpleplot.py
-
bargraph:
bargraph.py
Also see the matplotlib gallery
data from the web
fun things to do this summer…
thank your ninjas!
THANK YOU Emma, Alex, and Sydney!!! THANK YOU Emma, Alex, and Sydney!!!