This is an individual lab.
Most people are used to calculators which have parentheses so users can control the order of operations. For example, you might enter 3 + (4 * 5) to compute 23. An alternative that was popular decades ago was to use RPN which allowed you to enter the numbers and then apply operations. The HP-35 was one such calculator. See this HP-35 emulator. To use it, click on the 3, ENTER↑, 4, ENTER↑, 5, ×, +, and notice the calculator displays 23.
You are being given an implementation of a similar calculator. For most
students, you will get the code through GitHub Classroom, but this code
is also available in the file calculator.zip. While
this calculator uses RPN, it has other key differences from the HP-35.
You will not attempt to emulate the HP-35. Instead, you will extend the
provided calculator so it supports undo and redo through the Command
pattern.
To get started, check out (or download) the code and open the project in
IntelliJ. Attempt to build CalculatorTest. If you have errors saying
"package org.junit does not exist", then open
CalculatorTest.java (in IntelliJ) and select
"Add 'JUnit5' to classpath". This will cause IntelliJ to prompt you
to download the library from the Maven Repository; click OK. Once
built, right click on CalculatorTest in the project browser and
execute all of the tests. These test just the basic calculator
operations; they do not test undo and redo. You will test those in other
ways.
Once the built-in tests are working, confirm that your calculator works through the console. Run the program and enter the bold-face text as shown below:
4,5*
Display: 4
Multiply
Display: 20
q
Quit
Final result: 20
To compute "(18 - 3) * 2", enter
18,3-2*q
Note the comma (,) roughly corresponds to the "ENTER↑" command on the HP-35; it signals that a complete number has been entered. Note that values are being placed on a stack; try
2,3,4,5*-+q
Note that the - computes 3–20; that is, the current display is subtracted
from the next value on the stack. Operations take the top one or two values
from the stack, compute the result, and put the result back on the stack.
The calculator then displays the top value on the stack.
So you have an idea of where you are headed, the following shows what happens if the user decides to add instead of subtract and then goes on to do other operations:
18,3–2*
Display: 18
Subtract
Display: 15
Multiply
Display: 30
u
Undo
Display: 2
u
Undo
Display: 15
u
Undo
Display: 3
+
Add
Display: 21
2
*
Multiply
Display: 42
q
Quit
Final result: 42
Note that undoing the multiply (after displaying 30) results in displaying a 2 in the middle of this run; this is the value currently on the top of the stack.
Main.java for the list of commands and their effects. The
commands echo to the screen; on a real calculator, these would be
replaced by (say) lights that show particular operations have been
executed. You will not make any changes to Main.java.Calculator.java. This implements a
domain-level class capturing the calculator behavior, and its behavior has
been approved by your clients. Actions like adding numbers go through
class Calculator - every operation you implement will use Calculator
methods to get their work done.Main.java methods call CalculatorManager.java to actually
manipulate the calculator. You will make several changes to this file.
Note Main.java already has code invoking undo and redo on the manager.
The manager is to display Nothing to undo or
Nothing to redo if appropriate, otherwise it uses the history to
undo/redo the last result.History.java is the History class from the
phonebook example
with class Command renamed to CalculatorCommand. You should not
need to make any changes to History.java or CalculatorCommand.appendDigit, the calculator
should be in the state that allows new numbers to be entered
(newNumber should be true). That is, undoing most operations
means that the next digit starts a new number. Undoing appendDigit
should leave the next digit state as it was before the appendDigit
command was executed. That is, appendDigit will need to save and
restore Calculator.newNumber.Nothing to undo
or Nothing to redo (as appropriate).Main.java, and
implementing unexecute will boil down to figuring out what data to save
in execute and restoring the appropriate items in the unexecute. Remember
to call class Calculator methods to do the work.Main.java to use the add command rather than simply adding
values. Make sure you can handle an input sequence like 3,4+ud.NOTE: Do not change any files in the .github folder and do not
change Calculator.java, Main.java, or History.java. If you do make
changes to these by mistake, please talk to your instructor and they will
assist in correcting the issue.
Before submitting, check that your solution ran correctly. Assuming your instructor is using GitHub Classroom, tests are run on each commit. You must confirm that the tests ran successfully:
classroom.yml, this means all tests passed. A red plus indicates at least one test failed.run-autograding-tests.> symbol by Autograding Reporter and scroll to the bottom to see the Test runner summary. Passing tests show the same number in the Test Score and Max Score columns. You can see the number of tests that pass on the Grand total tests passed line. This example shows that just one test passes so more work is needed.console_test folder in your project. The inputs and expected outputs for each test run are in this folder.Repeatedly commit your code until all autotests pass. You can get partial credit for most tests passing, but once you get one test passing it is usually straightforward to get the others to pass as well. If you cannot, talk to your instructor! They often can help you narrow down the problem.
Once your solution is working, make sure you have satisfied your instructor's coding standard. Some common issues:
private or protected.Calculator.java or the unexecute does anything but reset elements of the calculator state, you probably are not using the pattern effectively.
In most cases, your code is submitted through GitHub Classroom. Be sure to answer any questions in Canvas to finish the assignment.If one of the runs shows an error, it is challenging to look at the output captured by GitHub to determine what went wrong. A much easier way is to run the code on the sample input in IntelliJ where you can use standard debugging tools. Note the inputs and expected outputs are in the console_test folder.
Typing a long input into IntelliJ is slow and error-prone. To run your code on a sample input file,
The most frequent issue is failing to reset everything the calculator changes when executing an operation. For example, it is often not enough to save and restore the accumulator and the display, you also have to save and restore other flags. But do remember there is a requirement to not save and restore everything on each command. That might result in the correct output, but it does so at the cost of requiring a lot more memory than necessary. This would not be an issue for small computations, but can become an issue for very large ones. So be careful to review the above requirements about saving and restoring data.
From time to time we may need to update the starter code used for this assignment. If this happens, we will suggest updating your repository to merge the changes into your project. The steps for doing this: