【问题标题】:Python creating a calculatorPython 创建一个计算器
【发布时间】:2012-10-18 10:41:00
【问题描述】:

我对 python 还很陌生。

我被要求只使用字符串命令、int/string/float 之间的转换等(如果需要)创建一个计算器,并且需要使用函数。也可以使用 while 和 for 循环。

程序需要采用 x/y 或 x/y/z 形式的输入,其中 x y z 是任何正数或负数。其中“/”也可以用加法和减法代替。并且操作数和运算符之间可以存在任意数量的空格。这是我到目前为止的想法。

我会对 +、-、/ 和 * 有一个唯一的定义。我会为用户输入的内容创建一个函数。我会使用“.lstrip”和“.rstrip”来去除空格。

现在我遇到的问题是创建输入函数。我对功能很陌生,这基本上就是我所拥有的。我知道这没什么好用的,但我真的很纠结如何正确输入函数。

def multiplication(x,a,y,b,z):
    if (a== "*"):
        return x*y
    if (b== "*"):
        return y*z

def division(x,a,y,b,z):
    if (a== "/"):
        return x/y
    if (b== "/"):
        return y/z

def addition(x,a,y,b,z):
    if (a== "+"):
        return x+y
    if (b== "+"):
        return y+z

def subtraction(x,a,y,b,z):
    if (a== "-"):
        return x-y
    if (b== "-"):
        return y-z

def (x,y,z):
    x=0
    y=0
    z=0

    zxc=int(input()):# this is where I get stuck and I don't know how to implement x,y,z into the input.

感谢所有帮助。如果您不确定您提供的代码是否过于密集,无法满足我的需求,请在为我浪费您的时间之前询问,制作我可能无法使用的代码。我保证尽快回复。

基本上,我正在尝试找到一种方法来拆分输入的字符串,然后用它开始计算。

【问题讨论】:

标签: python input calculator


【解决方案1】:

我可以替代您的代码。用户可以输入如下内容:8*6/4-3+3,这仍然有效。如果输入字母 (d, a, s),它也不会崩溃。非常紧凑。

代码(Python v3.3.0):

valid_chars = "0123456789-+/* \n";
while True:
    x = "x="
    y = input(" >> ")
    x += y
    if False in [c in valid_chars for c in y]:
        print("WARNING: Invalid Equation");
        continue;
    if(y == "end"):
        break
    exec(x)
    print(x)

