In this first proper programming lesson we are going to use the Python interpreter to perform simple operations, like numeric calculations that you would normally do on a calculator and slightly more advanced operations on words. The interpreter is what reads your code and converts that into the binary instructions that the computer can understand – think of it as translator between you and the low-level components (operating system, file system, network, display, etc.) of your machine. In these notebooks the interpreter is in the background and runs when you click the 'Run' button in a code cell (in future we'll see how we can use the Python interpreter with scripts of many lines of code).
As we progress through the excercises we'll encounter a range of new programming concepts. At this stage don't worry too much about memorizing all of them; it is through repeated used and practice that they will eventually come naturally. Instead, here we want you to try to develop a sense of what is going on and keep the concepts in mind when reading the examples... but the really important thing is to try to apply them while doing the excercises.
To help you get started, we have prepared an introductory video to aid your learning about the basic concepts in Python. Please note that by the time you have finished watching this video, you might need to re-launch binder. So if you have modified any part of your notebook, make sure to download the current version to your browser (the introductory video talks about how to do this).
Lastly, a few words on the excercises; in every notebook we've tried to develop a mix of exercises and examples to show you how Python works. There are four 'levels' of exercise:
We're not expecting you to master the fourth level at this stage; in fact, some of the examples might be challenging even after a full year of classes. However, we think it's important to try to show you where we're trying to go as well as the steps involved in how we get there. It's like trying to follow directions from someone who only tells you 'turn left', 'turn right', 'go straight' – it's a lot easier to fill in the gaps and to understand what's going on if they say "We're headed to London" first!
In [ ]:
3 - 2 + 10
In [ ]:
2 * 5
In [ ]:
10 / 5
In [ ]:
print(4 * (2 - 8) + 2)
print(4 * 2 - 8 + 2)
The results are different due to the order in which Python runs the operations. Anyway, remember the importance of parentheses in determining 'precedence' – which operations get done first.
You'll see that the code above encompases each formula in print()
command on each line; this simply allows us to print out the results of both calculations when the code runs. We'll come back to this later.
In [ ]:
(3 * 2) - 10
is not the same as:
In [ ]:
3 * (2 - 10)
In [ ]:
2 ** 4
That's the same as:
In [ ]:
2 * 2 * 2 * 2
So 2**4
is how we get 2-to-the-power-of-4 (the same as multiplying 2 together 4 times). Hopefully this all kind of rings a bell even if you've not studied any maths in a while.
So 2**4
is 2-to-the-power-of-4, but how do we get the square root (or fourth root) of a number? Right now, with what we've taught you so far, the best way is to remember that a square root is the same as an exponent of one-half. The fourth root is an exponent of one-quarter. Etc.
In [ ]:
print(2**8) # 2-to-the-8
print(256**(1.0/8.0)) # 256-to-the-one-eighth
In [ ]:
print(1/8)
print(1.0/8.0)
Many programming languages (Python used to be one of them) treat whole numbers (1, 8) differently from floating point numbers (1.0, 8.000000000001). In those cases, we get the answer 0
to the first equation because when we use whole numbers in our calculations we got whole numbers back. So 1/8
is obviously not 0
, but that's the nearest whole number to 0.125
! This is what we mean about computers doing exactly what you tell them: sometimes you want 1/8 to equal 0, other times 0.125, and the computer doesn't know which answer you need unless you are very clear about what you want!
While we're on the topic of division, how do you get the 'remainder' of 9/2 – the bit left over from the division? To get this there is a different symbol called the modulo operator which is a marked by a %
sign. According in fact to the Python Documentation
The % (modulo) operator yields the remainder from the division of the first argument by the second.
Using the modulo operator will thus return the remainder:
In [ ]:
print(9/2)
print(9%2)
Just to make this clear: 2 goes into 9 exactly 4 times and then you have 1 left over. So: (4 * 2) + 1 = 9
.
For division which yields no remainder the operation will return a value of 0.
In [ ]:
8%2
In [ ]:
print( (2*3) ** 2 )
The answer is 36 as Python would do the multiplication inside the parenthesis first.
Now what do you think this will give you? Again, work out your answer before running the code.
In [ ]:
print( (2*3) ** 2 / (12 % 5) )
In the code below replace the question marks ???
with the appropriate code to produce a remainder of 6. You may need a calculator to help you. Run the code to check your answer (you can change your answer and run the code multiple times to get the right answer).
In [ ]:
(2+4) ** 2 % (120 / ???)
The operators +, -, *, **, /, %, etc., and the parentheses are all evaluated (i.e. calculated) according to a set of rules that establish precedence, which is just a fancy way of saying: which calculations do we do first? There's a full list here but since that also lists a lot of operators we've not yet encountered it's easiest to summarise this in a table as follows:
\begin{array}{cl} \hline Operator & Description \\ \hline (\ldots) & Parentheses \\ ** & Exponentiation \\ +x, -x & Positive, Negative \\ *, /, \% & Multiplication, Division, Remainder \\ +, - & Addition, Subtraction \\ \hline \end{array}So parentheses trump everything else, then exponents (so 2**5.0/2
is not the same as 2**(5.0/2)
), then positive/negative, and then multiplication/division before we finally get to addition and subtraction.
Also pay attention when dividing by zero. Python won't be able to compute any value and will return an error (which is sometimes also called an exception):
In [ ]:
(30 + 2 ) / 0
Replace the questions marks ???
in the following exercise with the appropriate code to purposufully cause a ZeroDivisionError
exception (again, feel free to use a calculator and you can run the code multiple times).
In [ ]:
(1345 - 20 ) / ((- 3) ** 2 - ???)
Note: the error message is Python's way of telling you what went wrong in the operation. We'll get to these in more detail in a later lesson, but you'll notice that Python always tries to tell you what it thinks went wrong and this is the starting point for all debugging. When something goes wrong in a program this error is like the first clue that puts you on the trail of the wrongdoer: sometimes one clue will lead to another, and another, and another... sometimes one clue is all you need.
But regardless, if you ignore these clues and just put up your hand and say "It doesn't work!" then we're not going to be very impressed. We expect you to be able to explain the problem to us before we will help you with it. More on this later.
So we've seen some examples above of maths with integers (i.e. "whole" numbers) and maths with floats (i.e. "decimal" numbers). Both can be positive and negative (e.g. -1
or -254.32672
). Programmers, being lazy, often call integers ints because it's faster and requires less typing.
Any operation involving a mix of floats and integers will always yeld a float. For example, compare the output for the code below, but note how the resulting data type varies with the operation.
In [ ]:
print(7 * 4)
print(7 * 4.0)
In [ ]:
print(20 / 5)
print(20.0 / 5)
In [ ]:
print(22 / 7)
print(22.0 / 7)
print( int(22.0/7) )
Notice that last ticky bit: we'll get to what int(...)
means later, but if you remember that programmers are lazy then you might realise that it must be short for integer.
In [ ]:
print(6 + 3)
print(6.0 + 3)
The reason for this is that Python is implicitly converting (sometimes called casting) the numbers between the two different data types. This conversion doesn't happen with more complex bits of Python code, but for simple numbers Python tries to be helpful and save you the time and effort.
Note: the integer-to-float conversion might seem a bit of a pedantic distinction, but imagine if you were programming a banking application: you would definitely pay attention to all those decimals!
Let's start with calculating the area of a triangle. Here's the equation for the area of a triangle: $$A = \frac{l_{base} * l_{height}}{2}$$
So lets work out for a triangle that has sides of length 10 and 20! If you type the maths correctly into the empty block below you should get the answer: 100
In [ ]:
(10 * 20)/2
Now let's work out the length of the hypotenuse of a right-angle triangle with the same side lengths as above: $$l = \sqrt{x^2 + y^2}$$
You might remember this as the Pythagorean Theorem, and you should get an answer of about 22.4.
In [ ]:
Let's move on to two last harder ones. Write a line of code to work out the area of a circle of radius 6. Here's the formula: $$A = \pi r^2$$ and you should get something around 113.1 as the area. Use 3.1412 for the constant pi.
In [ ]:
Now work out the approximate radius of a sphere whose volume is 85. To do this, you'll need to work backwards from the formula to calculate a volume... this might seem a little rough at first, but remembering how to rearrange a formula is really helpful for computational thinking!
So what do you have to do to this formula: $$V = \frac{4}{3} \pi r^3$$
Here's a hint to get you started: $$ r^3 = \frac{3}{4 \pi} V $$
Also: remember that you're going to need to work with decimal numbers, not whole numbers and write your code accordingly! You should get a final answer of about 2.7.
In [ ]:
Note: there are a lot of different ways that you could write this formula as code and still get the right answer. Getting the right answer is 50% of the job. The remaining 50% is about doing it in a way that is elegant and easy to read... as get further into the term we'll point out how elegance and legibility (also: commenting) matter.
OK, so that's the basics of numbers. What about text?
In most programming languages, text and words are called strings, which is really a fancy word to say a sequence of characters enclosed in single- or double-quotes (' or "). This might seem like stating the bleedin' obvious but this is a really, really important idea...
"235op!u\$nlkgfd8 wp8ty fgdoy8p waklj ag9up0"
is a string. So is:
"If music be the food of love, play on; Give me excess of it, that, surfeiting, The appetite may sicken, and so die." (Twelfth Night, Act 1, Scene 1, 1–3)
The thing is that computers can't automatically distinguish between Shakespeare and the work of a monkey hitting keys at random. As long as they are both marked out by single- or double-quotes then as far as the computer is concerned they are strings. So even to ask the computer how many words there in the first 3 lines of Twelfth Night means we have to 'teach' the computer what a word is by giving it rules to recognise the start or end of one, and even how to recognise the start and end of a line so that it can find the first three of them!
In [ ]:
print("I'm a string of text!")
print('Me too! *&($£(£_@~{}|?<>$)')
Note: As before, we'll be using the print()
command on many lines of code; that is just a way to tell the Python interpreter to output somthing for us to see.
Although you can technically use either type of quote ('
or "
), it is generally better to use double-quotes as a way to prevent errors if a single-quote is contained in your string:
In [ ]:
print("I'm contained within double quotes. I'll be fine.")
In [ ]:
print('I'm sourrounded by single-quotes and I contain a single-quote so there may be trouble ahead...')
Notice the helpful error message after running the code above? We'll come back to how to read errors like these in more detail in the next notebook, but again Python is giving us hints about where we might have made a mistake.
What do you do if your string contains double-quotes and single-quotes? That's where the 'backslash' (\
, a kind of 'reverse division' symbol) comes in handy. The backslash is how we 'escape' characters so that we can do 'special' things with them when they should normally do something else.
In the example below, the backslash in front of the apostrophe in "I'm" says "Don't treat this as 'normal' single-quote that means the end of the string, treat it as a literal single-quote in the middle of a longer string marked out by single-quotes.
In [ ]:
print('I\'m using the backslash.')
print('I\'m also using the backslash \'\\\' to escape the error normally caused by having single-quotes.')
Let's look at this a little more closely:
"I'm using the backslash"
but you get the point."\'"
). But what's happening with "\\"
? Well, we need an extra backslash in front of the backslash so that the computer knows to print a literal backslash (we are 'escaping' the normal function of a backslash to escape the character immediately after it) instead of reading it as escaping the one in front of the single-quote.That's pretty weird, but just to show you what's happening here it is without that extra backslash:
In [ ]:
print('I\'m also using the backslash \'\\' to escape the error normally caused by having single-quotes.')
If you run the code above, you'll see another error! Also notice that in the two lines of code, in the first the whole line is in one colour (meaning the computer can see that it's all one string), but in the broken example right before this the text changes colour once we get to "to escape the error..." (meaning that the computer doesn't see it all as one string).
The escape symbol crops up in a lot of other circumstances. For example, what if we wanted to tell Python that a string contains a newline (i.e. that the string is split across one or more lines, like our Shakespeare quote above should be)?
Remember that programmers are always lazy when given half a chance and so they figured out that the easiest way to mark a newline was \n
. They used 'n' because it is fairly easy to remember that that means 'newline', and the backslash 'escapes' us from the simple world where an 'n' is the letter 'n' into the computer's world where 'n
' is 'n', but \n
is a newline:
In [ ]:
print("If music be the food of love, play on;\n Give me excess of it, that, surfeiting ,\n The appetite may sicken, and so die.")
See how that wraps the text on the \n
? Also note that the computer is printing exactly what we told it to do: I kept a space between the \n
and the start of the next line. If you squint, then you can see that lines 2 and 3 are indented by the width of one space character. There's also an extra space after 'surfeiting' before the comma.
We say this a lot later too, but you might as well start learning this fact now: spaces in a string matter. To a computer " A string"
and "A string"
are not the same. Notice that there is a single space in front of the 'A'. As a human being we tend to just skip over that space (especially if it's hard to see), but to a computer one string starts with 'A' and the other with ' ', so they are completely different.
Further, numbers and strings are not the interachangeable: "2016"
is not the same as 2016
. The first is a string that happens to contain the characters 2, 0, 1, and 6. The second is an integer number one larger than 2015.
In [ ]:
print("2016")
print(2016)
As you can see from running the code above, it's a bit annoying that they look the same when we print them. But if you run the next lines of code (after thinking about what they might do), you'll see how Python tries to be helpful with its errors:
In [ ]:
2015 + 1
In [ ]:
"2015" + 1
See how the first line of code prints 2016
, but the second line of code (which tries to add together a string "2015"
and the number 1
) gives you an error that lazily tells you about a problem with str
(i.e. string) and int
(i.e. integer) 'concatentation'. More on concatenation in a minute.
Obviously, having a lot of \n
markers would be hard to read and a potential problem if you wanted to copy and paste the text into a different application. If you have a long block of text then you can avoid the whole issue by putting your text inside triple-quotes:
In [ ]:
print("""Hi there,
this time,
I won't need those annoying newline characters.
I also don't have problems with "quotes" or 'quotes'! """)
As with numbers, there are many things that you can do with strings. The simplest, however, is like addition (which is why it uses a +
): when you add strings together you get a new, longer string that contains the characters of the original strings. This is usually called concatenation:
In [ ]:
print("String1" + "String2")
print("Hey, looks like" + " I'm " + "adding "+ "6" +" strings" + " together")
So just like you would do to add two numbers together, we can add "String1" and "String2" together to get "String1String2". But notice that the +
operator doesn't insert whitespace (i.e. a ' ' character) or anything else. It just sticks the two strings together exactly as they are.
And just like we can add together a whole set of numbers, we can add together a whole set of strings as in the second line beginning "Hey, looks like..."
In [ ]:
print("This is code " ??? " camp's notebook is " ??? " number " + "2.")
In [ ]:
print("I like Python a lot" + "!" * 3)
print("Foo " * 25)
In [ ]:
20 * '5'
Now, why do you think the next example below doesn't work? (Read the error output if you're not sure what's going on.)
In [ ]:
print("5" * "2")
So far, everything we've done was about performing some kind of calculation on an integer, float, or string, and then showing the result. Given that a lot of programming doesn't involve solving everything in one easy line, how do you save an answer so that you can re-use it later? Let's start with the first true programming concept: the variable.
If you have studied other programming languages before then the concept of the variable will be so familiar to you that it's hard to remember even having to learn it! Some people think of a variable simply as "a box" that contains values that we want to store and retrieve in the future. However, we think it might be more useful to think of a variable as the label of a box in which we put something: for programmers, the label is how we remember what we put in the box and where we put it.
Let me try to explain: if you watched the introductory videos in the previous notebook, then you'll remember that the computer stores 'information' in lots of places (in memory, on the hard drive, etc.), but it doesn't use an addressing system that you or I would be able to read. Instead, it will use a long, complicated number that tells the computer "Go look in this place for what to do when the mouse is clicked" or "Go look what to do when someone asks you to add together 1 and 5". In the same way that Python translates between what we humans can deal with and what the computer can deal with, it also translates between the 'labels' that we use to refer to different boxes storing different things and how the computer finds what we actually put there.
Here's an example:
In [ ]:
result = -2 * 10
Hmmmm, nothing printed out this time...
That's because this time we gave Python a bax with the label "result" in which to put the result of multiplying -2 and 10.
In [ ]:
result = -2 * 10
print("I'm wasting space...")
print(result)
Can you check the data type of your variable result and switch it to float?
In [ ]:
# First, we need to check the data type of our variable using a function called "type"
type(result)
# Rewrite the existing variable or put it as a new variable
result = float(result) # or result_float = float(result_float)
type(result)
Check it out! We assigned the outcome of -2 * 10
to a variable called result
; then we did something else (printed out a string); and then we printed out the value of the variable and the computer remembered!
This video may help you to further understand the concept of a 'variable':
In [ ]:
myFirstVariable = 1 * 5
print(myFirstVariable)
In [ ]:
mySecondVariable = myFirstVariable
print(mySecondVariable)
Cool, both variables have the same value! We assigned the result of 1 * 5
to a variable named myFirstVariable
and then we assigned this value to a second variable called mySecondVariable
.
But why is this called assignment (or, in plain English, copying)? Well what happens when I change the first variable myFirstVariable
? Will the second change as well?
In [ ]:
myFirstVariable = 2
print(myFirstVariable)
print(mySecondVariable)
Whoa! mySecondVariable
didn't change and still remembers what we assigned to in the first time.
Basically, we took the myFirstVariable
label and attached it to a different box.
As the Python Programming Wikibook explains, when you assign a variable you are just pointing this variable to an object (a value) which is stored somewhere in the memory.
Python variables are a kind of 'label' (as the YouTube video above illustrates – watch it!). So when assigning new values to already declared variables (i.e. variables that already exist in your code) you are not overwriting the old values but simply "moving" the label from one value to another.
That's why in Python variables have a name
, a data-type
and a value
.
Name | Data Type | Value |
---|---|---|
myFirstVariable | integer | 1 |
In the code cell below: a) define a variable called "name" and assign it a value of your choice, then b) print it with the "print" command
For example:
name = "Peter"
print(name)
In [ ]:
Replace the questions marks ???
in the following lines of code with the appropriate code to make it work (i.e. not produce an error).
In [ ]:
cheers ??? name ??? " is awesome!"
print(cheers)
In [ ]:
cheers = name + " is awesome!"
print(cheers)
How do you choose a variable name (i.e. label) in Python?
Here's a short list of the conventions:
myVar2
)2myVar
)my_var_2
)m2
or mySecondVariableIsReallyLong
)print
)So this block of code below will run:
In [ ]:
famous_geographer = "Mercator"
print(famous_geographer)
But this block of code will not:
In [ ]:
1st_geographic_projection = """ Mercator's most famous Geographic Projection
is a cylindrical map projection
that retains the ability
to ability to represent lines of constant course (loxodromes)"""
print(1st_geographic_projection)
Notice how the notebook has coloured the text so that the '1' in what we wanted to make the variable name stands out? Again, that's Python trying to help us figure out what is going wrong, but it requires that you look closely at the output of the error message.
Remember that we said the string " Some text"
and the string "Some text"
are different because the space at the start of the string changes everything? The same sort of strict checking is true for variables: in short, Python is case-sensitive!
This means that this_var
and This_var
are two different variables and can refer to two different boxes:
In [ ]:
this_var = "Mercator"
This_var = "Galileo"
print(this_var)
print(This_var)
As for many issues related to Python's style, it is good practice to always refer to the offical PEP 8 -- Style Guide for Python Code
For more examples of Python variables check out also OpenTechSchool's intro to Python
In [ ]:
old_satellite = 'Sputnik 1'
old_satellite_description = " was the first artificial Earth satellite, launched from the Soviet Union on the 4th of October, 1957."
print("Здравствуйте! My name is " + old_satellite)
print(old_satellite + old_satellite_description)
Similar to the example above, in the code cell below:
new_satellite
with value landsat
In [ ]:
new_satellite = 'Landsat'
print(new_satellite)
In [ ]:
print("The new satellite is " + new_satellite + " and the old satellite is " + old_satellite)
In [ ]:
pr???nt("Hello there " + ???(new_satellite) )
In [ ]:
print("Hello there " + new_satellite + " 8" )
In [ ]:
diameter_cm = 58
cm2inches = 0.393700787
diameter_inches = diameter_cm ??? cm2inches
print(diameter_inches)
In [ ]:
diameter_cm = 58
cm2inches = 0.393700787
diameter_inches = diameter_cm * cm2inches
print(diameter_inches)
In [ ]:
import math
PI = math.pi
radius_cm = diameter_cm/2
volume = (4/3) ??? PI ??? (radius_cm ??? 3 )
print(volume)
In [ ]:
import math
PI = math.pi
radius_cm = diameter_cm/2
volume = (4/3) * PI * (radius_cm ** 3 )
print(volume)
In [ ]:
print(new_satellite + "has a Near Infrared (NI), \
which band captures light in the wavelength from "+
770 +
" to " +
900 +
" nanometers." )
In [ ]:
# The error message indicates a type error, as we can only concatenate string
# The code should work by including "" to the numbers
print(new_satellite + " has a Near Infrared (NI), \
which band captures light in the wavelength from "+
"770" +
" to " +
"900" +
" nanometers." )
In this excercise you'll dip a toe in the wonderful world of web maps!
We are going to create a geographic marker (a pin on the map!) on top of OpenStreetMap (OSM) to visualise King's College location.
To do so we'll have to create a string representing a web URL
(that's the address you type in your browser when your surf the web) pointing to OSM website.
Now, as you can see there are two variables containing King's College Longitute/Latitude coordinate position. You will need to use them within the variable KCL_position
. Unfortunately they are in the wrong data type! Also, there might be something missing in the code.
HINT: To convert (cast) a float
to a string
use the str()
function (we haven't talked about functions yet, but see if you can work it out). You'll also need to think about how to concatenate strings?
Replace the ???
in the code below to make it work.
In [ ]:
# King's College coordinates
# What format are they in? Does it seem appropriate?
longitude = -0.11596798896789551
latitude = 51.51130657591914
#cast the floats to strings
??? = str(longitude)
lat = str(???)
# King's College marker
KCL_position = "https://www.openstreetmap.org/?mlat="+lat+"8&mlon="+lon+"#map=15/"+lat+"/"+lon
print(KCL_position)
In [ ]:
# King's College coordinates
# What format are they in? Does it seem appropriate?
longitude = -0.11596798896789551
latitude = 51.51130657591914
#cast the floats to strings
lon = str(longitude)
lat = str(latitude)
# King's College marker
KCL_position = "https://www.openstreetmap.org/?mlat="+lat+"8&mlon="+lon+"#map=15/"+lat+"/"+lon
print(KCL_position)
Now click on the outputed string and behold! You'll be flying to King's.
For the most curious among you.
On this lesson's topic:
General list or resources
The following individuals have contributed to these teaching materials:
The content and structure of this teaching project itself is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 license, and the contributing source code is licensed under The MIT License.
Supported by the Royal Geographical Society (with the Institute of British Geographers) with a Ray Y Gildea Jr Award.
This notebook may depend on the following libraries: None