Lesson 6.9
Parse delimited lines into a list or table
Part 6: Errors, testing and filesReading, about 8 min2 exercises in this lesson
Java answers can't run on ExamSpine yet. You can still read Java, trace it, and put an answer's lines in order.
Parse delimited lines into a list or table
By the end of this you will be able to read a file where each line holds several values with commas between them, split every line into its parts, and keep them as a list of rows.
A file like this is called comma-separated values, or CSV. Spreadsheets save to it, and most data you will be given in a file looks like it: one record per line, one field per comma.
How it is asked
As in the last two lessons, no past paper has a file question yet. Our map of the syllabus lists this one as reading a delimited file, such as CSV, into a list or a table. So the task to be ready for is reading a CSV into rows and fields, then answering a question about one field of each row.
Key idea: Split each line on the comma, and each field has its own index.
Split a line into fields
teams.csv has one runner per line: a name, then a team. Step through and watch each line become a list.
In Python, split(",") gives back a list of the pieces between the commas. In Java, split(",") gives back an array of them, a String[]. Either way the commas themselves are gone, and the fields are numbered from 0, left to right.
Take the line end off first
In Python the line end is still on the line when you split it, so it ends up stuck to the last field.
Java's readLine() has already left the line end off, so Java does not have this bug. It has a different one: comparing two strings with == asks whether they are the same object in memory, not whether they hold the same letters. A field cut out of a line by split is a new string, so fields[1] == "Blue" is false even when it holds Blue. Use fields[1].equals("Blue").
A list of rows
To keep the whole file, add each line's list of fields to one outer list. That outer list is a table: rows[r][c] is the field in column c of row r.
rows = []
with open("teams.csv") as f:
for raw in f:
line = raw.rstrip("\n")
rows.append(line.split(","))
print(rows[2][1])import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public static void main(String[] args)
throws IOException {
ArrayList<String[]> rows =
new ArrayList<>();
try (BufferedReader f = new BufferedReader(
new FileReader("teams.csv"))) {
String line = f.readLine();
while (line != null) {
rows.add(line.split(","));
line = f.readLine();
}
}
System.out.println(rows.get(2)[1]);
}It prints Red, in either language. In Java the rows go in an ArrayList, because you do not know how many lines there are before you read them, and each row is a String[].
Headers and empty fields
Real CSV files often start with a header line that names the columns, such as name,team. It is not data. Read it once before the loop and ignore it: f.readline() in Python, or one extra readLine() in Java before the read that starts the loop.
An empty field is two commas with nothing between them. "Ana,,12".split(",") gives three fields in both languages, the middle one empty. But an empty field at the very end of a line is different in Java.
How it is marked
An exam-style question of our own, marked one mark for each point a correct answer must show, as IB computer science markschemes mark code.
Now try it yourself on the questions below.
Exercise 6.9.16.9.1 · Write itSeat finder
The seating plan for an exam hall is saved in seats.csv. Each line of the file is one row of desks, from the front, and holds the names of the students in that row, from the left, with a comma between each name. Write a program that reads a name typed in and says where that student sits.
- Read the name, then read the file into a list of rows, each row a list of its names.
- If the name is in the plan, print
Rowand the row number, then, seatand the seat number, such asRow 2, seat 3. The front row is row 1, and the leftmost seat is seat 1. - If the name is not in the plan, print
Not seated, once. - Rows can have different numbers of seats. An empty seat is an empty field, such as the middle of
Ana,,Cy. A name appears at most once, has no commas, and never starts or ends with a space. The name typed in is never empty. - The last line may or may not end with a line end. There is no header line.
Your program is run several times, each time in a folder that holds only the files shown for that run.
Running Java here comes later. You can put this answer's lines in order instead. You can still write your Java answer (it stays while this page is open) and compare it with our worked solution. Or try this exercise in Python.
Examples
Your program is run 8 times: the 2 examples below, and 6 hidden ones that check the rules above. Only what it prints is checked. Each run starts in an empty folder that holds only the files shown for it.
Hu is in the middle of the third row (rule 2)
You type
- typed: Hu
It prints
Row 3, seat 2
Files in its folder
seats.csv Ana,Bo,Cy Dee,Eli,Fay Gil,Hu,Ivo
Fay is the last name on that line (rule 2)
You type
- typed: Fay
It prints
Row 2, seat 3
Files in its folder
seats.csv Ana,Bo,Cy Dee,Eli,Fay
Exercise 6.9.26.9.2 · Write itClub members
Sign-ups for school clubs are saved in signups.csv. Write a program that reads the name of a club typed in, then prints everyone who signed up for it.
- The first line of the file is a header,
name,club. It is not a sign-up. - Every other line is one sign-up: a student's name, a comma, then the club, such as
Ana,Chess. - Print the name of each student whose club is exactly the club typed in, capitals included, in the order they appear in the file.
- Then print
Members:followed by how many there were. With none, that isMembers: 0. - Names and clubs have no commas, and never start or end with a space. The file may have only its header. The last line may or may not end with a line end.
Your program is run several times, each time in a folder that holds only the files shown for that run.
Running Java here comes later. You can put this answer's lines in order instead. You can still write your Java answer (it stays while this page is open) and compare it with our worked solution. Or try this exercise in Python.
Examples
Your program is run 10 times: the 2 examples below, and 8 hidden ones that check the rules above. Only what it prints is checked. Each run starts in an empty folder that holds only the files shown for it.
two of the three sign-ups are for Chess (rules 2 to 4)
You type
- typed: Chess
It prints
Ana Cy Members: 2
Files in its folder
signups.csv name,club Ana,Chess Bo,Drama Cy,Chess
one sign-up for Drama (rules 3 and 4)
You type
- typed: Drama
It prints
Bo Members: 1
Files in its folder
signups.csv name,club Ana,Chess Bo,Drama Cy,Chess