Anonymous
timer Asked: Apr 14th, 2020

Question Description

In this assignment, you will implement a small subset of the python interpreter. The user should be able to write an expression, and your program will evaluate it.

For example, here is a sample run of the program (the user’s input appears after the >>> prompt):

>>> r = 10
10.0
>>> pi= 3.1416
3.1416
>>> circumference = 2*
62.832
>>> volume=(1 + 1/3) * pi * r*r*r 4188.8

Unformatted Attachment Preview

CS417 Programming Assignment #8 Due on Wednesday, April 22nd. Late penalty: Thu 5%, Fri 10%, Sat/Sun/Mon 20%, Tue 50%, Wed 100% Getting Started Begin by dowloading these two files: calculator.py stack.py Calculator In this assignment, you will implement a small subset of the python interpreter. The user should be able to write an expression, and your program will evaluate it. For example, here is a sample run of the program (the user’s input appears after the >>> prompt): >>> r = 10 10.0 >>> pi= 3.1416 3.1416 >>> circumference = 2* pi *r 62.832 >>> volume=(1 + 1/3) * pi * r*r*r 4188.8 Specifications The calculator should accept ordinary infix expressions with the following parts: Variables Variable names must qualify as valid python variables: they must start with a letter or an underscore the remaining characters (if any) may be letters, digits, or underscores Numbers Numbers should not raise an error when evaluated with float(). However, your code does not have to handle floats in mantissa-exponent notation such as 123.45e-6 . Operators The single-character binary operators should be implemented: +, -, *, /, and = . The last one is the assignment operator: its left operand (the lvalue) is a variable name, its right operand (the rvalue) is a valid expression, and its value is the value of the right operand. Parentheses Parentheses () may be used to override the rules of operator precedence. Whitespace Operators and operands may be adjacent in the infix expression, or may be separated by one or more whitespace characters, which are blanks ' ' and tabs \t . Behavior The calculator should perform a read-evaluate-print loop (REPL), until end-of-file is reached on the input: get an infix expression from the input convert the expression into an internal form: a postfix expression evaluate the expression print the result Symbol Table Some expressions, like 1 + 2 * 3.14 , do not change the state of the calculator. But others, like a = 1 + 2 * 3.14 have a side effect: a variable a is created or modified. To implement this functionality, your calculator will need a symbol table, which is a dict() that maps strings (variable names) to floats (the variable’s value). This symbol table should be passed into the code that evaluates an expression. Code to be implemented Implement your calculator in a module called calculator.py . Your module MUST implement the following functions (our testing code will call these functions): tokenize(line, specials, whitespace) : This function takes a string, and returns a list of the tokens in the string. line : an ordinary string (could be an infix or postfix expression) whitespace : a string, containing characters to be treated as whitespace. Typically whitespace == " \t" specials : a string, containing characters to be treated as single-character tokens. Typically specials == "+-*/()" Example: tokens = tokenize("1 +( total* 3/ 4.56)", "=+-*/()", " \t") print (tokens) should output ["1", "+", "(", "total", "*", "3", "/", "4.56", ")"] to_postfix(infix_expression) : This function takes a string, and returns a list. The input is an infix expression, and the output is the equivalent postfix expression. The postfix expression is a list of tokens. Example: postfix = to_postfix("1 +( total* 3/ 4.56)") print (postfix) should output [1, 'total', 3, '*', 4.56, '/', '+'] eval_postfix(postfix_expression) : This function takes a list of tokens, and returns a float. The input is a postfix expression, and the output is its value. This function may change the state of the symbol table, which is passed in. Example: value = eval_postfix([1, 2, 3, 4, '/', '*', '+'], symbols) print (value) should output 2.5 . Turning in your work When you are done, go to mycourses.unh.edu, and find CS417, and the assignment. Click the “Submit” button and upload calculator.py. CS417 Programming Assignment 8 Frequently-asked Questions Q: How do I convert an infix expression to postfix? A: Here is the pseudocode: make an empty stack, which holds operators make an empty postfix expression to begin with for each token in the infix expression, if token == '(', push it else if token is an operand, append to postfix expression else if token == ')', while stack is not empty and its top isn't '(', pop from S, append to postfix expression pop the ')' else (it's an operator), while stack is not empty and the precedence of its top is higher or equal to token's precedence, pop from S, append to postfix expression push token when done, stack may hold some pending operators. if so, pop them, and append to postfix expression Q: How do I evaluate a postfix expression? A: Here is the pseudocode: make an empty stack for each token in postfix expression, if token is an operand, push token else (it's an operator) pop right operand pop left operand apply operator push result Upon completion, the expression’s value will be at the top of the stack. Q: If I have a token, how do I know it is an operator, a number, or a variable name? A: This problem is part of a current lab, but here is the gist: (this is not python, it’s pseudocode) if token is one of "+-*/=", it's an operator else, try: x = float(token) it's a number, because no exception was raised except ValueError: if token obeys the rules for python variable names, it's a variable else, the expression has an error, and can't be evaluated Q: How are variables different from numbers? A: You actually know this ☺, but it’s worth spelling out. Variables are treated differently, depending on context. If a variable is the right operand, you should get its value from the symbol table. If a variable is the left operand of "+-*/", you should also get its value from the symbol table. If a variable is the left operand of "=", you should set a value in the symbol table. All of this must be handled in your evaluate_postfix function. Q: What is the precedence of each operator? A: Again, you know this, but there are some subtleties: * / : high precedence + - : medium precedence = ( ) : low precedence Parentheses should have low precedence, because of this code in the second question above: while stack is not empty and the precedence of its top is higher than token's precedence, pop from S, append to postfix expression Suppose you are converting this expression, and you are currently at the '-' token: 1 / (2 + 3 - 4) ^ At this point, the stack would have / ( + . The top of the stack is + . If ( had high precedence, then the while loop will pop the +, then the (, then the /. You would, at that point, have this partially-completed postfix expression: 1 2 3 + ( / which is obviously wrong, because postfix expressions have no parentheses. The solution is to give parentheses low precedence, so the while loop will exit as soon as it finds the ( on the top of the stack. Q: How do I implement the "=" operator? I know that the +, -, *, / operators produce a value. Does = produce a value too? A: Absolutely YES. Here is why: Suppose you have this infix expression: a = b = 20 The expression b = 20 should have the value 20. Thus, the above expression would change the value of b, and proceed to evaluate a = 20. As a result, both a and b get the value 20. To make this happen, in evaluate_postfix, you should push a value on the stack, when you process a = operator. That value is simply the value of the right operand. Q: The "=" operator is still giving me problems. Why does a = b = 10 give an error? A: The problem is that = is right-associative. In other words, a = b = 10 is equivalent to a = (b = 10) Which, in postfix, is: a b 10 = = In other words, b = 10 is evaluated first. Unfortunately, our infix-to-postfix conversion assumes that all operators are left-associative. For example, we expect that a - b + c should be interpreted as (a - b) + c Which, in postfix, is a b - c + In other words, a - b is evaluated first. Notice how the parentheses group differently in this case. The problem, ultimately, lies in this while loop: while stack is not empty and the precedence of its top is higher or equal to token's precedence, pop from S, append to postfix expression If you have several equal-precedence operators, they will be popped in left-to-right order. But if there is an = operator on the stack, and you get another = operator, you should not pop from the operator stack. So, the test in the while loop should be changed. You need to figure that one out. ...
Student has agreed that all tutoring, explanations, and answers provided by the tutor will be used to help in the learning process and in accordance with Studypool's honor code & terms of service.

This question has not been answered.

Create a free account to get help with this and any other question!

Brown University





1271 Tutors

California Institute of Technology




2131 Tutors

Carnegie Mellon University




982 Tutors

Columbia University





1256 Tutors

Dartmouth University





2113 Tutors

Emory University





2279 Tutors

Harvard University





599 Tutors

Massachusetts Institute of Technology



2319 Tutors

New York University





1645 Tutors

Notre Dam University





1911 Tutors

Oklahoma University





2122 Tutors

Pennsylvania State University





932 Tutors

Princeton University





1211 Tutors

Stanford University





983 Tutors

University of California





1282 Tutors

Oxford University





123 Tutors

Yale University





2325 Tutors