Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download
Project: math480-2016
Views: 2158

Math 480: Open Source Mathematical Software

2016-04-08

William Stein

Lectures 6: Dicts and Classes (Python 3/3)

  • My morning sucked: massive SageMathCloud problems. You can turn in your homework on Monday at 6pm rather than Friday at 6pm.

  • Screencast

Another important data structure: the Python dictionary

A Python dictionary is the Python version of what computer scientists might call an "associative array".

It's what us mathematicians call a "function" (from one finite set to another). Except, like a list, it can be modified (to make another function).

def foo(n): return random()
foo(5)
0.5057163160541822
foo(5)
0.2638328061849261
d = {5:25, 10:100, 3:8, 3:'another value'}
d
{10: 'foo bar', 3: 'another value', 5: 25}
d[10]
100
d[10] = 'foo bar'
d[10]
'foo bar'
d[5]
25
d[10]
100
d[3]
8
d[7] # should fail -- since we didn't say what 7 maps to.
Error in lines 1-1 Traceback (most recent call last): File "/projects/sage/sage-6.10/local/lib/python2.7/site-packages/smc_sagews/sage_server.py", line 904, in execute exec compile(block+'\n', '', 'single') in namespace, locals File "", line 1, in <module> KeyError: 7
try: d[7] except KeyError: print "there was an errror"
there was an errror

The keys (inputs) of a Python dictionary can be any object x in Python where hash(x) doesn't give an error.

In practice, hash(x) is supposeed to work if and only if x is immutable, i.e., really can't change.

hash(7)
7
w = [2,3] hash(w) # better not work!
Error in lines 2-2 Traceback (most recent call last): File "/projects/sage/sage-6.10/local/lib/python2.7/site-packages/smc_sagews/sage_server.py", line 904, in execute exec compile(block+'\n', '', 'single') in namespace, locals File "", line 1, in <module> TypeError: unhashable type: 'list'

Tuples -- I mentioned them very quickly last time.

Tuples are sort of like lists, but you can change the objects they point to or the number of things they point to.

Hence... they have a chance to be immutable:

d = {5:'a', [2,3]:5}
Error in lines 1-1 Traceback (most recent call last): File "/projects/sage/sage-6.10/local/lib/python2.7/site-packages/smc_sagews/sage_server.py", line 904, in execute exec compile(block+'\n', '', 'single') in namespace, locals File "", line 1, in <module> TypeError: unhashable type: 'list'
x = [2,3] d[x] ︠893a8827-7fdd-4df1-a191-d31bdd0fc83fs︠ hash([2,3])
Error in lines 1-1 Traceback (most recent call last): File "/projects/sage/sage-6.10/local/lib/python2.7/site-packages/smc_sagews/sage_server.py", line 904, in execute exec compile(block+'\n', '', 'single') in namespace, locals File "", line 1, in <module> TypeError: unhashable type: 'list'
w = (2,3) hash(w) # a tuple where each thing in the tuple is immutable
3713082714463740756
d = {(2,3):5, (7,19): 26} # you can use anything immutable as the inputs (or keys or domain) d[(7,19)]
26

Not all tuples are immutable. For example:

w = ([2,3], 5) # a tuple where first thing is NOT immutable hash(w)
Error in lines 2-2 Traceback (most recent call last): File "/projects/sage/sage-6.10/local/lib/python2.7/site-packages/smc_sagews/sage_server.py", line 904, in execute exec compile(block+'\n', '', 'single') in namespace, locals File "", line 1, in <module> TypeError: unhashable type: 'list'
id(w[0])
140218864891664
w[0].append("Sage") w
([2, 3, 'Sage'], 5)
id(w[0])
140218864891664

Exercise: Which of the following are immutable, i.e., hash-able, so they can be used as keys for a dictionary?

  • the string "Foo"

  • the empty list []

  • the number 3.14

  • the dictionary {7:10, 3:8}

  • the tuple ('foo', 'bar')

Make a dictionary that has all the immutable objects above as keys... and anything you want (hashable or not) as values.

hash("Foo") # no error <===> it's immutable
-5036909580522842981
d = {"Foo":(1,2), 3.14:5} # IS A DICTIONARY
type(d)
<type 'dict'>
d
{'Foo': (1, 2), 3.14000000000000: 5}
hash(d)
Error in lines 1-1 Traceback (most recent call last): File "/projects/sage/sage-6.10/local/lib/python2.7/site-packages/smc_sagews/sage_server.py", line 904, in execute exec compile(block+'\n', '', 'single') in namespace, locals File "", line 1, in <module> TypeError: unhashable type: 'dict'

Here's a dictionary with a function as a value:

def length(self): return sqrt(self['x']^2 + self['y']^2) self = {'x':10, 'y':25, 'length':length} self
{'y': 25, 'x': 10, 'length': <function length at 0x7f8740436ed8>}
self['length'](self)
5*sqrt(29)

Using dicts with data and functions you could model objects and work with them.

But the notation is very awkward!

Python classes do much the same thing, with vastly nicer notation!

︠f4dd5f00-1a75-4cc5-9eca-2d84a91d360bi︠ %md ## Python Classes Python classes let you easily create custom Python objects. They are a fantastic way of organizing math-related code. Example:

Python Classes

Python classes let you easily create custom Python objects. They are a fantastic way of organizing math-related code.

Example:

class Vector: def __init__(self, x, y): self.x = x self.y = y print "I just initialized myself" def length(self): print "hi this is length" return sqrt(self.x^2 + self.y^2) def __add__(self, right): return Vector(self.x+right.x, self.y + right.y) # change to Vector3 def __repr__(self): return "William's vector (%s, %s)"%(self.x, self.y)
v = Vector(e, pi) print v
I just initialized myself William's vector (e, pi)
v.length()
hi this is length sqrt(pi^2 + e^2)
v + v
The Vector (2*e, 2*pi)
v.__dict__
{'y': pi, 'x': e}

Exercise:

Copy the above code and make a class Vector3 that models a vector in 3-dimensional space.

If you have time, also include a __sub__ method, to subtract one vector from another, and test that v - w works.

v.cross_product(w)