程序不接受参数Python

2024-09-29 23:28:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在创建一个后缀计算器,它接受算术表达式并首先将运算符推送到stacl。你知道吗

./pythonfilename 3 4 1+-用作我的输入。但是,由于没有显示任何输出,我尝试调试我的程序,以了解为什么我的程序不接受我的参数。 不会导致打印任何输出。我按Ctrl+C显示回溯调用,它指出x=sys.stdin.readlines系统标准. 你知道吗

#!/usr/bin/python

import sys
import fileinput

class Stack:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def push(self,item):
        self.items.append(item)

    def pop(self):
        return self.items(pop)

    def peek(self):
        return self.items[len(self.items)-1]

    def size(self):
        return len(self.items)

    def is_number(line):
        try:
            float(line)
        except ValueError:
            return False        

def infixtoPostfix():
    initStack=Stack()
    x = sys.stdin.readlines() #read user input 
    for lines in x:#for lines in fileinput.input():
        for line in lines.strip().split(" "):
            if is_number(line):
                initStack.push(line)
                line = float(line)
            elif line =='+':
                firstNum = initStack.pop()
                secNum = initStack.pop()
                result = firstNum + secNum
                initStack.push(result)
                print initStack.peek()              

            elif line == '-':
                firstNum = initStack.pop()
                secNum = initStack.pop()
                result = firstNum - secNum
                initStack.push(result)
                print initStack.peek()

            elif line == '*':
                firstNum = initStack.pop()
                secNum = initStack.pop()
                result = firstNum * secNum
                initStack.push(result)
                print initStack.peek()
            elif line == "/":
                firstNum = initStack.pop()
                secNum = initStack.pop()
                result = firstNum / secNum
                initStack.push(result)
                print initStack.peek()
            elif line == "%":
                firstNum = initStack.pop()
                secNum = initStack.pop()
                result = firstNum % secNum
                initStack.push(result)
                print initStack.peek()

infixtoPostfix()

Tags: selfreturndefsyslineitemsresultpop
2条回答

读取管道(cat ... | python myprog.py)的标准方法是

import sys

for line in sys.stdin:
    print ">", line

line这里将包括最后的'\n'

如果您想在命令行(python myprog.py 3 4 1 + -)上获取参数,您可以使用sys.argv[1:]sys.argv[0]包含myprog.py)。你知道吗

要获得输入的一致词法,首先需要检查sys.argv,然后拆分sys.stdin

def lex_input():
    "Returns a list of tokens."
    tokens = []
    if len(sys.argv) > 1:
        tokens = sys.argv[1:]
    else:
        for line in sys.stdin:
            tokens += line.split()
    return tokens

然后您只需要更改infixPostfix()函数来使用这个令牌数组(而不是在同一个函数中同时进行解析和求值)。你知道吗

附言:一个更简洁的方式写的个别条款将是:

elif token == '+':
    push(pop() + pop())

但这取决于你想完成什么。。你知道吗

更新:完整解决方案

更新2:带有调试语句以可视化堆栈(为了简洁起见,删除了堆栈类而使用常规列表)

import sys

STACK = []
push = STACK.append
pop = STACK.pop

OPERATIONS = {
    '+': lambda b, a: a + b,
    '-': lambda b, a: a - b,
    '*': lambda b, a: b * a,
    '/': lambda b, a: b / a,
}

def infixtoPostfix(tokens):
    print '%-15s %5s %-15s' % ('STACK before', 'token', 'STACK after')
    print '-'*15, '-'*5, '-'*15

    for token in tokens:
        print '%15s %5r' % (STACK, token),

        if token not in OPERATIONS:
            push(int(token))
        else:
            push(OPERATIONS[token](pop(), pop()))

        print '%15s' % STACK

def lex_input():
    "Returns a list of tokens."
    tokens = []
    if len(sys.argv) > 1:
        tokens = sys.argv[1:]
    else:
        for line in sys.stdin:
            tokens += line.split()
    return tokens

if __name__ == "__main__":
    infixtoPostfix(lex_input())
    # well formed programs should leave a single value on the STACK
    print "\nResult is:", STACK[0]

测试:

(dev) go|c:\srv> python rpn.py 3 4 1 + -
STACK before    token STACK after
       -   -        -
             []   '3'             [3]
            [3]   '4'          [3, 4]
         [3, 4]   '1'       [3, 4, 1]
      [3, 4, 1]   '+'          [3, 5]
         [3, 5]   '-'            [-2]

Result is: -2

cat rpn.txt | python rpn.py将输出相同的东西,如果rpn.txt包含3 4 1 + -)。你知道吗

如果您尝试带有语法错误的rpn程序,则该程序将引发异常,例如:

(dev) go|c:\srv> python rpn.py 3 4 + -
STACK before    token STACK after
       -   -        -
             []   '3'             [3]
            [3]   '4'          [3, 4]
         [3, 4]   '+'             [7]
            [7]   '-'
Traceback (most recent call last):
  File "rpn.py", line 60, in <module>
    infixtoPostfix(lex_input())
  File "rpn.py", line 45, in infixtoPostfix
    push(OPERATIONS[token](pop(), pop()))
  File "rpn.py", line 26, in pop
    return STACK.pop()
IndexError: pop from empty list

在一个真正的编译器中,这是不好的,因为你不想让最终用户看到你实现的细节。相反,您应该给他们一个诊断错误消息,以及您的程序找到它的确切位置。你知道吗

在这种情况下,这并不难。我省略了用于打印堆栈的调试语句:

def infixtoPostfix(tokens):
    # make a copy of the input, for use in error handling
    input_tokens = tokens[:]  
    try:
        for i, token in enumerate(tokens):
            if token not in OPERATIONS:
                push(int(token))
            else:
                push(OPERATIONS[token](pop(), pop()))
    except IndexError:
        print 'Detected Syntax Error at token no.:', i + 1  # people count from 1..
        print ' '.join(input_tokens)
        print '%s%s' % ('-' * (1 + len(' '.join(input_tokens[:i]))), '^')
        push('SYNTAX ERROR')  # the top of the stack contains the result of the current operation..

需要对结果打印进行小的更改,打印列表中的最后一个元素(STACK[-1]),它是堆栈的顶部,而不是依赖列表/堆栈的末尾只有一个元素:

if __name__ == "__main__":
    infixtoPostfix(lex_input())
    # well formed programs should leave a single value on the STACK
    print "\nResult is:", STACK[-1]

如果我们给这个版本的程序提供语法错误:

(dev) go|c:\srv> python rpn.py 34 4 + -
Detected Syntax Error at token no.: 4
34 4 + -
   -^

Result is: SYNTAX ERROR

我们得到了一个正确的错误消息,带有一个小的尖尖的“图形”指示错误被检测到的位置。你知道吗

我们可以更进一步,因为我们知道所有的操作都在堆栈上包含两个元素,并给出更详细的错误消息,例如:

Syntax Error at token "-":  Stack underflow
   The "-" operation requires two stack arguments and the stack 
   contained only one:

        Stack      token
                -
        [37]        '-'

我将把它的实现作为一个练习。你知道吗

如您所见,即使在这个简单的示例中,错误处理代码也比求值代码多,这在编写简单的编译器时并不奇怪。你知道吗

./pythonfilename 3 4 1+-

实际上,3 4 1+-是作为参数传递的,而不是作为输入传递的。你知道吗

如果要读取文件,请使用open('filename')

使用./pythonfilename'3 4 1+-'

x=[系统argv[1] ]

代替x=sys.stdin.readlines系统标准()

但是,您的代码只处理单个输入作为参数

相关问题 更多 >

    热门问题