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 17, 2018: Introduction to Python (part 2 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.
Extra announcements (not in your copy of this file):
My office hours are Thursday 4-5 in APM 7202.
I will process the waitlist at the end of the week. In addition to priority on the waitlist, I will also take into account participation in the course so far (in-class plus homework).
There are two extra files in today's folder which you should ignore. You should have open "2018-01-17.ipynb".
Functions (carryover from last lecture)
Functions are batches of code that can be called from within other code.
A function takes zero or more parameters, and produces zero or more return values. A function may also have side effects, although it cannot change the values of variables outside of the function (that is, variables inside a function are locally scoped).
Just like assignments of variables, the definition of a function persists between cells, unless you overwrite it by assigning the same name to another function. (If you really want, you can also type del f
which removes the definition of f
without replacing it. This works for both variables and functions; in fact, a function is just a special type of value you can assign to a variable.)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-8-ee53d52ce0bb> in <module>()
----> 1 name_of_function('abc', 123) # This will fail -- you can't add a string and a number in Python
<ipython-input-5-b6c722822b73> in name_of_function(argument1, argument2)
2 x = 8
3 print("the first argument is ", argument1, " and the second is ", argument2)
----> 4 return argument1 + argument2
TypeError: Can't convert 'int' object to str implicitly
Try this now: last time, you wrote a code block that, given an integer x
, returns 1, -1, or 0 depending on whether the integer is positive, negative, or zero. Now create a function my_sign
that does the same for its input.
Try this now: write a function that takes four parameters and returns their average. Try the test cases below to see if your function is working.
Try this now:
Use a while
loop to write a function largest_power_of_2
that takes as input a positive integer n
and returns the largest power of 2 that is less than n
. Your loop should start with pow=1
and while pow*2
is less than n
replaces pow
with pow*2
; once the loop ends, return pow
.
Aside: the syntax for exponentiation in Python is 2**n
rather than 2^n
.
Lists
A list is a Python type consisting of an ordered list of other objects. This is similar to the concept of an array in other programming languages; however, in Python the objects of a list can be of different types (e.g., a single list can simultaneously contain numbers, strings, other lists, etc.).
One can create a list by specifying its contents enclosed in square brackets. The empty list is allowed.
If l
is a list, then the objects of the list can be retrieved as l[0], l[1], ...
; note that the first index is 0, not 1. The last items in a list can be retrieved as l[-1], l[-2], ...
.
Here are some examples of operations on lists.
Many of the available operations on lists, and on other Python objects, are accessed using a slightly different syntax than the one used so far. Look at these examples.
These kinds of functions are specific to a certain type of object, in this case lists; they are called methods of the object class. This is a symptom of the fact that Python is an object-oriented programming language; we will see later how Sage takes advantage of this architecture to implement mathematical objects.
In the meantime, I point out two ways to find out more about the methods associated to a particular class of objects.
Use tab-completion: type
l.
and hit the Tab key to see a list of methods associated tol
. If you have typed some letters after the period before hitting Tab, you'll only get objects whose names match the initial string you typed.Look at the page from the Python documentation corresponding to the type. For example, for lists this page is https://docs.python.org/2/tutorial/datastructures.html.
List comprehensions
Mathematicians are fond of constructing sets out of other sets. Python offers a similar syntax:
et cetera.
You can typically rewrite a list comprehension as a for
loop (or nested for
loops).
Helpful hint: The order of the for
loops and the if
are exactly the same as in the list comprehension.
Try this now:
Construct the following list using a list comprehension and the function my_sign
you wrote earlier (which should still be declared):
If you have extra time, do the same using a for
loop.
Advanced note: the definition of list comprehension does now allow for an else
clause. However, there is an inline version of if/else
that is sometimes useful in this context.
Warning: lists are mutable
There is a serious subtlety with how Python lists works. 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/
File "<ipython-input-38-f13a981896f0>", line 2
copy. # Let's do the tab completion here to see what new functions we got
^
SyntaxError: invalid syntax
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-54-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-58-3bf7a14c4b06> in <module>()
----> 1 t.append # 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.