CS 110X Jan 17 2014
Expected reading: pages 11-20.
Expected interaction: Programming Python
Clicker: Trial Run
To be a [programmer] is to be an agent of change. Barbara Chandler Allen
A Whole New Mind
1 Begin, be bold and venture to be wise
We will start this lecture – as we will start every lecture – by stating a problem to be solved. Each problem will contain the "seed" of its own solution which you can exploit to solve the problem.
Naturally, we will be using Python to compute the answer.
1.1 Opening Question
When I did this lecture last year, the spacecraft was traveling at 38,127 miles per hour. Why would it be slowing down if there is no friction in space?
The Voyagers 1 and 2 space probes are far from
Earth. They are the most distant man-made artifacts in existence. Based on
data freely available from the
Jet
Propulsion Laboratory, you can find information about the probe on November
8th 2013. At that time, the velocity of the Voyager 1 probe (the furthest probe) was roughly 38,108 miles per hour and it was (roughly) 11,710,000,000
miles from the Sun.
Q1: How far has Voyager 1 traveled since November 8th,
2013?
Q2: How far away is Voyager 1 now?
Q3: What is the ratio of this newly traveled distance to its current
distance?
Clearly these three answers are all related. So how should you go about solving this problem?
Yesterday we used the Python IDLE environment for simple computations. You can put these skills to work now to solve the problem.
Take a moment (yes! Right now!) to perform Q1 by hand.
Once done, add this value to 11,710,000,000 to produce the answer to Q2.
The percentage Q3 can be computed as Q1 / Q2.
Now that you have done these computations manually, let’s write a Python program to do the same. Run IDLE and select menu option File -> New Window. This will pop up a new untitled window. Type the following Python in this window. This is your first program!
A comment in Python starts with a # character. Python ignores everything on a line after a #
Save this someplace convenient on disk and make sure that you save with a file extension of .py to declare that this is a python program. In my case, I saved it as file "day02.py"
To run the program, select menu item Run -> Run Module and you will see that the program will execute in a window identified as "Python Shell".
When you run this program, however, the output shows a computed Q3 value of 0. Congratulations! You have encountered the way integer division occurs in most programming languages!
Yesterday you saw floating point computations, which result in an approximation of values. For example, the fraction 1/7 is the endlessly repeating value 0.142857.... Look how Python computes this value to give 17 digits of precision.
1.0 / 7.0
However, if instead you type:
1 / 7
then Python produces a value of 0, which is clearly incorrect. The basic problem is that values such as 1 and 7 are int values and cannot store decimal "fractions."
When you write a computation in Python, the type of the values determines the type of the computation. And you might be surprised at the results, especially when division is concerned. Try the following
1 / 7.0 # float in numerator or denominator has same impact 122 / 2 # OK integer division 100 / 24 # unexpected integer division 122 / 2.0 # OK for a float to have no decimal component 1.0 * 2 / 7 # Multiplying 1.0 * 2 creates a float 2.0
And, yes, you have to pay attention to these tiny details. By the way, you already are familiar with this kind of computation. For example, if some event is happening 100 hours from now, about how many days is that? You would quickly respond 4.
The reason we call this type float is because its values conform to an IEEE standard for floating point arithmetic. You should already be familiar with this notation from science. For example, the number 3.137 x 107 is also 31370000. There are four known ("precise") digits regardless of magnitude. The number 3.137 x 1061 also contains four precise digits, and you don’t want to lose that precision even though the size of the number has now grown to 31370000000000000000000000000000000000000000000000000000000000.
Each floating point number is stored using 32- or 64-bits (depending upon the machine you are using). It is represented by a sign bit (+/-), a coefficient (above this was 3137) and an exponent (an integer). To find more details about the allowed ranges of Python floating point numbers, type the following in an IDLE window.
import sys print (sys.float_info)
On my Python interpreter, I got the following useful information:
sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)
In general, you should not expect floating point numbers to exactly represent any arbitrary number that you like; in most cases, they will only approximate the value. To be very precise (see epsilon value above?), if the difference between two numbers is smaller than epsilon=2.220446049250313e-16, they are considered to be identical.
The following shows how to "fix" the earlier program to properly compute Voyager distances and ratios.
# Author: George Heineman # Assignment: Lecture Example # # This program computes distance for Voyager. # Note that all comments start with a # character print ("Q1 Distance Traveled Since November 8 2013") print (70 * 24 * 38108) print ("Q2 Total Distance from sun") print (11710000000 + 70*24*38108) print ("Q3 Ratio of Q1 to Q2") print (1.0 * 70 * 24 * 38108 / (11710000000 + 157*24*38108))
Make the change now and save the Python file. From the menu of the IDLE editor, select Run -> Run Module and you will restart the Python Shell to use the modified module. This is critical because the Python Shell does not automatically re-load the changed module.
When you execute this code, you will see the ratio appear properly as 0.00543751685236. Think about that. In just about two months, Voyager has made just about 0.5% of its total progress since launch.
Can you quickly come up with a ballpark estimate for when Voyager 1 was launched?
Well, if 70 days is 0.54375% of the total distance...
print (1 / 0.00543751685236 * 70 / 365)
Based on this computation, voyager 1 was launched 35.2699 years ago or October 19 1978. Of course, the actual launch date was 1977, but at least you can see how quickly you can come up with a decent estimate.
1.2 Variables
There are other problems with this program, however. If you are not careful, you could easily mistype the numbers in the equations, and it would be nearly impossible to detect that you had made an error.
When working with math equations (since pre-algebra at least!) you are familiar with using variables like x and y to represent values that you use in a computation. You can do the same in every programming language.
In this case, the essential values are speed and distance of the voyager space probe. You also see elapsedTime since November 2013 as another variable.
To set a variable you use the = operator, like the following, which sets the value of x to be 5.
x = 5
Now when you type this statement into an IDLE window, the value of x will be replaced with the value 5 in any subsequent computation.
As you might expect, if you exit IDLE and run it again, this variable definition is lost, much like how the memory on a calculator is lost when you turn it off.
To convert our ongoing program, make the changes as follows:
# Assignment: Lecture Example # # This program computes distance for Voyager. # Note that all comments start with a # character # useful variables speed = 38108 elapsedTime = 70*24 distance = 11710000000 print ("Q1 Distance Traveled Since November 8 2013") print (speed * elapsedTime) print ("Q2 Total Distance from sun") print (distance + speed * elapsedTime) print ("Q3 Ratio of Q1 to Q2") print (1.0 * speed * elapsedTime / (distance + speed * elapsedTime))
No doubt you should find this program easier to understand, because numbers are replaced with names that reflect real-world concepts.
Even here I can make improvements, because you could introduce additional variables for Q1 and Q2.
# Assignment: Lecture Example # # This program computes distance for Voyager. # Note that all comments start with a # character # useful variables speed = 38108 elapsedTime = 70*24 distance = 11710000000 print ("Q1 Distance Traveled Since November 8 2013") Q1 = speed * elapsedTime print (Q1) print ("Q2 Total Distance from sun") Q2 = distance + speed * elapsedTime print (Q2) print ("Q3 Ratio of Q1 to Q2") print (1.0 * Q1 / Q2)
And now one final change. Since you are aware that you are computing approximate values in all of these cases, you could choose at the outset to represent values as float, and then you won’t have to worry about integer division errors. Here is the final program.
# Assignment: Lecture Example # # This program computes distance for Voyager. # Note that all comments start with a # character # useful variables speed = 38108.0 elapsedTime = 70.0 * 24 distance = 11710000000.0 print ("Q1 Distance Traveled Since November 8 2013") Q1 = speed * elapsedTime print (Q1) print ("Q2 Total Distance from sun") Q2 = distance + speed * elapsedTime print (Q2) print ("Q3 Ratio of Q1 to Q2") print (Q1 / Q2)
At this point, then, you can understand that a Python program is a sequence of statements, executing one after the other. As variables are defined, they can be used in subsequent computations.
1.3 Modules
You’ve seen me use the word "module" in reference to this program. In python a module is any file that you create in which you store python program statements. And in CS 110x, we will only create modules that are composed of variables and functions.
In this whirlwind of an introduction, I wanted to make sure you had seen functions before the weekend. The reading covers this topic, so be sure you follow up there.
A function is a way to group a number of Python statements together into a named entity. You have already seen the print function. Python allows you to define as many functions as you would like, and you can take advantage of this mechanism to better organize your code and build modules that can be reused in multiple situations.
Let’s restructure this module and describe what we have done.
On each subsequent line, the ⇒ symbol means indentation and I have only shown it here as a reminder of how to use indentation in Python, and why you should always use IDLE to write your Python programs. It will automatically indent for you when needed.
This module defines a new function voyagerStatus using the def Python keyword, followed by the name of the function and parentheses "()" to declare that a function is about to be defined. This definition line must close with a colon. Each programming language defines functions using a specific syntax, and this is the Python syntax.
Python uses indentation to group a sequence of statements into a single body. We use words like "the body of the function" to refer to the sequence of indented statements. Each function has a name that uniquely identifies the function. In this case, the name of the function is voyagerStatus.
How do you know that you must indent? Look for the ":" colon character at the end of the def voyagerStatus() definition. This is the signal that what follows must be indented.
If you open up a new IDLE editor and start typing the Python program that you see here, it automatically indents each line after you type the ":" and press return.
How do you know when the indented block ends? Well, the indented block continues as long as each subsequent line is (a) indented at the exact same number of characters; or (b) empty or entirely composed of "whitespace" characters like spaces and tabs; or (c) the end of the module file is reached.
So the simplest way to "stop" an indented block is to backspace to the beginning of the line.
The IDLE editor by default uses 4-spaces as the indentation, and it automatically indents for you when you are typing the code into the window. This is a huge convenience. Please avoid the misguided temptation to use Notepad to complete your python exercises for this course. Doing so will only lead to wrack and ruin (as well as poor grades).
1.4 Python 2.7 vs. Python 3.0
We are using the 2nd edition of the book, which has been upgraded to be compatible with Python 3.0. Unfortunately, the free software that we are using for the course is Python 2.7.3. There are some differences, which will likely frustrate you if you don’t understand the differences.
I am compiling a list of these differences that affect the examples that you will find in the book (and, no doubt, via the Internet). Please review these first when you have a question about code from the book that doesn’t work as advertised.
1.5 Debugging Challenge
With new constructs, you are going to make mistakes. How can you spot them? Consider the following program. Can you spot three defects?
Press To Reveal
Defects
Make sure you can spot these kinds of defects, because I will be asking a question like this on homeworks and the exams.
1.6 Skills
IO-1: Know how to print information to the console window
DS-2. Know basic mathematical operators {-, +, *, /, **}
PS-11. Understand operator precedence and use of parentheses for clarity
PF-1: Know how to define a function
PS-9: Understand how indentation identifies body of statements
DG-1: Identify an arithmetic defect
DG-3: Identify syntax defect
1.7 Self Assessment
Given the skills that you are learning through the readings and lecture, you should now be able to write a Python module that solves the following problem. Recall that a Python module contains Python statements that define variables and functions.
The
Ideal Gas Law
approximates the behavior of many gases under many conditions. You may
remember it from high school physics. The equation is PV = nRT where P is
the pressure of the gas (in standard atmospheres or atms), V is the volume
of the gas (in litres), n is measured in moles (a dimensionless number), R
is the ideal gas constant equal to 0.08206 L * atm * mol-1 *
K-1, and T is the temperature (measured in Kelvin units).
Given this formula, you should be able to compute
the number of moles of gas you have given that: Pressure=1.4 atm, Volume =
500 millilitres, Temperature = 20 degrees Celsius.
Write a program to verify that the actual answer is
n=0.029 moles.
Hint: Make sure you
properly convert units!
1.8 Just For Fun
In this class you will be exposed to a number of programming concepts that are immediately transferable to different languages. This course is not strictly about Python, although that will be the dominant language used in our discussions. I want to prepare you to be ready for MATLAB, Maple, C or any other language that you might run across.
Voyager Distance
If you look at the source for this web page, you will see a Javascript snippet that automatically computes the Voyager distance and updates the web page accordingly.
Compare the computed value on the right with NASA’s own update.
1.9 No class Monday January 20th
As you know there will be no class on Monday January 20th in honor of Martin Luther King Day. I would only ask that you take the time to listen to the full version of his "I have a Dream" speech during the Civil Rights rally on the steps of the Lincoln Memorial in Washington D.C. on August 28, 1963.
1.10 Version : 2014/01/22
(c) 2014, George Heineman