0

I'm a python beginner and I'm practicing a simple calculation class.

This piece of code is supposed that when user input 2 numbers and 1 operator in the command line, it will show you the answer. I just wonder why it prints 4 lines in function add(), subtract(), multiply() and divide(). I just put them in a dictionary, not call all of them. Could anybody explain that for me please? It would be great to show me the solution as well. Thanks in advance!

Here is the output from windows power shell:

PS D:\misc\Code\python\mystuff> python .\CalculationTest.py
Please input a number:
>1
Please input a operator(i.e. + - * /):
>+
Please input another number:
>2
Adding 1 + 2         #why it shows these 4 lines?
Subtracting 1 - 2
Multiplying 1 * 2
Dividing 1 / 2
3

and here is my code:

class Calculation(object):
def add(self, a, b):
    print "Adding %d + %d" % (a, b)
    return a + b

def subtract(self, a, b):
    print "Subtracting %d - %d" % (a, b)
    return a - b

def multiply(self, a, b):
    print "Multiplying %d * %d" % (a, b)
    return a * b

def divide(self, a, b):
    if b == 0:
        print "Error"
        exit(1)
    else:
        print "Dividing %d / %d" % (a, b)
        return a / b

def get_result(self, a, b, operator):
    operation = {
        "+" : self.add(a, b),        # I didn't mean to call these methods,
        "-" : self.subtract(a, b),   # but it seems that they ran.
        "*" : self.multiply(a, b),
        "/" : self.divide(a, b),
    }
    print operation[operator]

if __name__ == "__main__":
    print "Please input a number:"
    numA = int(raw_input(">"))

    print "Please input a operator(i.e. + - * /):"
    operator = raw_input(">")

    print "Please input another number:"
    numB = int(raw_input(">"))

    calc = Calculation()
    #print calc.add(numA, numB)
    calc.get_result(numA, numB, operator)

3 Answers3

2

You say that you did not mean to call the methods. But you did. You write

self.add(a, b)

and that calls add since it uses the call operator (). You are calling each one of your arithmetic operator methods as you populate your dictionary.

If you want to capture the method instead of calling it you need to put self.add into the dict.

Then when you do want to call the method you do it like this:

print operation[operator](a, b)

At this point we are using the call operator () and supplying the parameters.

Putting it all together, your function looks like this:

def get_result(self, a, b, operator):
    operation = {
        "+" : self.add,      
        "-" : self.subtract, 
        "*" : self.multiply,
        "/" : self.divide,
    }
    print operation[operator](a, b)

Since the dict never varies, it may be more sensible to make it be a class attribute and initialise it once only.

It doesn't look to me as though your instance is doing very much useful here. You are not referring to self anywhere. Which suggests that these methods may be better as static methods.

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
2

Do this instead:

def get_result(self, a, b, operator):
    operation = {
        "+" : self.add,
        "-" : self.subtract,
        "*" : self.multiply,
        "/" : self.divide,
    }
    print operation[operator](a, b)

Notice how the actual method call (with (a, b)) has been moved to after you create the dictionary. The way you had it, you were calling each of the methods and storing the results in the dictionary, rather than storing the methods and then only calling the one you wanted.

Amber
  • 507,862
  • 82
  • 626
  • 550
0

The following code:

operation = {
    "+" : self.add(a, b),        # I didn't mean to call these methods,
    "-" : self.subtract(a, b),   # but it seems that they ran.
    "*" : self.multiply(a, b),
    "/" : self.divide(a, b),
}

will eagerly evaluate all the values because that is the way python works. You want to do:

operation = {
    "+" : self.add,
    "-" : self.subtract,
    "*" : self.multiply,
    "/" : self.divide,
}

and then adapt the rest of your code to call only the appropriate method.

If you want to code in your original style, you need a language with lazy evaluation semantics such as haskell.

Simon Bergot
  • 10,378
  • 7
  • 39
  • 55