WEEK07: File I/O, top-down design
---------------------------------------------------------------
W: File Input/Output
- Quiz 3 on FRIDAY
- Lab 6 due Saturday
- craps.py: let's add one more function to the game: what do
we need to do the "play for point" section???
* keep rolling until we get:
7 and lose
original roll and win
* if we make this a function, we'll need the original roll
* if we make this a function, what should it return? Probably
True/False to be like playOneGame()
def playOneGame():
""" Plays a single of craps
Returns True if player wins, False otherwise
"""
print "Playing one game"
roll = rollTwoDice()
if roll == 2 or roll == 3 or roll == 12:
return False
elif roll == 7 or roll == 11:
return True
else:
#play for point
return playForPoint(roll)
def playForPoint(originalroll):
"""
roll dice until we get 7 or original roll.
return True for win (orig roll), False for lose (7)
"""
while True:
roll = rollTwoDice()
if roll == 7:
return False
elif roll == originalroll:
return True
else:
print "rolling again..."
FILE I/O:
- motivations:
* video game data files (read in terrain data; high scores)
* grader.py: store student grade data in a file (don't have to
type it in each time the program runs)
* iTunes: how does iTunes keep track of # of plays for each song??
- files can be just text files, like you edit with vim
OUTPUT:
- here's how to open a file for writing (note: myfile is a variable
name that I choose, and "newfile" is the name of the file to write to):
$ python
>>> myfile = open("newfile", 'w')
>>> type(myfile)
<type 'file'>
(a new python type!!)
>>> myfile.write("write this to the file \n")
>>> myfile.write("and this.... \n")
>>> myfile.close()
- and here are the results of this:
$ ls
newfile
$ cat newfile
write this to the file
and this....
- what happens if we leave out the \n's on each line??
INPUT:
- I have a file called "words.txt" with a few words in it:
$ cat words.txt
happy
computer
lemon
zebra
- to open a file for reading, use 'r' mode:
>>> infile = open("words.txt", 'r')
- file "words.txt" must exist, otherwise we get an error
- note: infile is a variable of type file:
>>> type(infile)
<type 'file'>
- and it can be used as a sequence (in a for loop!):
>>> for line in infile:
... print line
...
happy
computer
lemon
zebra
- we can use the for loop like above, or we could use the
file methods: readline() to read one line
readlines() to read them all at once
>>> infile.close() # need to close and reopen to get back to start of file
>>>
>>> infile = open("words.txt", "r")
>>> word = infile.readline()
>>> print word
happy
>>> word = infile.readline()
>>> print word
computer
>>> infile.close()
>>> infile = open("words.txt", "r")
>>> words = infile.readlines()
>>> print words
['happy\n', 'computer\n', 'lemon\n', 'zebra\n']
- so readlines() reads in EVERYTHING and puts each line into a python list
(NOTE: the newline characters are still part of each line!)
- sometimes you want to read in EVERYTHING, all at once
- sometimes it's better to read data in line-by-line and process
each line as you go (use the for loop: for line in infile)
FILE I/O NOTES:
- reading from and writing to files is usually SLOW
- for this reason, we usually read in data at the beginning of a
program and store it in a list or other data structure (ie, if we
need the data throughout the program, it's much faster to
refer to the list rather than the file)
- also, reading from the file is similar to watching a movie on
VHS tapes -- at the end of the movie, you have to rewind the tape
to get back to the beginning. Once we do that "for line in infile"
loop above, we are at the end of the file. You can "rewind" the
file by closing and reopening it (or use the seek() method in python)
EXAMPLE:
- suppose we have a file of usernames and grades, like this:
$ cat grades.txt
lisa :95
jeff :35
jason :88
adam :97
frances :96
rich :77
- here's a program to figure out the average of those grades:
# store grades in python list, in case we need them later
grades = []
# read all grades into a list
gfile = open("grades.txt", "r")
for line in gfile:
name, grade = line.split(":") # split in two, based on colon
grades.append(float(grade))
gfile.close()
# find ave of grades in list
total = 0.0
for g in grades:
total += g
ave = total/len(grades)
print "ave grade = ", ave
YOUR TURN:
- how would you read in multiple quiz grades for each student,
finding the ave quiz grade for each student?
$ cat quizgrades.txt
lisa :98,100,95,93,99
jeff :58,50,55,53,59
rich :88,78,89,75,79
frances :67,78,89,90,99
$ python quizgrades.py
lisa: 97.0
jeff: 55.0
rich: 81.8
frances: 84.6