In this file, we'll look at some of the language features of python and how to use them. Some prior programming experience might be useful here, with Java, Javascript, C, C++, or Python.
In your virtual machine's terminal, you can run the command python3,
and you can enter code in the resulting prompt.
Now let us look at some Python code examples.
Click in the next cell with the example code and press Shift+Enter
keys to run it.
prius_weight = 4000
battery_weight = 150
just_the_normal_car_weight = prius_weight - battery_weight
print ("If you took the battery out of a Prius it would weigh", just_the_normal_car_weight, "pounds.")
It should be obvious what the code above does. Python has all the usual arithmetic "operators" you would expect:
sum = 4 + 2
difference = 4 - 2
product = 4 * 2
thingie = 9 / 3
print(sum, difference, product, thingie)
There are also some other operators:
integer_division = 7 // 2
remainder = 7 % 2
big_number = 9 ** 25
print(integer_division, remainder, big_number)
The // operator (two slashes next to each other) mean "divide this
and ignore the remainder". The % operator means "divide this and
only give us the remainder. Finally, two asterices mean "evaluate
the left side raised to the right side's power".
The standard order of operations that we learned in school still applies here. Exponentiation is done first, then the multiplications and divisions, and then finally the additions and subtractions.
Within the same level, operators are evaluated left-to-right:
print(8 - 5 + 3)
There is an exception, though. Exponentiation is done right-to-left:
print(2 ** 3 ** 4)
print(2 ** 81)
Notice how big those numbers are? Python (at least, all modern versions) represent integers with 64 bits. This will hold numbers from positive to negative 9 billion billon, give or take a little. If you want to count the atoms in a micromole, knock yourself out.
Parentheses work as expected for explicitly forcing a particular order of operations:
test_1 = 92
test_2 = 90
test_average = (test_1 + test_2) / 2
print(test_average)
Python has a shortcut for using the value of variable, changing it, and storing it back in the same variable. So the code in both the below cells do the same thing:
weight = 6
weight = weight + 4
print(weight)
weight = 6
weight += 4
print(weight)
Along with the += operator, there is also -=, *=, and /=.
We've been throwing those print() function calls around without
talking about them.
The print() function will take any number of arguments, separated by
commas, and print them out with one space between them. After the last
item is printed, Python will put out a "newline" character, go to the
next line, and get ready to start printing at the beginning of the
next line.
Variables give names to things. We've seen variables used as integers and as floating point numbers. Variables can also refer to strings.
Unlike Java or C++, the are not "strongly" typed. A variable can be a number one moment and then can suddenly become a string. You don't have to declare types of variables either.
amount = 7
print(amount)
amount = "a whole lot!"
print(amount)
Variables in Python work similarly to Javascript, if you're familiar with that language.
Python has these basic data types:
- Booleans, which are
TrueorFalsevalues. - Numbers, which can be:
- Integers (example:
-1,0,1,2, …) - Floating point numbers (example:
3.14) - Complex numbers (example:
3+4j)
- Integers (example:
- Strings (example:
"hello world!") None, which is a special constant that indicates the absence of a value.Noneis the equivalent ofnullin some other languages. When you call a function and it returns nothing, you will get aNone, for example.
There also decimal numbers and fractions, should you ever need them. You can take a look at Python's Numeric and Mathematical Modules if you are curious what else is available.
We will discuss modules later. For now, just bear in mind that: (1) a "module" is some code that you can use when writing your own code, and (2) Python has a standard library, which is a collection of useful and commonly used modules. You will use the standard library a lot if you use Python.
Strings can be surrounded by single quotes (') or double quotes
("). Whichever one you start a string with, you have to end with
that same kind, and it does not matter which kind of quote you use:
'hello' and "hello" are the same.
'hello' == "hello"
Note that you can't mix the types of quotes when declaring a string. Running the below code cell will result in an error:
'hello"
Regardless of the type of quote you use, it would be a good idea to use one type of quotes consistently across a program or project.
Some data structures are immediately available to you in the core language:
- Lists
- Dictionaries
- Tuples
- Sets
Here is an example of a list:
temperatures = [44.2, 43.6, 107.9, "awfully hot!"]
You write the elements of the list inside square brackets ([ and
]), with commas to separate them.
Python lists are like arrays in C++ and Java, except:
- Python lists can grow (and shrink) as needed.
- The different elements of an array do not all have to be the same type.
Here's another example:
grades = ["A", "B", "C", "D", "F"]
print(len(grades))
print(grades[0])
print(grades[1])
print(grades[2])
print(grades[3])
print(grades[4])
Notice the first element in a list is numbered 0 (zero). Any time you index into a list, Python always counts starting at 0, not 1. Forgetting this fact will likely be a big source of mistakes.
You can also loop over lists using a for statement (we will discuss
for statements later in this notebook):
for grade in grades:
print(grade)
If you try to read past a list, that would result in an error. Try running the below cell:
grades[5]
Lists are one-dimensional. If you would normally use a 2D array for something, you would want to use a list of lists:
list_of_lists = [
[1, 2, 3],
[],
[4, 5, 6]
]
print(list_of_lists[1])
[] is an empty list, obviously.
Dictionaries (or dict objects in Python parlance) contain pairs of
keys and values. You will use them when you want to look up items by
a key whose value you already know.
drugs = {
"asprin": 325,
"acetaminophen": 500
}
print(drugs["asprin"])
print(drugs["acetaminophen"])
If you try to look up by a key that does not exist, that would result in an error:
drugs["ibuprofen"]
In order to avoid the error, you can do something like this:
value = drugs.get("ibuprofen")
if value != None:
print("Found ibuprofen:", value)
else:
print("Could not find ibuprofen")
You can add new keys and values to an existing dictionary:
drugs["methotrexate"] = 2.5
print(drugs)
Keys in a dictionary are immutable: you can't change them once they are inserted. But you can change the values associated with them:
drugs["methotrexate"] = 3.5
print(drugs)
Tuples (or tuple objects) construct groups of objects. These are
all tuples:
() # An empty tuple.
(1,) # A one-item tuple.
(0, 'Ni', 3.14) # A four item tuple.
Unlike lists, tuples are immutable: you can't change a tuple's elements once the tuple is constructed. You can use tuples when you need to:
- Use a collection of things that remains constant.
- Return multiple values from a function. (We'll discuss functions later.)
Tuples can be dictionary keys because they are immutable.
locations = {
(40.7128, -74.0060): "New York",
(51.5074, -0.1278): "London"
}
The strings that start with # are comments. We will discuss
comments later in this notebook.
Sets (or set objects) are structures whose elements are unique.
{1,2,3}
{0, 'Ni', 3.14}
If you want to get just the unique elements of a list, you can insert the list to a set!
numbers = [10,1,1,1,1,2,20]
unique_numbers = set(numbers)
print(unique_numbers)
Operators can have different meaning depending on the types of data they operate on.
For example, the + operator applied to numbers will result in an
addition. When applied to strings, the + operator will concatenate
("jam together") them.
first_part = "super"
other_part = "conducting"
supreme_coolness = first_part + other_part
print(supreme_coolness)
Notice that it did not insert a space. If you need a space, you have to do it yourself.
not_as_cool = first_part + " " + other_part
print(not_as_cool)
First, there are three things being concatenated: a variable, a string "literal" with only a single space in it, and another variable. Second, when we evaluate a cell and create a variable in it, those variables become available to every cell further down the line.
(If you're curious, there is one instance of Python running behind the scenes. Jupyter just crams code into when you execute a cell. When Python is done running that, any output is put into the notebook right below that block. Running another command later, in another cell, sends that code to the one and only Python instance associated with the entire notebook. There is no need to write insanely long cells, and in fact you should keep them 30-50 lines at most if you can. Shorter cells are easier to understand and debug.
Python has the same control structures you're used to, such as if
and if/else. It's just that syntax may be a little different now.
if 5 > 4 :
print("arithmetic still works!")
print("now back to the show!")
else:
print("it appears we have shifted universes for a few minutes.")
print("I have a feeling this will be bad.")
Notice that there is a : (colon) at the end of the if line. A
colon indicates that a "code block" is coming up. In our case, these
blocks are two lines long. They have to be indented, and they have to
be indented the same amount. In Python, indentation has meaning. The
"visual" level that things are indented to indicates the "lexical"
level of the code block.
Python has loops, as expected:
weight = 6.0
while weight < 11.2:
print("running inside the loop!")
weight = weight + 4
print("done with the loop now.")
while loops are very versatile: you can test anything to see if you
should continue. Sometimes you know how many times you want to do
something and you want a cleaner way to express that. You would use a
for loop in such instances.
for i in range(1,6):
print(i)
if i == 5:
print("we got to 5, like we expected!! Surprise!!")
else:
print("hmmm...")
Notice something above: when testing for equality, Python uses ==
operator. This is just like Java, C, C++, etc.
Notice something else: in range(1,6) we specified the range to be
from 1 to 6, but it stopped after 5. That's how range() works: you
specify the number to start at and the number that is the first one
you want it to stop at. Forgetting this will result in some
easy-to-make mistakes.
Back to for loops for a minute. These loops can also iterate over a
list:
for color in ["red", "green", "blue"] :
print(color)
In fact, the range() function is used to build a list of values and
then the for loop steps over it.
A function is a reusable piece of code that performs a certain task. When you find yourself writing the same pieces of code over and over, you would "refactor" the pieces of repeating code, and put them in a function. Now you can call the function over and over.
Here's how you would create (or "define") a function: use the def
keyword, followed by a space and then the name of the function,
followed by the function parameters (or arguments), followed by a :,
and then the block of code that should perform the thing that you want
the function to perform. If you want to return some value from the
function, you would use the return keyword.
When you want to pass more than one parameter to the function, you would separate them by commas.
Here's an example of a function:
import math # use Python's math module.
def area_of_circle(radius):
"""
Compute area of a circle.
:param radius: radius of the circle.
"""
result = math.pi * radius ** 2
return result
You can call the function like so:
area_of_circle(10)
There are two new things here: import statements, and code comments.
Let us talk about code comments in the next section. We will talk
about import statements and importing modules in a later section.
Did you notice the lines in the cell above that started with a #?
That # character means "everything on the rest of the line is just a
note to myself and should not be run". These comments are very
valuable for reminding yourself (or other readers of your code) about
what's going on when you come back to your code three months later and
you can't remember anything. You would use # when your comment can
be written in one line.
You can also write comments that span multiple lines: you would start
the comment with a """, write the comments, and then use another
""" to end the comment.
Note the comment surrounded by """ that describe the function in
(somewhat) detail. They are called docstrings, and this is a common
way to document Python code.
When you read the documentation of some libraries (such as NumPy numpy-reference), you might be looking at pages generated by processing docstrings that are written along with the code. Python has conventions for writing docstrings, and tools for generating such documentation from docstrings.
Python classes can't be too strange to those familiar with C++ or
Java. You would use the class keyword to define classes, and an
(optional) __init__() method (or member function) to create the
class constructor. Note that the first parameter to member functions
is the self keyword.
class Customer:
""" An example class. """
def __init__(self, name, address):
"""
Constructor.
:param name: name of the customer.
:param address: address of the customer.
"""
self.name = name
self.address = address
def show(self):
""" Print the customer's details. """
print(self.name + " lives at " + self.address)
Now you can create objects of the class, and invoke member functions of these object:
c = Customer("Bob", "1234 Wooded Way")
c.show()
We can't go into all the details here, but some basic familiarity with
the idea of classes and objects would be helpful when programming with
Python. Important data structures list, dict, set, and tuple
are implemented as classes.
Consider the code below:
total_grams = 100
number_of_people = 0
individual_portion = total_grams / number_of_people
If you run the above, it would result in an error, since division by zero is undefined.
When an unrecoverable error such as the above occurs, the Python
runtime "raises" (or "throws") an exception. In the above instance,
you would see an exception called ZeroDivisionError. There are
other kinds of exceptions too. You also can create your own exception
classes because doing so is sometimes useful.
Unless exceptions are "caught" by an exception handler, your program
would exit or behave in ways that you do not want. In order to do
that, you would use a try/except block, like so:
try:
individual_portion = total_grams / number_of_people
except:
print("Number of people was zero, no valid answer!")
We already saw how to use an external definition like math.pi when
we talked about functions: you do an import math, and then use the
code in math module with math.pi.
But what are modules?
Modules are the organizational units of a Python program. When you create a Python project, you would split your code into logical units, called modules. You can create and use modules within your own programs, and you can use modules from external libraries.
In concrete terms, modules correspond to files. You would put code that does related things in separate files, somewhat like so:
mypackage/
__init__.py
module1.py
module2.py
subpackage/
__init__.py
submodule1.py
And then you will be able to use these modules elsewhere by importing
them. You would use import statements to do this, like so:
from mypackage import module1
from mypackage.subpackage import submodule2 as sm2
module1.some_function()
sm2.some_other_function()As shown above, the as keyword lets you import modules under a more
convenient (perhaps shorter) name.
An alternative, but more verbose syntax for importing modules would be this:
import mypackage
mypackage.module1.some_function()
mypackage.subpackage.submodule1.some_other_function()The first way is a little more convenient.
Now you know just enough Python to be dangerous.
An excellent Python tutorial is available at https://docs.python.org/. I recommend you bookmark that for handy reference.
Now that we're at least a threat to ourselves, if not others, let's go to the next notebook and look at Python packages.
