Thursday, January 12, 2006
Due: Wednesday, January 18, 2006 - 10:00PM
Preliminaries
If you have questions at any point, ask me.
In this lab, you will work on developing an "Electronic Butler" program, which I talked about during our first lecture. You may work with a partner on this lab, as all others. To write the program, follow the steps I have outlined below.
First, download a compiled version of the program and run it so that you understand how it is supposed to function. Here is a JAR (Java archive) file: elecbutler.jar, and here is an input file containing a list of facts: butler.db.
Download both files to a directory somewhere on your local machine.
Open a terminal (DOS console) window and use "cd" commands to change to the directory in which you downloaded the files.
Run the program by typing the following command at the DOS prompt:
java -jar elecbutler.jar
Experiment with the program to see how it works. First you will need to load the database (menu option 1). Then you may use option 5 to print all the facts. Next, you may try the query functionality. For this program, facts are composed of three parts - two noun phrases and a verb phrase (relation) in between. For example, in the statement, "Lord Dunsmore is married to Lady Emily", the first noun phrase is "Lord Dunsmore", the relation is "is married to", and the second noun phrase is "Lady Emily".
To operate the query functionality, you enter three phrases against which the database of facts will be matched. To indicate a wildcard for a phrase, enter just a question mark "?". For example, to query all facts about Lord Dunsmore, enter "Lord Dunsmore", and then "?" and "?", each on a separate line. To find all facts about who is married to who, enter "?" on a line, followed by "is married to", and then "?". To exit the query functionality, just input an empty line.
Developing a Fact class
Now, you will write your own code to develop the program you experimented with above. Log into your CS server account, and open up your Eclipse workspace. In the "lab01" project, create a new class called "Fact".
First, add fields to the class to store the two noun phrases and the verb phrase. (You will probably add three String fields with appropriate names.)
Next add two constructors to the Fact class. The first one should take three String arguments (parameters) and initialize the fields appropriately. The second constructor should take a single Scanner object parameter and read in the field data one line at a time. (Use the Scanner's nextLine() method.) If the first line input is empty, then the constructor should throw a runtime exception (e.g.
if ( nounA.equals("") ) throw new RuntimeException("Empty fact line");
).Now add a simple toString method to the Fact class -- it should put the three phrases together with spaces in between and return the statement as a String.
To help implement the query functionality, fill in the body of the following method:
public boolean compare(Fact query)
. As you may guess, this method takes another triple of phrases (thequery
parameter) and tries to match the current fact against it. It returns true if they match. Use the equalsIgnoreCase method to compare the strings. This method should also handle wildcard matching -- i.e. if the query Fact contains a "?" in one field, it should be considered as matching against the current Fact.Finally, copy the following method into your Fact class (it is used to store the facts in a file, like the butler.db file):
/** * Prints out the fact to an output stream * @param outstream the output stream */ public void printToFile( PrintWriter outstream ) { outstream.println("*"); outstream.println(nounA); outstream.println(relation); outstream.println(nounB); }
public static void main( String[] args ) { Fact[] db = { new Fact( "The sun", "is", "yellow" ), new Fact( "The sun", "is", "a star" ), new Fact( "Bananas", "are", "yellow" ), new Fact( "Monkeys", "like", "bananas" ), new Fact( "Plants", "need", "the Sun" ) }; Fact query1 = new Fact( "the sun", "is", "blue" ); for ( Fact f : db ) if ( f.compare( query1 ) ) System.out.println( f ); Fact query2 = new Fact( "?", "is", "yellow" ); for ( Fact f : db ) if ( f.compare( query2 ) ) System.out.println( f ); Fact query3 = new Fact( "bananas", "?", "?" ); for ( Fact f : db ) if ( f.compare( query3 ) ) System.out.println( f ); }
Developing the ManorDatabase class
Now you will fill in code for a class that represents a database of facts. In your "lab01" Eclipse project, create a new class called "ManorDatabase". Delete the skeleton code that Eclipse provides for you and instead copy and paste the entire code below into the file. Then you must fill in the bodies of any methods that are commented "FILL IN HERE".
/* * ManorDatabase.java * Nadeem Abdul Hamid - Spring 2006 - CSC121 - Berry College * * The manor database program representing a list of facts * * Based on a program developed in "Great Ideas in Computer Science * with Java" by Biermann and Ramm. * */ import java.io.FileReader; import java.io.PrintWriter; import java.util.Scanner; public class ManorDatabase { /* The maximum number of facts that can be stored in the database */ private final static int MAXFACTS = 100; /* Array containing facts in this database */ private Fact[] facts; /* The number of valid facts currently stored in the array */ private int numfacts; /* Initializes the database */ public ManorDatabase() { facts = new Fact[MAXFACTS]; numfacts = 0; } /* Returns the number of facts currently in the database */ public int numOfFacts() { return numfacts; } /* Reads a set of facts from a file */ public void readFacts(FileReader inFile) { Scanner in = new Scanner( inFile ); // FILL IN HERE ********* /* Use the Scanner object to read in a fact. Notice, the Fact class can already read in a Fact from a Scanner object, but the format of the database file is that there is an extra line containing only a '*' (asterix) before each triple of lines for a fact. So in the while loop, you need to try to read in the first line of input and test to make sure it is a '*' (break out of the loop if not). Then pass the Scanner object to the Fact constructor to create and read in a Fact object. Then store the Fact object into the array of facts. */ } /* Inputs a fact from the user (keyboard) */ public void inputFact() { System.out.println("Enter a new fact (nounA/relation/nounB - one per line): "); Scanner kybd = new Scanner( System.in ); facts[numfacts] = new Fact(kybd); numfacts++; } /* Print out all available facts. */ public void printFacts() { // FILL IN HERE *********** /* The output should match the format of my solution that I provided for you. */ } /* Save all facts to file */ public void saveFacts(PrintWriter outFile) { // FILL IN HERE *************** /* Use the printToFile method of the Fact class to save all the facts that are in the array */ } /* Query and print out matching facts */ public void searchFacts(Fact query) { // FILL IN HERE *************** /* This method should compare all the facts in the database to the query and print out any that match. Again, the behavior and output should match the sample solution I provided to you. */ } } |
Putting it all together
Finally, download and copy this Java code file into your Eclipse project: ElectronicButler.java. The easiest way to do this is to save this file on the desktop of your machine, then drag it onto the "lab01" project folder in Eclipse. (If you download and save it directly into your Eclipse workspace folder, you may need to choose the "Refresh" option from the "File" menu in Eclipse to see the file added to your project.)
You should now be able to run the Electronic Butler program yourself.
Homework Exercises
Complete the following exercise by the due date at the top of this page and copy it into the appropriate submit folder on the CS server. Also, email me a copy of your source code file, just in case. (After we get the CS server set up properly, you will not need to do this again.)
- [50 points] (Exercise P8.18, page 318 in the textbook.) Magic
squares. An n x n matrix that is filled with the
numbers 1, 2, 3, ..., n2 is a magic square if the
sum of the elements in each row, in each column, and in the two
diagonals is the same value. For example,
16 3 2 13 5 10 11 8 9 6 7 12 4 15 14 1 - Did the user enter n2 numbers for some n?
- Do each of the numbers 1, 2, ..., n2 occur exactly once in the user input?
- When the numbers are put into a square, are the sums of the rows, columns, and diagonals equal to each other?
Here is my compiled solution to this assignment. Your solution should work exactly the same way. If you find something wrong with the way my program works, let me know. If you don't understand some feature of how the solution works, please ask me by email or in person.
- Sample solution: NumberSquare.class
To run this solution, at a terminal, change to the same directory
as this class file and then type java NumberSquare
.
Files to Submit
- Source code file(s) for the homework exercise above. The main class should be in a file named NumberSquare.java.