Objectives

For this assignment, you will:

Description

Your next program is to implement a postfix calculator application. The calculator should take expressions input in postfix notation and display the results of the computation.

In postfix notation, the operator comes after the operands. For example, the expression 3 + 5 would be written as 3 5 +. As another example, the expression 52 − (5 + 7) ∗ 4 would be written as:

52 5 7 + 4 ∗ −

It is not necessary for this assignment that you know how to convert from infix to postfix since you can assume that the user of your calculator will input all expressions in postfix notation. You are only responsible for evaluating such expressions and displaying the result.

Appearance of the calculator program  

Let’s look at a few examples of evaluating postfix expressions using your calculator. To evaluate the postfix expression 3 5 +, the user would click on: 3, enter, 5, +. The enter button is used to signal the end of a number being input. Without the enter, we would not know whether the user was inputting the number 3 or the number 35. The user can also click on an operator button to signal the end of a number being input. Notice that in our example the user clicked the enter button only after the digit 3. After the digit 5, the user clicked the + button. When we see the + button, we know the user has finished entering a number and we can now add those numbers together.

Here is another example. To calculate 3+5*7 (which is written 3 5 7 * + in postfix notation), click on 3, enter, 5, enter, 7, *, +. Again, note that the only thing clicking enter does is to signal the end of the number being input.

A version of this program running as an applet can be found here.

Classes

There are 4 classes for this project: Calculator, DigitButtonListener, OpButtonListener, and State. Of these 4 classes, you are expected to complete the DigitButtonListener class and the State class.

Once you have both of these classes working properly, you must add one or more new buttons to the calculator.

Possibilities include a squaring button, factorial, or xy. You should add the new button so that it looks nice, add an appropriate listener (created from OpButtonListener if you like), and make sure that the state knows how to handle that operation.

Calculator class

We have provided you with the code for the main Calculator class. This relieves you of the burden of layout of the buttons and display of the calculator. We have also included the code for MiscButtonListener as an inner class of Calculator (it is nested at the bottom of that class). The class MiscButtonListener implements the ActionListener interface for the miscellaneous buttons on the calculator: clear, exch, pop, and enter. Read through the Calculator class until you are confident that you understand how it operates.

OpButtonListener class

The OpButtonListener is a listener class for the operation buttons: +, -, *, /. When the user clicks on an operation button, the corresponding listener is responsible for informing the state what operation is to be performed. Read through the OpButtonListener class until you are confident that you understand how it operates. This class provides a useful example for you when you are implementing the DigitButtonListener class.

DigitButtonListener class

This class contains the code to be executed when the user clicks on a digit button. Make sure you understand how the DigitButtonListeners are being used in the Calculator class. Each digit key has its own specialized DigitButtonListener which is responsible for knowing which number key it is listening to. When a button is clicked, the code in the actionPerformed() method is executed. This methods should inform the state what digit has been clicked on so that the state can use the digit to build the number being typed in.

StateTest JUnit class

StateTest is a JUnit test class for the State class. It is partially written for you. You must finish writing unit tests for the remaining methods – i.e. you must fill in the unit tests for the methods that are not yet implemented. As you probably discovered in last week’s assignment, it’s not uncommon to have multiple unit tests for a single method. In the same way, feel free to add additional unit tests to the StateTest class.

State class

A State object represents the memory of the calculator. Its purpose is to keep track of the current state of the computation. For instance, it has to keep track of whether the user is entering a number, and what the number is so far. It must also keep track of the display window of the calculator (a JTextField that displays the current state of the calculator).

The most important feature of the State is its stack, which represents those numbers stored on the calculator. Use java.util.ArrayDeque rather than writing your own stack.

Let’s look at how you would evaluate the example from earlier (3, enter, 5, +). First, you must keep track of the number being constructed. When the enter button is clicked, you know this number is complete. We would then push the number, 3, onto the stack. The next number is a 5. We would push this number onto the stack as well. Finally, since the user clicks + we would pop the two numbers off the stack, add them to get 8, and then push 8 back onto the stack.

