ITEC 120
L12a: Loading Treasures and Rooms from a file

Objectives

After successfully completing this lab you will be able to create objects based on data read from a file, store the objects in an array, and you will perform operations on the array and the objects contained in the array.

Assignment

Dowload these files for this lab: L12aTest.java, quiz_scores.csv, rooms.csv, treasures.csv.

You'll also need FileReader.java from the previous lab. You will also need your Room.java and Treasure.java that you've been working with for the past several weeks.

 

File Format

Consider the table shown below. You probably think about tables as having rows and columns. Tables may also be described as having records and fields where each row in a table represents a record and each column is a field.

 Name 

 Description 

 Value 

 Weight 

 Key

 A golden key   

 25 

 1.25 

 iPod

 Plays music 

 100 

 2.8 

The data in the table above may be represented in a date file with each record on a separate line and each field separated by a delimiter, a character that marks the beginning or end of a unit of data. There are four units of data in the table above: key, description, value, and weight (i.e., each column contains a unit of data). The data in the table is shown below in comma separated values (CSV) format. A comma separates each unit of data (i.e., each field). Note that there are no spaces around the commas.

Key,A golden key,25,1.25
iPod,Plays music,100,2.8

The format of a file defines how the data is represented in the file. If there is no structure to the data we say the file is flat. Data often has structure. Treasures, for example, have a name, a description, a value, and a weight. When a person or a program reads the file the reader must know the order of the fields. For example, the name and the description of a treasure are both strings. Therefore, it is not possible to determine if a string is a name or a descrip­tion. The CSV format relies on the position in the record to determine the field. For the data shown above, the first (leftmost) field is the name followed by the descrip­tion, the value, and the weight.

A data file may define a collection of treasures by storing each treasure in a record and placing each record on a separate line in the file. This format makes the file easy to parse. Parsing breaks a file into parts – the file is parsed into records (one line of text) and each record is parsed into fields.

Each record will have one field for each attribute (name, description, value, and weight). A delimiter must separate each field. Note that the delimiter may not appear in the data. For example, the description may not contain a comma because the comma will be interpreted as a delimiter separating fields. Common delimiters include pipes (|) and tabs as well as commas.

Examine the quiz_scores.csv file. Each line in the file contains a name in the first field followed by a list of quiz scores. Add code to the L12a driver to read and print each line from the quiz_scores.csv file. You did this in the previous L11b lab.

 

Parsing Fields

Now that your driver can read and print each record in the file, we want to process the data to print the high score, the low score, and the average score for each student. This requires the driver to parse the fields in each record (i.e., extract the name and each score in the string that represents the record being processed). Note that the name is a string and each score is an integer. The driver must use the correct Scanner method to retrieve the appropriate data type (read the name as a string and read each score as an integer). The driver must also call the useDelimiter method to change the Scanner's delimiter to a comma and use the Scanner's hasNext method to determine when all of the scores have been processed. These details were described in the previous L11b lab. (Note: You do not need an array to do this. Simply process the data as you read it. )

Create a nested loop that processes each row in the quiz_scores.csv file. As shown below, the nested loop will print the students name followed by the high score, low score, and average score. You may assume that each row in the file contains at least one score (i.e., there are no empty rows in the data file). A tab separates each field in the output.

Name    High Low  Average
Susan   98   82   94.8
Robert  93   79   86.0

 

Creating Objects

Now that you understand how to parse the data in a file, use the data (shown below) in the rooms.csv file to create a room to represent each record in the data file.

rooms.csv
4
Start room,A cold dark place
Davis 225,A place of higher learning
Davis 231,The Wizard's Lair
End Room,A bright warm place

The first record indicates the number of rooms in the file. For now, read this record but do not process it. The remaining records contain two fields: name and description. Extend your L12a driver to read each record in the rooms.csv file. For each record, create and print a room with the given name and description. Create a "Piece of lint" treasure and pass it to the room constructor. Note that you can reuse the same treasure handle to create each room.

Once you are able to create and print each room, store each room in an array of Rooms. The first record in the file contains the number of rooms which will be the size of the array. Read that first record, create the array, loop through the remaining records, create a room for each record, and put the room into the array.

Write a second loop to process the treasures.csv file. As shown below, each line contains the name, description, weight, and value of a treasure and finally, an integer that represents which room the treasure is placed in. Start by creating and printing each treasure, then modify your loop to put each treasure in the correct room.

treasures.csv
key,opens a secret door,0.5,2,0
iPod,plays music,2.5,75,1
Golden nugget,valuable stone,75,500,3

 

Output

Print each room using the toString method in the Room class. The start room is printed below based on the data shown above. Print a blank line after each room. When all the rooms are printed, print the total number of rooms, the total number of treasures, and the total value and total weight of all treasures as shown below.

Start room – A cold dark place
Treasure: key – opens a secret door
Weight: 0.5    Value: 2   

4 rooms with 3 treasures
Total value: 578          Total weight: 78

 

Data Files

You must submit one set of data files, but you may want to create multiple data files for testing. The data files you submit must have 5 or more rooms, 4 or more treasures, and you must have more rooms than treasures. You may not use the example data shown above. Be creative with your rooms and treasures. Note that it is much easier and faster to create data for rooms and treasures than it is to write code to create the objects. Further­more, recognize that your driver may load data for any configuration of rooms and treasures. This is not possible if the driver hard codes the rooms and treasures.

 

Error Checking

Optional Challenge Exercise

Correctly handle the following test cases.


Input Filenames

Optional Challenge Exercise

The name of each data file (rooms.csv and treasures.csv) may be hard coded into the driver. However, the driver could accept filenames from the command line. This will be helpful to test the error checks above because the data for test each error check may be stored in a different file.

As we discussed in class, create default filenames: rooms.csv and treasures.csv. If there are exactly two arguments on the command line, overwrite the default filenames. The first argument contains the name of the file with rooms and the second argument contains the name of the file with treasures.

 

Submit Your Assignment

Submit your Java source code files and all data files to the L12a dropbox on D2L.

The data files you submit must have 5 or more rooms, 4 or more treasures, and you must have more rooms than treasures. You may not use the example data shown above. Be creative with your rooms and treasures.

 

Class Definitions for Room and Treasure

The class definitions for Room and Treasure are shown below. There is no need to recreate these classes - you have already written them. This is just for reference.

Treasure

Instance Variable

Description

String name

the name of the treasure

String description

a short description of the treasure

double weight

number of ounces the treasure weighs

int value

whole number representing the value of the treasure

Room

Instance Variable

Description

String name

a short name that describes the room

String description

a slightly longer description of the room

Treasure treasure

a handle to a single treasure