In this ICS4U Grade 12 Computer Science lesson you will be learning how to
Text files can be accessed using two different methods
In this course, we are only going to look at Sequential Access
One of the more frustrating aspects of FileIO is making sure Python can actually find the data file. In this course I would recommend putting the file in same directory as your program (or maybe a subdirectory). If you do that it “should” be easy for python to find the file
Suppose you had information stored in a file on your computer called “data.txt”
If the file is in the same directory as your python program, then the following code would open the text file for reading
file = open("data.txt","r")
If the file is in a subfolder that is in the same directory as your python program, then the following code would open the text file for reading
file = open("MyFiles/data.txt","r")
Once the file is open you can use the readline() function to get the data from each line of the file. Every time that function is called, it reads the entire line of the file as String, then puts the file pointer to the next line of the file. Basically it is acting exactly like an input() function that you’ve been using to get data from the keyboard.
In order to successfully read and process data from files your program needs to know how the data is formatted.
In this example, lets assume that you know exactly how many lines are in your data file. This is easy because we can just use a counted loop that executes as many times as there are lines in the file. In that loop you would want to call readline() and then store that String somewhere. Likely a list so you can process it after the fact.
Let’s look at a data file that contains a list of 10 integers
You need to create this file. If you want to use the python editor below on the web, just click the + button on the right hand side of the editor and it will create a text file that you can rename whatever you want. (If you want to try on your computer then you can just create a file using any text editor)
Enter some integers, one per line, into your file and execute the code below to see what happens
#Open the file for reading
file = open("data.txt","r")
#Make an empty list to store the data
x = []
#Read the 10 lines of the file and append to the list
for i in range(0,10):
x.append(file.readline())
#Done reading so close the file
file.close()
#Print the results of the read to the screen
print(x)
Now if you look at your output you will see that it read the values and stored them in the list, but they are stored as strings, and also have the new line character attached to them. We need to strip that new line character and convert each number to an int.
Modify your code as follows and run the program again. Now you will notice you have a true list full of 10 integer values.
#Open the file for reading
file = open("data.txt","r")
#Make an empty list to store the data
x = []
#Read the 10 lines of the file and append to the list
for i in range(0,10):
x.append(int(file.readline().rstrip("\n")))
#Done reading so close the file
file.close()
#Print the results of the read to the screen
print(x)
Sometimes you will have a file that you won’t know how much data is it when the program is written, or maybe the number of entries in the data file changes every time the program is run. Perhaps its storing user data and users are constantly being added or deleted.
A simple way to handle that is to read a line of the file. And if it reads as a blank line, assume you are at the end of the file and stop reading.
Take the same data file you were using in the previous activity and modify your code to as follows.
#Open the file for reading
file = open("data.txt","r")
#Make an empty list to store the data
x = []
#Read until a blank line is found
#Only append when there is data found
while True:
line = file.readline()
if line == "":
break
else:
x.append(int(line.rstrip("\n")))
#Done reading so close the file
file.close()
#Print the results of the read to the screen
print(x)
Run the code several times and after each run, change the amount of data in the file and you should see that this code handles that change just fine.
Lets say in this example you have a data file that includes information about a person’s first name and their bank account balance. The data looks as follows in the file
The program we will write will take that information and then find out who has the most money
The general strategy would be to read the line and then use the split() function on that String to separate the data into its pieces (tokens).
#Open the data
file = open("data.txt", "r")
#Lists to store names and bank info
name = []
bankAmount = []
#Loop for as much data as is in the file
while True:
line = file.readline()
if line == "":
break
else:
#Split the line into tokens delimited by blank spaces
tokens = line.split(" ")
#The name is the first token
name.append(tokens[0])
#The bank value is the second token, but it has the \n attached to it
bankAmount.append(float(tokens[1].rstrip("\n")))
#Done with reading
file.close()
#Now process the data to solve the problem
#Find max bank account value
maxBank = max(bankAmount)
#Find the location in the list for that value
location = bankAmount.index(maxBank)
#Get the person at that location
maxPerson = name[location]
print("The person with the hightest bank account is:", maxPerson)
Let’s say that in the example above you didn’t want the data into two separate lists, but you wanted it stored in only one, 2D list.
#Open the data
file = open("data.txt", "r")
#2D list to store the data
bankAccount = []
#Loop for as much data as is in the file
while True:
line = file.readline()
if line == "":
break
else:
#Create a blank row for the 2D List
row = []
#Split the line into tokens delimited by blank spaces
tokens = line.split(" ")
#The name is the first token
theName = tokens[0]
#The bank value is the second token, but it has the \n attached to it
theAmount = float(tokens[1].rstrip("\n"))
#Append the data to the row
row.append(theName)
row.append(theAmount)
#Append the entire row to the 2D List
bankAccount.append(row)
#Done with reading
file.close()
#You can see the structure of the 2D list with this if statement
print(bankAccount)
#You can see that you can access each invidividual value using a nested loop
for i in range(0,len(bankAccount)):
for j in range(0,len(bankAccount[i])):
print(bankAccount[i][j],end = " ")
print("")
When you want to write data to a file there are two options
Note: If the file you are opening for writing doesn’t exist, it will make it for you.
#Opens a data file to write to
file = open("data.txt","w")
#Opens a data file to append to
file = open("data.txt","a")
The function you need to write data is the write() function.
No data is actually written to the file itself until a close() function is called. So don’t forget that.
The following example just writes some random data to a file named “dataOUT.txt”
#Open the data
file = open("dataOUT.txt", "w")
#Some data to write to the file
x = "Paul"
y = 50
z = 25.35
#Write Data to file
file.write(x)
file.write(str(y))
file.write(str(z))
#Close file so it actually writes
file.close()
Perhaps a better way to write data to a file is to form each line of the file and then write the entire line using a single write() function
#Open the data
file = open("dataOUT.txt", "w")
#Some data to write to the file
x = "Paul"
y = 50
z = 25.35
#Write Data to file
line = x + " " + str(y) + " " + str(z) + "\n"
file.write(line)
#Close file so it actually writes
file.close()
In this example it takes data stored in lists and writes the data one per line to a file, delimited by spaces
#Open the data
file = open("dataOUT.txt", "w")
#Data to Write
x = ["Paul", "Jim", "Kevin", "Kate", "Sidney"]
y = [5,15,30,17,20]
#Loop through the data and write it the file [name],[number]
for i in range(0,len(x)):
line = x[i] + " " + str(y[i]) + "\n"
file.write(line)
#Close File
file.close()
Take the code in the previous examples and run it in editor so you can see how the file is created
Try to code the following questions using an IDE of your choice. You will save those files on your computer for future reference.
Each question has:
Try your best to solve the problems yourself without looking at the solutions.
Make sure you test your programs with multiple different inputs to ensure it is functioning properly.
Treat these questions like Math homework (Do as many as you feel you need to do to feel comfortable with the material)
Name Your File: “ICS4UcreateMathQuestions.py”
Write 50 random math questions and their answer to a data file using the 4 main operators. One question per line. Use numbers between 0 and 25. Don’t allow division by zero and round division to 2 decimal spots Spaces between everything
Example:
import random
#File for writing to
file = open("mathQuestions.txt", "w")
#Possible Operators
operatorList = ["+","-","*","/"]
#Loop for 50 questions
for i in range(0,50):
#Get the random values for the question
operator = random.choice(operatorList)
num1 = random.randint(0, 25)
num2 = random.randint(0, 25)
#Calculate the Answers
if operator == "+":
answer = num1 + num2
elif operator == "-":
answer = num1 - num2
elif operator == "*":
answer = num1 * num2
if operator == "/":
num2 = random.randint(1,25) #Avoid a division by zero
answer = round(num1 / num2,2)
#Create question in proper format
question = str(num1) + " " + operator + " " + str(num2) + " = " + str(answer) + "\n"
#Write data to the file
file.write(question)
file.close()
Name Your File: “ICS4UanswerMathQuestions.py”
Take the file you created in the previous example and write a program that will quiz the user with the questions in the file. Make sure it outputs if they got the question correct or not.
#Open the data
file = open("mathQuestions.txt", "r")
#Read all the data into the program
for i in range(0,50):
#Read the data and separate into tokens
line = file.readline().rstrip("\n").split(" ")
#Extract the correct data from the tokens
num1 = line[0]
num2 = line[2]
operator = line[1]
answer = line[4]
#Print the question
print(num1, operator, num2, "= ?")
userAnswer = input()
#Check the answer
if userAnswer == answer:
print("Got it")
else:
print("Wrong, it's ", answer)
import random
#Open the data
file = open("mathQuestions.txt", "r")
#Need to get all the questions into memory first before you can randomize
questionList = []
for i in range(0,50):
questionList.append(file.readline())
#Display the 50 questions in random order
for i in range(0,50):
#Get a random question and remove it for no duplicates
aQuestion = random.choice(questionList)
questionList.remove(aQuestion)
#Separate into tokens
line = aQuestion.rstrip("\n").split(" ")
#Extract the correct data from the tokens
num1 = line[0]
num2 = line[2]
operator = line[1]
answer = line[4]
#Print the Question
print(num1, operator, num2, "= ?")
userAnswer = input()
#Check the answer
if userAnswer == answer:
print("Got it")
else:
print("Wrong, it's ", answer)
Name Your File: “ICS4UcheckAgeFromFile.py”
Create a text file on your computer in some text editor. Fill it with first names and birthdays for a few different people.
Example of what your text file data should look like:
Write a program that reads that text file and prints out the name of all people that have a birthday after July 23, 2014
#Open the file
file = open("birthdayData.txt","r")
#Read for all the data in the file
while True:
line = file.readline()
if line == "":
break
else:
#Split the line into tokens for name and birthday
fileLineTokens = line.split(" ")
#Name is the first token
name = fileLineTokens[0]
#Split the second token into more tokens for day,month,year
birthdayToken = fileLineTokens[1].rstrip("\n").split("/")
day = int(birthdayToken[0])
month = int(birthdayToken[1])
year = int(birthdayToken[2])
#Check for born after 23/7/2014
if year > 2014:
print(name, "was born after July 23, 2014")
if year == 2014:
if month > 7:
print(name, "was born after July 23, 2014")
if month == 7:
if day >= 23:
print(name, "was born after July 23, 2014")
file.close()
Name Your File: “ICS4UsumOfDiceRolls.py”
Two 6 sided dice are rolled an unknown number of times. The values of each roll is organized and recorded in a table like the one shown below
Complete the following tasks:
For example, in the data file that is shown above, the combinations below would have been written to the output file because the maximum value of 35 occurred when these dice combinations occured.
#Open the data file with the dice rolls
fileIN = open("dice.txt","r")
#Read the data into a 2D list
grid = []
for i in range(0,6):
#Split each row values into individual values(they are strings)
row = fileIN.readline().rstrip("\n").split(",")
#Convert into integers
for j in range(0,len(row)):
row[j] = int(row[j])
#Make into a 2D list
grid.append(row)
fileIN.close()
#Find the max value in the 2D list
max = 0
for i in range(0,6):
for j in range(0,6):
if grid[i][j] >= max:
max = grid[i][j]
#Find the dice values where the max occurs and write to the file
fileOUT = open("maxCombo.txt","w")
for i in range(0,6):
for j in range(0,6):
# Dice values are 1 more then index values
if grid[i][j] == max:
dice1 = i + 1
dice2 = j + 1
#Create a line to write to the file
line = str(dice1) + "-" + str(dice2) +"\n"
fileOUT.write(line)
fileOUT.close()
import random
#Create a data file to write to
file = open("dice.txt","w")
#Loop for each row in the data file
for i in range(0,6):
#Create a string of 6 random numbers
line = ""
for j in range(0,6):
# pick any range you want
value = random.randint(25,35)
#Comma delimited except after final number go to new line
if j < 5:
line = line + str(value) + ","
else:
line = line + str(value) + "\n"
#Write the string of 6 comma delimited values to the file
file.write(line)
file.close()