CS 110X Feb 06 2014
Expected reading: 152 – 159.
Expected Interactions: Reading files
Writing files
Clicker: Hardware failure in PM section: No Assessment
1 Accessing data stored in a File
1.1 Documenting functions
You have already seen the ability to use comments (#) to provide information about the programs you are writing. However, this information is not available to the Python shell. Specificall, Python simply ignores all comments.
You may have seen the ability in Python to see information about a function simply by typings its name into the shell. For example, type len( and immediately after the open paranthesis, you are shown "Return the number of items in a sequence or mapping". You can provide similar guidance in the functions that you write. In fact, moving forward, you will need to do this for each and every function that you write.
To document a function properly, you need to insert as the first statement of the function a triple-quoted string that briefly describes the purpose of the function. For example:
def someFunction(): """This is a sample function description""" print ("Does nothing really...")
1.2 Loading Lines From A File
Conceptually, a file is a sequence of data that is stored in secondary storage. As you know, files can be incredibly large in size (gigabytes of data for video files, for example).
Python offers a number of convenient ways to retrieve data from a file.
To keep this lecture simple, I’ll only show a small example that loads information from a small text file. Make sure that the small text file simpleFile.txt exists in the exact same folder/directory as the loader.py file, otherwise this code example won’t work.
def loadListFromFile(filename): """Load list of integers from file (one per line)""" inFile = open (filename, ’r’) list = [] for line in inFile: val = int(line) list.append(val) inFile.close() return (list) def main(): """Main function to demonstrate use of loadListFromFile""" myList = loadListFromFile(’simpleFile.txt’) print (myList)
Given your Python knowledge, you should be able to make the appropriate mental map for the above code. The for loop returns each line in the file, one at a time. For each of these lines, the program converts the value into an int and appends it to the growing list. Once done, the File is closed (a necessary step to free up resources) and the loadListFromFile function returns the list that was created.
A line is defined by a sequence of characters up to and including an end of line character. In Python, and most programming languages, this is the special character ’\n’. Yes, that is single-quote, followed by a backspace, followed by a n, followed by a closing single-quote. The ’n’ stands for "new line".
If you are curious, type the following strings into a Python shell and you will see what the character prints.
>>> print (’n’) n >>> print (’\n’) >>>
1.3 Writing Lines To A File
For completion, I need to show how to write information to a file. This has been improved in Python 3.0, but here is how you would do it in Python 2.7.3.
def writeListToFile(): """Write ten integers (0 through 9) to a file.""" #this file is being opened for WRITING outFile = open (’simpleOutput.txt’, ’w’) for val in range(10): outFile.write(str(val)) outFile.write(’\n’) outFile.close()
This time when you open a file by name, you pass a ’w’ argument which stands for "write" mode.
To write a str to the file, use the write command. Note that only you know how to structure the file, specifically, where to insert end of line characters. Python will not make any assumptions for you. Thus you have to manually insert an end-of-line character as shown above after each integer is written to disk.
Once done, the file is closed, and all written values are safely stored to persistent storage.
1.4 Primary storage vs. Secondary Storage
You have already seen a daily demonstration of the difference between secondary storage and primary storage.
Launch IDLE and bring up a Python Shell variable. Now define a variable value = 137.
>>> value = 137 >>> value 137
Where does this "value" exist? As I’ve mentioned in class, if you exit the Python Shell and restart, this variable is no longer present.
All values used by Python are stored in primary memory, also known as RAM. It only exists for the duration of the program, and doesn’t persist on disk beyond individual executions.
As we move into this middle third part of the course, I thought it would be useful to review how variables really store values in primary memory. This will serve as a useful exercise for understanding your own programs.
>>> height = 10 >>> height 10
When a variable is defined, you can imagine that Python sets aside a box in memory for that unique variable. Using a "reference view" style, the following figure shows that the variable height has value 10 because the arrow associates the variable height with the value 10. All variables are identified by a box, and all values are identified by a rounded rectangle.
What happens after the following statement?
>>> height = 11
As you can see, the variable height is now associated with the value 11.
Sometimes this "reference view" is cumbersome to use, and we simplify it using a "box view", like we had used for some of the in-class exercises I did. The above sequence can also be drawn as follows:
And after the variable is updated, the resulting view is:
1.5 In Class Variable Exercise (Clicker)
To make sure you have the ability to simulate the execution of a small code fragment, let’s all try the following code. I intend to hand out a copy of this code for you.
# in class clicker assessment # record xpos/ypos values here xpos = 1 # xpos : 1 ypos = 5 # ypos : 5 while xpos < ypos: xpos = xpos * 2 ypos = ypos + 4 print (str(xpos) + "," + str(ypos))
Let’s take a few minutes so we can work this out.
Then we’ll move to the clicker question; the code example on the clicker question will be different from the above.
1.6 Python Context
This discussion on variables leads us next to talk about how functions can each store their own variables for their needs. These variables defined within a function are kept "under wraps" so they can’t be accessed outside of the function.
Consider the following small example:
def getArea(): """Return area of a rectangle""" height = 10 width = 5 return (height * width) def main(): """Demonstrate local variables""" height=20 area = getArea() print (area)
When the main function is executed, and getArea is about to return the computed area, the following image represents the variables and values known to Python:
Immediately after getArea returns, the following represents the variables and values known to Python:
You should take careful note that the height and width variables are no longer present. Indeed, the image I want you to have is that each function maintains its own context of variables; and when main calls the getArea function, a new "function context" appears, like a "stack".
Whena function completes and returns, its "function context" is removed from the top of the "stack", and the calling function continues executing where it had left off.
We are going to continue this discussion of variables and functions tomorrow.
There is one more point to discuss: global variables. You have seen, twice now, how the template files provided to you for the homeworks contain variable definitions at the end of the module. These variables can be accessed by the functions stored in the same module. Check this out:
# How function sees global variable def main(): """Demonstrate ability to access global variable""" height = 20 width = 10 price = height * width * pricePerSquareInch print ("Costs " + str(price) + " Dollars to ship.") # defined variable for use by any function in this module pricePerSquareInch = 0.25
Note how the main method is able to access the pricePerSquareInch variable, even though that variable is not defined within the function itself.
You can depict this situation using the following variable box view:
In fact, any function that you define in the example.py module will be able to access this variable. It is thus known as a "global" variable within the module.
Common etiquette places these global variables at the start of the module, so they can quickly be known by the users of that module. If the data is large, however, then they are traditionally placed at the end of the module so they don’t interfere with understanding the rest of the functions.
1.7 Version : 2014/02/07
(c) 2014, George Heineman