CSCI162 - Lab 10 1 Lab 10: Prefix Evaluator 1 Objective In this assignment you will read and figure out how to use several classes that I provide, write your own class from scratch, and implement a...

1 answer below »
CSCI162 - Lab 10 1 Lab 10: Prefix Evaluator 1 Objective In this assignment you will read and figure out how to use several classes that I provide, write your own class from scratch, and implement a classic use of recursion. 2 Background: Prefix Expressions In last week’s lab we evaluated postfix expressions, where the operator comes after the operands. The same person who invented them also invented prefix expressions, where the operator comes before the operands. Here is an example: + - 5 3 * 8 2 Like with postfix expressions, no parenthesis are needed. This means that we should first subtract 3 from 5, then multiply 8 by 2, then add those two results, like this: + - 5 3 * 8 2 + 2 * 8 2 + 2 16 18 You wouldn’t be able to solve this using the algorithm that we wrote for postfix expressions. Surprisingly, there is a different stack-based algorithm that will work. But we are going to solve the problem in a different way, by using recursion. (There is actually a hidden stack in all recursive programs: the call stack, in which the computer remembers all of the method calls that are waiting to finish.) 3 Setup Create a new Java Project (Lab10). Download the Lab10Files.zip file, unzip it, and place the files it contains into your project’s source folder. You should have the following files: Token A class that represents a component of an arithmetic expression (same as Lab 09) TokenScanner A class that breaks apart a mathematical expression into individual tokens (same as Lab 09). P02TestFunctionality My tests for the class that you will write. PrefixProgram A very simple program you can run to manually test your code. CSCI162 - Lab 10 2 4 Class Specifications You must create your own class, which must be named PrefixEvaluator. This class has two required methods: 1 /** 2 * E v a l u a t e s a p r e f i x m a t h em a t i c al e x p r e s s i o n . 3 * 4 * @param i n p u t A S t r i n g c o n t a i n i n g t h e e x p r e s s i o n . 5 * @re turn A S t r i n g c o n t a i n i n g t h e v a l u e o f t h e e x p r e s s i o n , or an e r r o r message i f t h e r e was a p r oblem . 6 */ 7 public static String evaluate ( String input ) 8 9 /** 10 * E v a l u a t e s t h e n e x t sub−e x p r e s s i o n f oun d i n a sc a n ne r . 11 * 12 * @param sc a n ne r A TokenScanner c o n t a i n i n g a t l e a s t one p r e f i x ( s ub )−e x p r e s s i o n . 13 * @re turn The r e s u l t o f t h e f i r s t sub−e x p r e s s i o n f o un d i n t h e sc a n ne r . 14 */ 15 private static Double evaluateSub ( TokenScanner scanner ) The private method is the one that does all of the work, recursively. If the private method finds an error in the input, it should throw an appropriate exception. All the public method does is call the private one and handle errors. Just like the previous lab, it must catch any exceptions that get thrown and instead return exactly the following error messages: input string is empty or all spaces or tabs "No input." NoSuchElementException thrown by TokenScanner "Not enough operands." evaluation ended before end of input "Computed answer, but not all input used." parentheses in input "( has no meaning here." / ") has no meaning here." In the PostfixExpression class it was possible to avoid exceptions entirely. In the PrefixExpression class this is not possible, because the private method must return a Double if it returns at all. So if the private method encounters an exceptional situation it should throw something (probably an IllegalArgumentException) and the public method should catch it. 5 Algorithm And Example What is the simplest possible prefix expression? It’s the same as the simplest possible postfix or infix expression: a single number! So that should be our base case. The value of such an expression is the number itself. An operator leads to the recursive case. We know that the two operands come after the operator, so when we find an operator we should recursively evaluate the first sub-expression after it, then recursively evaluate the second sub-expression after it, then apply the operator to those two results to get our answer. Consider our original example: + - 5 3 * 8 2. CSCI162 - Lab 10 3 ˆ Alice first finds an operator (’+’), so she asks Bob to solve the first sub-expression after it, and waits for his answer. – Bob also finds an operator (’-’), so he asks Cindy to solve the first sub-expression after it, and waits for her answer. * Cindy finds a number (5), and so she answers 5 back to Bob. – Bob thanks Cindy for her answer, and remembers it. Then he asks Dan to solve the next sub-expression, and waits for her answer. * Dan finds a number (3), and so he answers 3 back to Bob. – Bob thanks Dan for his answer, and remembers it. Then he applies his operator (’-’) to the answers he got from Cindy (5) and Dan (3). Then he answers 2 back to Alice. ˆ Alice thanks Bob for his answer, and remember it. Then she asks Ellen to solve the next sub-expression, and waits for her answer. – Ellen finds an operator (’*’), so she asks Fred to solve the first sub-expression after it, and waits for his answer. * Fred finds a number (8), so he answers 8 back to Ellen. – Ellen thanks Fred for his answer and remembers it. Then she asks Gail to solve the next sub-expression, and waits for her answer. * Gail finds a number (2), so she answers 2 back to Ellen. – Ellen thanks Gail for her answer, and remembers it. Then she applies her operator (’*’) to the answers she got from Fred (8) and Gail (2). So she answers 16 back to Alice. ˆ Alice thanks Ellen for her answer, and remembers it. Then she applies her operator (’+’) to the answers she got from Bob (2) and Ellen (16), and concludes that 18 is the value of the entire expression. 6 Grading AutoLab Problem Points Autograded Description 01 structure 2 yes Does the program have the right components? 02 functionality 88 yes Do the methods work? 03 style 10 partial Is the program written with good style? Note that a non-recursive solution will earn no points, even if it solves the problem. 7 Submitting Your Work Make sure that you have submitted your final version of your file to AutoLab, and that you have 100/100 autograded points. You do not need to submit your work through D2L – I will look at whatever your last AutoLab submission is.
Answered Same DayNov 19, 2021

