2015-09-12 42 views
0

我正尝试在Python中建立一个反转波兰语计算器,而且就我而言。它似乎工作,直到我尝试运行PRT,此时我从文本文件中获取最后一个数字,而不是从先前计算中附加到堆栈的结果。 Python不是我的正常语言,所以我对你即将看到的内容表示歉意。在Python中反转波兰语计算器

def is_number(ln): 
     try: 
      int(ln) 
      return True 
     except ValueError: 
      return False 

    def main(): 
     stack = [] 
     # Open file 
     infile = open('math.txt', 'r') 

     line = infile.readline() 

     while line != '': 
      if is_number(line): 
       line = int(line) 
       stack.append(line) 
      if line in ['ADD', 'SUB', 'MUL', 'DIV']: 
       if line=='ADD': result = stack.pop() + stack.pop() 
       if line=='SUB': result = stack.pop() - stack.pop() 
       if line=='MUL': result = stack.pop() * stack.pop() 
       if line=='DIV': result = stack.pop()/stack.pop() 
       print(result) 
       stack.append(result) 
      if line=='PRT': print(stack.pop()) 
      if line=='STOP': exit() 
      line = infile.readline() 

     # Close file 
     infile.close() 

    # Call main function 

    main() 

math.txt:

1 
    2 
    3 
    4 
    5 
    6 
    ADD 
    PRT 

我猜也许问题是与换行符或readline的做,但我就是不使用Python写正常,所以我我不确定。

+1

你可以发布你的math.txt。 –

+0

一旦你修复了你的代码,我就让你[这个要点](https://gist.github.com/spectras/dabae78e0e94a58793b8)带有更多pythonic版本的你做的,所以你可以比较。可能不完美,但利用python的强大代码更清晰。需要python3。 – spectras

+0

@BarunSharma我添加了我的math.txt文件 – skwills

回答

1

readline()返回包含尾部lf或crlf的行,所以我不确定这部分是如何工作的,除非您只是将raw_input更改为文件读取。无论如何,您的程序和工作代码在该数据集之间的最短距离是剥离线。你可以用你当前的数据做一个rstrip,但是我只是去掉双方。修改你的程序是这样的:

 while line != '': 
+  line = line.strip() 
     if is_number(line): 
      line = int(line) 

但这仍然不是很健壮。这是一个修改后的版本,首先处理这些行,然后运行相同的算法。不过,我会鼓励你学习和理解通过spectras在发表了主旨,因为它显示了一个更为有用的Python的成语比这

def is_number(ln): 
    try: 
     int(ln) 
     return True 
    except ValueError: 
     return False 

def main(): 
    with open('math.txt', 'r') as f: 
     lines = (line.strip() for line in f) 
     lines = [line for line in lines if line] 

    stack = [] 
    for line in lines: 
     if is_number(line): 
      stack.append(int(line)) 
     elif line in ['ADD', 'SUB', 'MUL', 'DIV']: 
      if line=='ADD': result = stack.pop() + stack.pop() 
      if line=='SUB': result = stack.pop() - stack.pop() 
      if line=='MUL': result = stack.pop() * stack.pop() 
      if line=='DIV': result = stack.pop()/stack.pop() 
      print(result) 
      stack.append(result) 
     elif line=='PRT': 
      print(stack.pop()) 
     elif line=='STOP': 
      exit() 
     else: 
      raise ValueError("Unknown line: %s" % line) 

# Call main function 

main() 
+0

谢谢!我与gist提供的解决方案的斗争是将其转换为Python 2.我只是没有花足够的时间来使用该语言。 – skwills

0

Here是我实现一个后缀表达式求值。

此代码需要以空格分隔的字符串形式表达。你可以做到这一点;

with open('math.txt') as f: 
    expr = f.read() 

此代码中最有用的技巧是使用字典将操作员名称映射到函数。例如有两个参数的操作符;

from operator import add, sub, mul, truediv, pow 

_binops = {'+': add, '-': sub, '*': mul, '/': truediv, '**': pow} 

这将替换所有if语句;

b, a = stk.pop(), stk.pop() 
stk.append(_binops[i](a, b)) 

使用_binops[i]从字典中选择函数对象。 使用从堆栈弹出的值调用此函数对象。

IPython中的交互式示例;

In [1]: %cpaste 
Pasting code; enter '--' alone on the line to stop or use Ctrl-D. 
:from operator import add, sub, mul, truediv, pow 
:_binops = {'+': add, '-': sub, '*': mul, '/': truediv, '**': pow} 
:-- 

In [2]: _binops['+'] 
Out[2]: <function _operator.add> 

In [3]: _binops['+'](1, 2) 
Out[3]: 3 

如图在github的完整代码也实现了一些运算符采取只有一个参数等三角函数,并提供了一些常数。

它可以很容易地修改为接受ADD而不是+,只需更改_binops字典;

_binops = {'+': add, 'add': add, '-': sub, 'sub': sub, 
      '*': mul, 'mul': mul, '/': truediv, 'div': truediv, 
      '**': pow, 'pow': pow}