2015-09-12 50 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}