File I/O

Where's My Stuff?

When our programs are run, we usually have a bunch of variables that store numbers, lists, strings and all sorts of other data. But where do you think this data is actually stored?

Our program and the data that our programs have been using is stored in your computer's main memory (really! I mean, where else would you put values that need to be remembered)

RAM!?

Your computer's main memory or RAM (random access memory) is an example of volatile memory.

What are some examples of non-volatile memory

Hard drives, flash drives, CDs and DVDs

Storing Data in Main Memory

What are the consequences of your data being stored in your computer's main memory?

I Want Data to Last Longer Than That

What if we want to persist our data beyond the lifetime of the running program… or through on-off cycles?

File Input and Output

open

Python has a built-in function called open.

A File Object …

Writing to a File

f = open("test.txt", "w")
f.write("I'm in yr filez!\n")
f.write("Writin' some bits!\n")
f.write("...\n")
f.close()

Using open to Write to a File

Let's look at open and write in more detail:

open(filename, mode)

write(s)

Lottery Ticket

Write a program that creates a lottery ticket. The lottery ticket should:

Lucky Number
3
28
33
50
51

Pseudocode #1

"""
create a list of numbers
mix up the numbers
open a file
write out 'lucky numbers' to file
get the last 5 numbers from list
sort them
for each number in list
	write it the number
"""

Pseudocode #2

"""
create an empty list to store numbers
while length of list < 5
	generate a random number
	if the number isn't in the list of stored numbers
		add it
sort numbers
open a file
write out 'lucky numbers' to file
for every number in the list
	write it to the file
"""

Potential Solution

import random

#  generate list of sorted unique random numbers
random_number_list = []
while len(random_number_list) < 5:
    n = random.randint(1, 59) 
    if n not in random_number_list:
        random_number_list.append(n)
random_number_list.sort()

#  write out the list of numbers to a file
file_handle = open('lotto.txt', 'w')        
file_handle.write('Lucky Numbers\n')
for n in random_number_list:
    file_handle.write('%s\n' % n)

How About Some Tidying Up

Can we abstract out some of this code into a reusable function?

Another Version

import random
def unique_random_list(sample_size, a, b):
    """ 
    sample_size is the number of random numbers to return
    a is the start of the pool of numbers to choose from
    b is the end of the pool of numbers to choose from
    """
    numbers = []
    while len(numbers) < sample_size:
        n = random.randint(a, b)
        if n not in numbers:
            numbers.append(n)
    return numbers 

observed = unique_random_list(3, 1, 5)
assert 3 == len(observed)
for n in observed:
    assert 1 == observed.count(n)

Another Version Continued

random_number_list = unique_random_list(5, 1, 59)
random_number_list.sort()
file_handle = open('lotto.txt', 'w')
file_handle.write('Lucky Numbers\n')
for n in random_number_list:
    file_handle.write('%s\n' % n)

BTDubz (re random)

By the way… (of course) there's already a function in the random module that does this:

>>> print(random.sample([1, 2, 3, 4, 5, 6, 7], 4))
[7, 3, 1, 6]
>>> print(random.sample([1, 2, 3, 4, 5, 6, 7], 4))
[7, 5, 4, 6]
>>> print(random.sample([1, 2, 3, 4, 5, 6, 7], 4))
[5, 6, 3, 4]

Reading a File

To open a file in read mode, use "r" as the second argument:

f = open("test.txt", "r")

Reading a File

Once you have a file object (sometimes called a file handle), you can read the contents of a file by: using one of the following methods on your file handle object:

The Easiest Way to Read a File

Once you have a file object, you can actually iterate over the file object itself. That is, you can use a for loop to loop over every line in the file object:

f = open("test.txt", "r")
for line in f:
    print(line)

Using readline

readline() takes no arguments, and it returns a string.

Using readline Continued

To use readline to read the contents of a file, loop forever (or at least until we know that we're at the end of a file! …

f = open("test.txt", "r")
while True:
	line = f.readline()
	if len(line) == 0:
		break
	print(line)
f.close()

Using readline() Continued More!

Using the test.txt file we've used in previous examples:

I'm in yr filez!
Writin' some bits!\n
...

What is the first line that will be printed? What is the actual string representation? How many times will the loop run?

f = open("test.txt", "r")
while True:
	line = f.readline()
	if len(line) == 0:
		break
	print(line)
f.close()

Reading a File in All At Once

Use the read() method on your file handle object to read the file in all at once. read() returns the entire contents of a file (including newlines) as a string.

f = open("test.txt", "r")
contents = f.read()
print(contents)

Reading a File in All At Once

Use the readlines() method on your file handle object to read the file in all at once as a list, with each line being a single element in the list.

f = open("test.txt", "r")
lines = f.readlines()
for line in lines:
	print(line)

Memory Efficiency

Which function uses more main memory, readline or read/readlines? Why?

Some Notes…

A File Object and For Loops

Again, a file object is itself an iterable (you can loop over it using a for loop)… and it reads in chunks of the file as you go along

f = open('my_file.txt', 'r')
#  read chunks at a time
for line in f:
  print(line)

Creating Text Files with IDLE

Some of these exercises require you to work with existing text files. So, how do you create these files? →

IDLE can be used to work on files that aren't Python programs. To save a plain text file

(You can also open file that aren't .py or .txt in IDLE, as long as they're just plain text)

Multiple File Objects

You can have more than one file object open at a time. The following example:

input_file = open('readme.txt', 'r')
output_file = open('writeme.txt', 'w')
for line in input_file:
    output_file.write("{}!\n".format(line))

File System and Paths

Oh… make sure you know about your file system and how paths work (see these slides!)

An Exercise

Reading and Writing

The contents of names.txt (download and save to where your program is) will be:

Erin
Charles 
Bob
David
Alice

A Potential Solution

file_in = open("names.txt", "r")
names = file_in.readlines()
#  or alternatively...
#  contents = file_in.read()
#  names = contents.split("\n")
names.sort()
file_in.close()
file_out = open("names_sorted.txt", "w")
for name in names:
        file_out.write(name + "\n")
file_out.close()