Python Forum
How to pass a method as argument in an another method?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to pass a method as argument in an another method?
#1
Question 
I want to write a python calculator program that has different methods to add, subtract, multiply which takes 2 parameters. I need to have an execute method when passed with 3 parameters, should call respective method and perform the operation. How can I achieve that?

class calc():
    def __init__(self,a,b):
        self.a=a
        self.b=b
        
    def ex(self,fun):
        self.fun=fun
        if fun=="add":
            self.add()
    
    def add(self):
        return self.a+self.b
    def sub(self):
        return self.a-self.b
    def mul(self):
        return self.a*self.b
    def div (self):
        return self.a/self.b
    def execu(
obj1=calc()
obj1.ex("add",1,,2)
Reply
#2
Why do you want to put that logic in your class, instead of having it be outside? You can of course pass functions to other functions, but it doesn't really make sense here.
Reply
#3
The execute method needs to have the 2 number parameters and needs to update the instance attributes.
class Calculator:
    def __init__(self):
        self.number1 = 0
        self.number2 = 0
        self.result = 0
        self.operator = ""

    def execute(self, func, number1, number2):
        self.number1 = number1
        self.number2 = number2
        if func == "add":
            self.add()

    def add(self):
        self.result = self.number1 + self.number2
        self.operator = "+"

    def sub(self):
        self.result = self.number1 - self.number2
        self.operator = "-"

    def mul(self):
        self.result = self.number1 * self.number2
        self.operator = "*"

    def div(self):
        self.result = self.number1 / self.number2
        self.operator = "/"

    def __str__(self):
        return f"Result: {self.number1} {self.operator} {self.number2} = {self.result}"


calculator = Calculator()
calculator.execute("add", 1, 2)
print(calculator)

Rather than having a chain of if statements you can use a dictionary instead
class Calculator:
    def __init__(self):
        self.number1 = 0
        self.number2 = 0
        self.result = 0
        self.operator = ""
        self.commands = {
            "add": self.add,
            "sub": self.sub,
            "mul": self.mul,
            "div": self.div,
        }

    def execute(self, func, number1, number2):
        self.number1 = number1
        self.number2 = number2
        command = self.commands[func]
        command()

    def add(self):
        self.result = self.number1 + self.number2
        self.operator = "+"

    def sub(self):
        self.result = self.number1 - self.number2
        self.operator = "-"

    def mul(self):
        self.result = self.number1 * self.number2
        self.operator = "*"

    def div(self):
        self.result = self.number1 / self.number2
        self.operator = "/"

    def __str__(self):
        return f"Result: {self.number1} {self.operator} {self.number2} = {self.result}"


calculator = Calculator()
calculator.execute("add", 1, 2)
print(calculator)
Reply
#4
Hey thanks for the response. I guess we don't need an init function here. Checkout the trimmed the code.
#calculator class with arithmetic methods

class calc:
 
    def execute(self, func, a, b):
        self.a = a
        self.b = b
        if func == "add":
            self.add()
        elif func == "sub":
            self.sub()
        elif func == "mul":
            self.mul()
        elif func == "div":
            self.div()
 
    def add(self):
        print (self.a,"+",self.b,"=",self.a + self.b)
      
 
    def sub(self):
          print (self.a,"-",self.b,"=",self.a - self.b)
     
 
    def mul(self):
          print (self.a,"*",self.b,"=",self.a* self.b)
        
 
    def div(self):
        print (self.a,"/",self.b,"=",self.a / self.b)
       
 
 
cal = calc()
cal.execute("div", 6, 3)
Reply
#5
You successfully turned the class into what may as well be separate functions.
Reply
#6
It's homework. Don't expect it to make any sense. A real program would not write methods for code already provided in the operator library. A real program would not use strings like 'add' or 'sub' instead of '+' or '-'. A real program would not write a class when a simple function would suffice.

It is a wonder that anyone ever learns what "object oriented" means when you see so few examples where the "object oriented" benefits are demonstrated.
Reply
#7
If you define the math functions you may as well make them generally useful. I would do something like this:
#calculator class with arithmetic methods

class calc():
    def solve(self, equation):
        '''Solve eqation in the form a op b where b is in "+-*/"'''
        a, op, b = equation.split()
        print(equation, '=', self.execute(op, float(a), float(b)))

    def execute(self, op, a, b):
        '''Return result of binary math operation'''
        if op == "+":
            return self.add(a, b)
        if op == "-":
            return self.sub(a, b)
        if op == "*":
            return self.mul(a, b)
        if op == "/":
            return self.div(a, b)
        raise ValueError(f'{op} is not a recognized operator')

    def add(self, a, b):
        '''Return a + b'''
        return a + b

    def sub(self, a, b):
        '''Return a - b'''
        return a - b

    def mul(self, a, b):
        '''Return a * b'''
        return a * b

    def div(self, a, b):
        '''Return a / b'''
        return a / b

cal = calc()
cal.solve('6 / 3')
print(cal.execute('*', 2, 3))
If we pretend that the calculator has support for more interesting operations, making those operations visible outside the calculator changes it from an application to a library. Your code exposed the operations, but not in a generically useful way. If I am using your library I probably want the div function to return the quotient instead of None.

Though this is a silly program it aspires to do "good design" things like separating the implementation from the interface. add(a, b) knows how to compute a + b. It should not have to know about how results are displayed (there should not be a print). execute(op, a, b) does not know how to do any operations, but it knows how to find the right function for the operator. solve(equation) does not know anything about math, but it knows how to parse an equation and display the results. When you design code you should look for this kind of division of labor. Every function should do one thing that is easily described with a sentence or two. If you cannot describe what a function does you need to "refactor" your code to have functions that are well defined.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Question about List.reverse() method tomliuwhite 1 260 Dec-07-2021, 08:20 AM
Last Post: ndc85430
  Class Method to Calculate Age Doesn't Work gdbengo 1 300 Oct-30-2021, 11:20 PM
Last Post: Yoriz
  Regex - Pass Flags as a function argument? muzikman 6 893 Sep-06-2021, 03:43 PM
Last Post: muzikman
  Which method for arrays is faster ? thunderspeed 2 542 Aug-31-2021, 10:58 AM
Last Post: DeaD_EyE
  Carlssons method for log Gusbagro 2 758 Jul-04-2021, 02:17 AM
Last Post: Larz60+
  anonymous method in a class Skaperen 8 1,557 May-23-2021, 11:17 PM
Last Post: Skaperen
  Unable to use random.choice(list) in async method spacedog 4 1,242 Apr-29-2021, 04:08 PM
Last Post: spacedog
Question Google Foobar- Code works in my IDE but not in foobar. Static method? pr3ttykitty 4 1,667 Feb-24-2021, 05:03 PM
Last Post: nilamo
  Magic Method Arithmetic Operators ClownPrinceOfCrime 3 987 Jan-10-2021, 03:24 PM
Last Post: ndc85430
  How to apply a class method to an entire dataframe column tirtha9 1 1,472 Jan-03-2021, 04:44 AM
Last Post: klllmmm

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020