Here are some more details:

Getting Started

  1. All startup code is available in /common/cs/cs062/assignments/assignment05. You can copy the starter code using Finder as usual, or you can use the command line (after creating an Eclipse project named Assignment05):

    cp -r /common/cs/cs062/assignments/assignment05/* ~/Documents/cs062/workspace/Assignment05/src

    A quick note about shell commands for the curious: shell commands consist of arguments separated by spaces. So the above command has three arguments:

    The cp command takes all of its arguments except the last one, and copies them into the directory specified by the last argument. The -r argument is called a “flag,” “switch,” or “option” and tells the cp program to trigger some special behavior (in this case, copy things recursively, so target all subdirectories and files under the source file(s) given). You can use the command man <program> to see information about what flags a program accepts and what they do, and most programs also accept either -h or --help and will print out some help text if you give them that argument. Now the * character in the second argument is special: before calling the cp program, the shell application will take the * wildcard character and replace any argument containing it with all possible arguments that fit the pattern given, where the * can be replaced by any valid file or folder. So this command will target all of the files in the assignment05 directory. The ~ character is also special: the shell replaces it with the current user’s home directory. The cool thing about the command line is that you can write a bunch of commands into a file, and then run that file as a script. Essentially, when you use the shell, you are programming. Accordingly, the shell supports things like variables (using $ signs) and you can use it to automate any common task you do on your computer. In fact, if you open up the submit script, you’ll see that it just contains a bunch of shell commands.

  2. You might find it easier to write the code first under the assumption that the user must click the enter button after punching in each number. However, for full credit, it should also handle the case where the user punches in a number followed immediately by an operation. The result should be equivalent to sticking in an intervening “enter”. That is punching in 5, enter, 7, + should give the same results as 5, enter, 7, enter, +. (Think about what pressing the enter key actually does. What is the difference between pressing 3 7 and 3 enter 7? It makes a difference.)

Grading

Criterion Points
JUnit tests for each method in State 3
Digits and enter handled appropriately 3
Arithmetic operations handled correctly 3
Appropriately handle errors and show message 2
Misc keys handled correctly 3
Digit listener 2
Extra method/calculator functionality 2
Appropriate comments (including JavaDoc) 2
Style and formatting 2
Submitted correctly 1
Extra credit 2

NOTE: Code that does not compile will get a zero! Make sure that your code compiles before submitting.

Submitting Your Work

As usual, export the entire folder from Eclipse to your desktop, change the name of the folder to Assignment05_LastNameFirstName where you should replace LastNameFirstName by your own last name and first name. Make sure the folder contains both your .java and .class files in the src and bin directories, respectively. Also make sure that you have your asg05.json file filled out in the top directory of your submission. Once everything’s in place, run the submit script to submit it like so:

/common/cs/cs062/bin/submit cs062 asg05 ~/Desktop/Assignment05_Name

Make sure that you set the ‘ec’ field in asg05.json to true if you attempt the extra credit.

Be sure that your code is clear, formatted properly, and commented appropriately (using Javadoc). See the CS62 Style Guide on the Handouts page for details on what’s expected for comments.

Extra Credit

If you are interested in extra credit, add a decimal point button so that your calculator can handle floating point numbers. Be sure to check that the user does not input an illegal number (e.g., with two decimal points). Possibilities for new buttons with this include square root, trig functions (e.g., sin, cos, tan, etc.), inverse trig functions, xy, ex, factorial, inverses, or logarithms. See the class Math in package java.lang for a list of available mathematical functions in Java. Make sure the basic functions of your calculator are working correctly before moving on to extra credit. You may find the floating point does not work with the auto-grader compatibility test – this is fine, but please name your folder Assignment05_Name_ExtraCredit and set the ec field in your asg05.json file to true so that we can look out for that.