Answer To: CSCI162 - Lab 10 1 Lab 10: Prefix Evaluator 1 Objective In this assignment you will read and figure...

Ayush answered on Nov 22 2021
151 Votes
72154/72154/desktop.ini
[ViewState]
Mode=
Vid=
FolderType=Generic
72154/72154/P02TestFunctionality.java
72154/72154/P02TestFunctionality.java
package com.company.STACK.INTERN;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
/*
 * You must include the Junit4 library to use this test unit.
 *
 * To add it, select the project and then choose Properties... from the File menu.
 * Click on "Java Build Path" in the panel at the left.
 * Select Libraries fr
om the list at the top.
 * Select Add Library... from the right side of the panel.
 * Select JUnit and click on Next.
 * Change the version to JUnit 4 and click on Finish.
 * Click on OK in the properties panel.
 * 
 * You can then run these tests using "Run As JUnit Test" instead of "Runs As Java Application".
 */
/**
 * JUnit tests for PrefixEvaluator.
 *
 * @author Chad Hogg
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class P02TestFunctionality {

    /** The maximum allowable difference when comparing doubles. */
    private static final double EPSILON = 0.00001;
    /** The return value when the expression was empty. */
    private static final String NO_INPUT = "No input.";
    /** The return value when there were not enough operands on the stack. */
    private static final String INSUFFICIENT_OPERANDS = "Not enough operands.";
    /** The return value when the answer is infinity. */
    private static final String INFINITY = "Infinity";
    /** The return value when values are left on the stack. */
    private static final String OVERFULL_STACK = "Computed answer, but not all input used.";
    /** The return value when not all input is used. */
    private static final String MORE_INPUT = "Computed answer, but not all input used.";
    /** The return value when a left parenthesis is found. */
    private static final String LEFT_PAREN = "( has no meaning here.";
    /** The return value when a right parenthesis is found. */
    private static final String RIGHT_PAREN = ") has no meaning here.";
    /**
     * Attempts to evaluate a well-formed expression.
     * 
     * @param input The postfix expression to evaluate.
     * @param expected The correct answer.
     */
    private void runTest(String input, Double expected) {
        try {
            String result = PrefixEvaluator.evaluate(input);
            try {
                Double dResult = Double.parseDouble(String.valueOf(result));
                assertEquals("\"" + input + "\" produced wrong answer.", expected, dResult, EPSILON);
            }
            catch(NumberFormatException exception) {
                fail("\"" + input + "\" should have produced a number, not \"" + result + "\"");
            }
        }
        catch(Exception exception) {
            fail("\"" + input + "\" should not have caused a " + exception.getClass() + " to be thrown.");
        }
    }
    /**
     * Attempts to evaluate a mal-formed expression.
     * 
     * @param input The bad postfix expression to evaluate.
     * @param expected The expected error message.
     */
    private void runBadTest(String input, String expected) {
        try {
            String result = PrefixEvaluator.evaluate(input);
            assertEquals("\"" + input + "\" should have produced \"" + expected + "\", not \"" + result + "\"", expected, result);
        }
        catch(Exception exception) {
            fail("\"" + input + "\" should not have caused a " + exception.getClass() + " to be thrown.");
        }
    }

    /**
     * Tests that an addition of two doubles works.
     */
    @Test
    public void test01SimpleAddition() {
        runTest("+ 5.0 7.0", 12.0);
    }
    /**
     * Tests that a subtraction of two doubles works.
     */
    @Test
    public void test02SimpleSubtraction() {
        runTest("- 7.0 5.0", 2.0);
    }

    /**
     * Tests that a multiplication of two doubles works.
     */
    @Test
    public void test03SimpleMultiplication() {
        runTest("* 3.0 2.0", 6.0);
    }

    /**
     * Tests that a division of two doubles works.
     */
    @Test
    public void test04SimpleDivision() {
        runTest("/ 3.0 2.0", 1.5);
    }

    /**
     * Tests that combining two subexpressions works.
     */
    @Test
    public void test05CombiningSubexpressions() {
        runTest("- - 8.0 2.0 + 1.0 3.0", 2.0);
    }

    /**
     * Tests that multiple consecutive operations works.
     */
    @Test
    public void test06ConsecutiveOperations() {
        runTest("/ + - + 5.0 3.0 2.0 6.0 2.0", 6.0);
    }
    /**
     * Tests that more than two initial numbers works.
     */
    @Test
    public void test07ManyNumbersToStart() {
        runTest("+ 3 * 2 + 5 4", 21.0);
    }
    /**
     * Tests evaluating a long expression.
     */
    @Test
    public void test08LongExpression() {
        runTest("+ - + - + 5 * 7 4 * * 3 2 4 5 1 * 6 5", 43.0);
    }

    /**
     * Tests an expression whose value is negative.
     */
    @Test
    public void test09NegativeAnswer() {
        runTest("* - 5 7 3", -6.0);
    }

    /**
     * Tests an empty expression.
     */
    @Test
    public void test10EmptyInput() {
        runBadTest("", NO_INPUT);
    }

    /**
     * Tests an expression without enough numbers.
     */
    @Test
    public void test11Underflow() {
        runBadTest("- + 5 7", INSUFFICIENT_OPERANDS);
    }

    /**
     * Tests an expression involving division by 0.
     */
    @Test
    public void test12Infinity() {
        runBadTest("/ 7 0", INFINITY);
    }
    /**
     * Tests an expression with too few operands.
     */
    @Test
    public void test13NotEnoughOperands() {
        runBadTest("+ 5 3 8", ...
SOLUTION.PDF

Answer To This Question Is Available To Download

Related Questions & Answers

More Questions »

Submit New Assignment

Copy and Paste Your Assignment Here