Data update
This commit is contained in:
parent
5150844a7d
commit
4bb20c9b71
7735 changed files with 38060 additions and 199180 deletions
|
|
@ -1,117 +1,92 @@
|
|||
"""
|
||||
>>> # EXAMPLE USAGE
|
||||
>>> result = rpn_to_infix('3 4 2 * 1 5 - 2 3 ^ ^ / +', VERBOSE=True)
|
||||
TOKEN STACK
|
||||
3 ['3']
|
||||
4 ['3', '4']
|
||||
2 ['3', '4', '2']
|
||||
* ['3', Node('2','*','4')]
|
||||
1 ['3', Node('2','*','4'), '1']
|
||||
5 ['3', Node('2','*','4'), '1', '5']
|
||||
- ['3', Node('2','*','4'), Node('5','-','1')]
|
||||
2 ['3', Node('2','*','4'), Node('5','-','1'), '2']
|
||||
3 ['3', Node('2','*','4'), Node('5','-','1'), '2', '3']
|
||||
^ ['3', Node('2','*','4'), Node('5','-','1'), Node('3','^','2')]
|
||||
^ ['3', Node('2','*','4'), Node(Node('3','^','2'),'^',Node('5','-','1'))]
|
||||
/ ['3', Node(Node(Node('3','^','2'),'^',Node('5','-','1')),'/',Node('2','*','4'))]
|
||||
+ [Node(Node(Node(Node('3','^','2'),'^',Node('5','-','1')),'/',Node('2','*','4')),'+','3')]
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
PRECEDENCE = {"^": 4, "*": 3, "/": 3, "+": 2, "-": 2}
|
||||
ASSOCIATIVITY = {"^": 1, "*": 0, "/": 0, "+": 0, "-": 0}
|
||||
|
||||
prec_dict = {'^':4, '*':3, '/':3, '+':2, '-':2}
|
||||
assoc_dict = {'^':1, '*':0, '/':0, '+':0, '-':0}
|
||||
|
||||
class Node:
|
||||
def __init__(self,x,op,y=None):
|
||||
self.precedence = prec_dict[op]
|
||||
self.assocright = assoc_dict[op]
|
||||
def __init__(self, x: Node | str, op: str, y: Node | str | None = None):
|
||||
self.precedence = PRECEDENCE[op]
|
||||
self.right_associative = ASSOCIATIVITY[op]
|
||||
self.op = op
|
||||
self.x,self.y = x,y
|
||||
self.x, self.y = x, y
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
Building an infix string that evaluates correctly is easy.
|
||||
Building an infix string that looks pretty and evaluates
|
||||
correctly requires more effort.
|
||||
"""
|
||||
# easy case, Node is unary
|
||||
if self.y == None:
|
||||
return '%s(%s)'%(self.op,str(self.x))
|
||||
if self.y is None:
|
||||
return "%s(%s)" % (self.op, str(self.x))
|
||||
|
||||
# determine left side string
|
||||
str_y = str(self.y)
|
||||
if self.y < self or \
|
||||
(self.y == self and self.assocright) or \
|
||||
(str_y[0] is '-' and self.assocright):
|
||||
if (
|
||||
self.y < self
|
||||
or (self.y == self and self.right_associative)
|
||||
or (str_y[0] == "-" and self.right_associative)
|
||||
):
|
||||
str_y = "(%s)" % str_y
|
||||
|
||||
str_y = '(%s)'%str_y
|
||||
# determine right side string and operator
|
||||
str_x = str(self.x)
|
||||
str_op = self.op
|
||||
if self.op is '+' and not isinstance(self.x, Node) and str_x[0] is '-':
|
||||
if self.op == "+" and not isinstance(self.x, Node) and str_x[0] == "-":
|
||||
str_x = str_x[1:]
|
||||
str_op = '-'
|
||||
elif self.op is '-' and not isinstance(self.x, Node) and str_x[0] is '-':
|
||||
str_op = "-"
|
||||
elif self.op == "-" and not isinstance(self.x, Node) and str_x[0] == "-":
|
||||
str_x = str_x[1:]
|
||||
str_op = '+'
|
||||
elif self.x < self or \
|
||||
(self.x == self and not self.assocright and \
|
||||
getattr(self.x, 'op', 1) != getattr(self, 'op', 2)):
|
||||
str_op = "+"
|
||||
elif self.x < self or (
|
||||
self.x == self
|
||||
and not self.right_associative
|
||||
and getattr(self.x, "op", 1) != getattr(self, "op", 2)
|
||||
):
|
||||
str_x = "(%s)" % str_x
|
||||
|
||||
str_x = '(%s)'%str_x
|
||||
return ' '.join([str_y, str_op, str_x])
|
||||
return " ".join([str_y, str_op, str_x])
|
||||
|
||||
def __repr__(self):
|
||||
"""
|
||||
>>> repr(Node('3','+','4')) == repr(eval(repr(Node('3','+','4'))))
|
||||
True
|
||||
"""
|
||||
return 'Node(%s,%s,%s)'%(repr(self.x), repr(self.op), repr(self.y))
|
||||
return "Node(%s,%s,%s)" % (repr(self.x), repr(self.op), repr(self.y))
|
||||
|
||||
def __lt__(self, other):
|
||||
def __lt__(self, other: object) -> bool:
|
||||
if isinstance(other, Node):
|
||||
return self.precedence < other.precedence
|
||||
return self.precedence < prec_dict.get(other,9)
|
||||
return self.precedence < PRECEDENCE.get(str(other), 9)
|
||||
|
||||
def __gt__(self, other):
|
||||
def __gt__(self, other: object) -> bool:
|
||||
if isinstance(other, Node):
|
||||
return self.precedence > other.precedence
|
||||
return self.precedence > prec_dict.get(other,9)
|
||||
return self.precedence > PRECEDENCE.get(str(other), 9)
|
||||
|
||||
def __eq__(self, other):
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if isinstance(other, Node):
|
||||
return self.precedence == other.precedence
|
||||
return self.precedence > prec_dict.get(other,9)
|
||||
return self.precedence > PRECEDENCE.get(str(other), 9)
|
||||
|
||||
|
||||
def rpn_to_infix(input: str, *, VERBOSE: bool = False):
|
||||
"""Convert `input` in rpn notation to infix notation."""
|
||||
if VERBOSE:
|
||||
print("TOKEN STACK")
|
||||
|
||||
def rpn_to_infix(s, VERBOSE=False):
|
||||
"""
|
||||
|
||||
converts rpn notation to infix notation for string s
|
||||
|
||||
"""
|
||||
if VERBOSE : print('TOKEN STACK')
|
||||
|
||||
stack=[]
|
||||
for token in s.replace('^','^').split():
|
||||
if token in prec_dict:
|
||||
stack.append(Node(stack.pop(),token,stack.pop()))
|
||||
stack: list[Node | str] = []
|
||||
for token in input.replace("^", "^").split():
|
||||
if token in PRECEDENCE:
|
||||
stack.append(Node(stack.pop(), token, stack.pop()))
|
||||
else:
|
||||
stack.append(token)
|
||||
|
||||
# can't use \t in order to make global docstring pass doctest
|
||||
if VERBOSE : print(token+' '*(7-len(token))+repr(stack))
|
||||
if VERBOSE:
|
||||
print(token + " " * (7 - len(token)) + repr(stack))
|
||||
|
||||
return str(stack[0])
|
||||
|
||||
strTest = "3 4 2 * 1 5 - 2 3 ^ ^ / +"
|
||||
strResult = rpn_to_infix(strTest, VERBOSE=False)
|
||||
print ("Input: ",strTest)
|
||||
print ("Output:",strResult)
|
||||
|
||||
print()
|
||||
if __name__ == "__main__":
|
||||
EXAMPLES = [
|
||||
"3 4 2 * 1 5 - 2 3 ^ ^ / +",
|
||||
"1 2 + 3 4 + ^ 5 6 + ^",
|
||||
]
|
||||
|
||||
strTest = "1 2 + 3 4 + ^ 5 6 + ^"
|
||||
strResult = rpn_to_infix(strTest, VERBOSE=False)
|
||||
print ("Input: ",strTest)
|
||||
print ("Output:",strResult)
|
||||
for example in EXAMPLES:
|
||||
print(f"Input: {example}")
|
||||
print(f"Result: {rpn_to_infix(example, VERBOSE=True)}")
|
||||
print()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue