This assignment consists of two parts: "porting" Unicalc to Java and writing a closed-list Queue class. The key ideas are that a lot of the functionality that's available in Rex is also available in Java, but Java makes it easier to write code that takes advantage of side effects (like closed lists). In addition, it is meant to provide more practice with Java references and Java syntax so that they will be less of an issue in the graphical programs coming up.
For this assignment, you will need to create two files, named Unicalc.java and Queue.java.
To submit the files, you will need to run
cs60submit Unicalc.javaand
cs60submit Queue.java
Be sure your files are named as indicated above, because our scripts that sort the files into appropriate places will depend on that name to determine which file you are submitting.
In each case, be sure to input that the assignment number is 4.
Test cases for each of the (two) classes you're writing in this assignment
appear in the directory
/cs/cs60/as/a4 . In the files Unicalc.examples
and Queue.examples there are main functions with
a number of print statements that will test your Unicalc code and your
Queue code.
In Queue.examples there is also a toString method, which
you should use in your Queue class (that way everyone's Queue
printing will be consistent).
To test your java code (once the appropriate mains are in your code), you can simply run it and compare your output with the correct output in either Unicalc.out or Queue.out. Or, you can let the machine compare the outputs for you with
% java OpenList | diff - /cs/cs60/as/a4/Unicalc.outor
% java OpenList | diff - /cs/cs60/as/a4/Queue.outIf you see nothing (that is, no "differences" occur), you know your code is producing the correct output. If you do see lines beginning with "<", they are output lines that your program printed , but do not appear in the answers file. Lines beginning with ">" appear in that file, but not your program's output.
Write a java class named Queue that implements a closed-list version of a Queue. Recall that a Queue is a list in which data are added (enqueued) at the back and removed (dequeued) from the front.
As a starting point, you might want to consider the Stack class covered in class and available in /cs/cs60/as/a4/Stack.java. You may also want to consider the suggestion that your Queue class have two QCell data members: front and back.
In any case, you need to have/do the following things in your Queue class:
static void enqueue(Object o, Queue Q) {...}
and
void enqueue(Object o) {...}
static Object dequeue(Queue Q) {...}
and
Object dequeue() {...}
Both methods should return null if dequeue
is called on an empty Queue. They should
also print a warning message of some sort in that case.
static boolean is_empty(Queue Q) {...}
and
boolean is_empty() {...}
You can test your Queue class with the toString and main methods in the /cs/cs60/as/a4/Queue.examples file. The correct output for the printing statements in that main method are both in a comment at the bottom of that file and in the file /cs/cs60/as/a4/Queue.out .
The completely optional extra credit involves extending your Queue class. See problem 3 for a description.
The second problem is to write a class named Unicalc in a file named Unicalc.java. NOTE: you should include in your Unicalc.java file the OpenList class you wrote for Assignment 3. If you'd rather use the solution OpenList class, it's available in /cs/cs60/as/a3/OpenList.sols . You will use Open Lists to handle the data (units, quantity lists, etc.) for the Unicalc application.
Your Unicalc class is an "execute-only" class. That is, no objects fo type "Unicalc" will be made and there will be no nonstatic mathods in the Unicalc class. Instead, the Unicalc class will be written so that its main method can test several static methods that implement Unicalc's functionality.
Thus, you need to write seven methods (in addition to main) in your Unicalc class. Feel free to write any additional functions you may need to implement these seven:
(1) static OpenList simplify(OpenList L) {...}
(2) static OpenList multiply(OpenList L, OpenList M) {...}
(3) static OpenList divide(OpenList L, OpenList M) {...}
(4) static OpenList conv_unit(String s, OpenList db) {...}
(5) static OpenList norm_unit(String s, OpenList db) {...}
(6) static OpenList norm(OpenList QL, OpenList db) {...}
(7) static void convert(OpenList FromQL, OpenList ToQL, OpenList db) {...}
To start you off, the simplify method will be covered in class and available in /cs/cs60/as/a4/Unicalc.examples. I would suggest simply copying the simplify and main methods into your Unicalc class and compiling and running the code. Be sure that any lines in main that call methods other than simplify are commented out. Once this is working, you can add the rest of the functions above, as well as any helper functions you might want.
Keep in mind that all methods in your Unicalc class will be static. And, because you'll never create a Unicalc object, you do not need to write any constructors... .
You may want to write additional methods in your OpenList class (for example, second and third). Feel free to add whatever functionality you might need to your OpenLists.
For example, suppose that QL is an OpenList that is a quantity list. Then, QL.first() returns an Object that is really the amount portion of the quantity list. In reality, that is a Double object. As mentioned in class, Double is a "wrapper class" for the ordinary double data type that hold floating-point numbers.
To get at the Double object, you will need to
cast the returned Object to a
Double Amt = (Double)(QL.first());
You can use the doubleValue() method to
get the value:
double d = D.doubleValue();
will assign the value of the Double D to the double
d. Then, you can multiply or divide d by other
doubles, e.g.,
d = 1.0/d;
However, in order to put the resulting double value (call it
d again) into a Polylist, you will need to again make a
Double object (called a "wrapper") out of it, e.g.,
Double newD = new Double(d);
then it can be placed in an OpenList:
OpenList newQL = new OpenList(newD, ..., ...);
OpenList N = (OpenList)(QL.second());
as long as the method second is defined appropriately.
(Individual elements of these numerator and denominator lists
will have to be cast to Strings.)double evaluate()What evaluate does is return a double that is the "value" of the Queue that invoked the method (the "this" Queue). That is, evaluate looks through the items on its Queue one by one as if they were forming an arithmetic expression. Then it evaluates that expression. You can assume that every data element in the Queue will be either a Double or a String that is one of "+", "-", "*", or "/". The "*" and "/" should be executed immediately -- at highest priority -- and the "+" and "-" have lower priority. For example, if the Queue Q consisted of
10 + 4 * 5 / 2 - 3where the left is the front of the Queue and the right is the back (most recently inserted elements), then Q.evaluate() should go through these steps:
10 10 + 4 10 + 4 * 5 == 10 + 20 10 + 20 / 2 == 10 + 10 10 + 10 - 3 == 20 -3 20 - 3 == 17Any implementation that provides the correct answer (17 in this case) is all right.