【讨论】:

    【解决方案2】:

    由于这看起来像家庭作业,我怀疑允许 OP 使用典型的方法来解决问题。我认为这是一个输入验证和字符串操作的练习;其次是程序流程和理解函数返回值。

    你需要在这里做两件事:

    1. 找出对您的程序有效的输入。
    2. 不断提示用户,直到他或她输入对您的程序有效的输入。

    对于#1,我们知道有效的输入是数字(正整数或负整数),并且它们必须是表达式的形式。所以这意味着,输入的最小长度将是三个(两个数字和一个数学符号)并且输入中的字符(字符串)是无效的。

    这是我们获取用户输入的基本循环:

    expression = raw_input('Please enter the expression: ')
    expression_result = check_input(expression)
    
    while not expression_result:
        print 'You did not enter a valid expression'
        expression = raw_input('Please enter the expression: ')
        expression_result = check_input(expression)
    

    check_input 方法将根据我们的规则验证用户输入的内容是否准确:

    def check_input(input_string):
    
        # Check the basics
        if len(input_string) < 3:
            return False
    
        # Check if we are getting passed correct characters
        for character in input_string:
            if character not in '1234567890' or character not in '/*+-':
                return False
    
        # Things like /23 are not valid
        if input_string[0] in '/*+':
            return False
    
        return input_string
    

    获得正确的输入后,下一步是将输入拆分为您需要提供给数学函数的各个部分。我会把这部分留给你。


    假设你有正确的字符串(也就是说,它是你程序的有效输入),你现在需要将它分成两部分。

    1. 运算符(数学符号)
    2. 操作数(数学符号周围的数字)

    所以我们知道我们有一组有限的运算符+,-,/,*,所以一个想法是使用字符串的split() 方法。这很好用:

    >>> s = '4+5'
    >>> s.split('+')
    ['4', '5']
    

    您可以尝试使用所有运算符拆分字符串,然后检查结果。请注意,用不存在的字符拆分字符串不会引发任何错误,但您只会将字符串返回:

    >>> s = '4+5'
    >>> s.split('/')
    ['4+5']
    

    所以一种方法是 - 在运算符上拆分字符串,如果结果列表的长度 > 2,则您知道结果列表的第一个成员是运算符的左侧,而列表的第二个成员是右手边的任何东西。

    这适用于正数,但是对于负数:

    >>> s = '-4+3'
    >>> s.split('-')
    ['', '4+3']
    

    好消息是我们不是第一个遇到这个问题的人。还有另一种计算方程的方法,称为Polish notation(也称为前缀表示法)。这是来自维基百科页面的算法:

    Scan the given prefix expression from right to left
    for each symbol
     {
      if operand then
        push onto stack
      if operator then
       {
        operand1=pop stack
        operand2=pop stack
        compute operand1 operator operand2
        push result onto stack
       }
     }
    return top of stack as result
    

    要获得波兰风味的正常表达式(称为中缀),请使用 shunting yard algorithm,这是我最喜欢的计算机科学中基于训练的算法。

    使用调车码将表达式转换为波兰表示法,然后使用伪代码求解方程。您可以将列表用作“堆栈”。

    请记住,您的所有输入都是字符串,因此请确保在进行实际数学运算时将它们转换为整数。

    【讨论】:

    • 你说这是作业是完全正确的。我遇到的问题实际上是拆分输入。我试过 string.partition 和 string.strip 和 string.split 都无济于事。你能不能帮帮我。想法是实现输入函数,以便实现上述拆分字符串的想法,但事实证明这对我来说非常困难。
    【解决方案3】:

    这是使用正则表达式的可能解决方案大纲。错误检查留作练习。如果这不是家庭作业,并且您希望看到充实的解决方案,view it here

    import re
    
    # input is a list of tokens (token is a number or operator)
    tokens = raw_input()
    
    # remove whitespace
    tokens = re.sub('\s+', '', tokens)
    
    # split by addition/subtraction operators
    tokens = re.split('(-|\+)', tokens)
    
    # takes in a string of numbers, *s, and /s. returns the result
    def solve_term(tokens):
        tokens = re.split('(/|\*)', tokens)
        ret = float(tokens[0])
        for op, num in <FILL THIS IN>:
            # <apply the operation 'op' to the number 'num'>
        return ret
    
    # initialize final result to the first term's value
    result = solve_term(tokens[0])
    
    # calculate the final result by adding/subtracting terms
    for op, num in <FILL THIS IN>:
        result +=  solve_term(num) * (1 if op == '+' else -1)
    
    print result
    

    【讨论】:

      【解决方案4】:

      如果你只是制作一个玩具计算器,eval() 接受局部和全局变量,所以你可以使用这样的东西:

      def calculate(x=0, y=0, z=0):
          expression = raw_input('Enter an expression: ')
      
          return eval(expression, None, locals())
      

      这是一个示例控制台会话:

      >>> calculate()
      Enter an expression: x + 5 - y
      5
      

      请注意,eval() 不安全。如果你想让事情变得严肃,你将不得不解析表达式。

      此外,由于您的表达式很简单,您可以在evaling 之前使用正则表达式来验证输入:

      def validate(expression):
          operator = r'\s*[+\-/*]\s*'
      
          return bool(re.match(r'^\s*(?:x{o}y|x{o}y{o}z)$'.format(o=operator), expression))
      

      【讨论】:

      • 对于玩具计算器,您可以通过在将输入传递给 eval 之前验证输入来增加乐趣。这样您就可以在不处理所有数学运算的情况下获得输入验证。
      • @Cam:你会如何验证它?
      • 正则表达式,或者(如果不允许 OP 使用正则表达式)检查所有输入字符以查看它们是数学运算还是数字
      • 如果我可以使用 eval 我就不会在这里了......不幸的是我不能。
      • @Cam:除了真正的基本表达之外,这对其他任何事情都不太适用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-26
      相关资源
      最近更新 更多