This repository contains the course materials from Math 157: Intro to Mathematical Software.
Creative Commons BY-SA 4.0 license.
License: OTHER
Math 157: Intro to Mathematical Software
UC San Diego, winter 2018
January 19, 2018: Introduction to Python (part 3 of 3)
Administrivia:
Homework 1 due Friday, January 19 at 8pm. Remember, put all your work in the "assignments/2018-01-19" folder; it will be collected automatically after the deadline passes.
For problem 5b, I will give full credit if your list
l1
contains four objects. Hint: a dictionary key must be unchangeable (or in Python jargon "immutable"), and if it is a composite type then its components must also be unchangeable.For problem 6, and are supposed to be integers.
The waitlist will be frozen at the end of the day. Thereafter, I will manually add students from the waitlist as space becomes available.
Mutability
There is a serious subtlety with how Python lists (and certain other types, see below) work. This is a frequent source of errors for new Python users.
In Python, objects are copied by reference, not by value. That is, when you perform the assignment b = a
, Python does not assign a copy of the value of a
to the new variable b
; rather, a
and b
are both references to the same object in memory. (This is different from MATLAB, for example.)
This is already true for basic objects like integers, but isn't really an issue.
By contrast, basic operations on lists change the original list, rather than creating a new one. This can lead to unexpected side effects.
Different programming languages make very subtle and different design choices regarding this and other aspects of programming (see homework).
The copy by reference choice of Python makes lists potentially subtle. For example:
Now what the heck is w equal to? (Wait until lots of people in class think this through.)
Moral: Don't judge an object by its cover (how it prints). Just because something prints out at [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
doesn't mean you know what that something is! In Python, things can be very subtle.
If you don't get this point, you might hate Python. If you do get it, you might start to see huge power and flexibility in what Python offers... and understand why Python might be the most popular programming language in data science (and why DS10 is taught in Python).
Shallow and deep copies
In light of the previous issue, let's take a closer look at how copying works. Let's try the copy module from Python's standard library: https://docs.python.org/2/library/
Another approach to the shallow copy uses slicing, which is actually more general: given a list, you can use it to produce a new list consisting of some subrange of objects from the first list. The trivial case, where the subrange is the whole list, is equivalent to shallow copy.
A shallow copy is to be distinguished from a deep copy, which can be modified with no side effects on the original.
MORAL: Python is a real programming language designed (and very occasionally modified) by software engineers. As a result, it takes into account important subtleties about programming to which mathematicians tend to be oblivious.
By contrast, most legacy mathematical software systems were built by mathematicians (or physicists) whose expertise and interests lay far away from programming. The interfaces with these systems are themselves programming languages, but were designed by people without much familiarity with software engineering; this tends to cause problems in the long run.
Tuples
Tuples are a data structure that look quite similar to lists.
Like Python lists, except you use parentheses instead of square brackets to create them.
Tuples are immutable in the sense that you can't change the number of entries or what they reference. However, you might be able to change the referenced thing itself (e.g., if it is a list).
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-31-08a06e0316d9> in <module>()
----> 1 t[1] = 3 # not allowed!
TypeError: 'tuple' object does not support item assignment
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-35-ee693b63bed6> in <module>()
----> 1 t.append(4) # not so for tuples
AttributeError: 'tuple' object has no attribute 'append'
Try this now: Write a function that takes as input a tuple and returns the sorted version of the tuple.
Dictionaries
A Python dictionary is the Python version of what computer scientists might call an "associative array" or a "lookup table".
It's what us mathematicians call a "function" from one finite set to another (not to be confused with a Python "function", which is really a subroutine).
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-49-bac296b2ff6b> in <module>()
----> 1 d[7] # should fail -- since we didn't say what 7 maps to.
KeyError: 7
The values that you use to index a dictionary are called keys.
Aside: Python has a form of flow control for catching runtime errors (exception handling).
But you can also specify a default value in case the key doesn't exist. (For example, you might want to treat all unset values as 0.)
You can add, modify, or delete values to a dictionary after it has been created; it is therefore another mutable type, like lists.
An object can only be used as a key if it cannot be changed. (Officially, hash(x)
has to return without an error.)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-65-ed4910cf88e7> in <module>()
----> 1 d = {[2,3]: 1} # No good, lists are changeable
TypeError: unhashable type: 'list'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-67-9ab58a71f613> in <module>()
----> 1 d = {(2,[3,4]): 1} # ... unless they contain changeable objects.
TypeError: unhashable type: 'list'
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.
Here's a dictionary with a Python function as a value:
Using dicts with data and functions, you could try to model mathematical objects and work with them. But the notation is very awkward!
Python classes do much the same thing, with vastly nicer notation. We will see these in action when we start working with Sage.