0

This code given is a part of my program. Here I want to reduce the 3 functions to just 1 as they are exactly similar except 1 line. I read about passing function(let this function be Bar) and its arguments as arguments in another function(let this function be called Foo ).

But in this scenario, I can't change the function Foo. Here my Foo function is .clicked.connect() and addXMin is my function Bar. I want to pass Bar and its argument num into Foo, where I can't change whats going on in Foo. Is there a way I can reduce the 3 functions into 1 and pass 15, 10 and 5 as arguments to that single function?

self.add15m.clicked.connect(self.add15Min)
self.add10m.clicked.connect(self.add10Min)
self.add5m.clicked.connect(self.add5Min)

def add15Min(self):
    global mins, secs, time
    time = self.lineEdit.text()
    mins = int((time.split(':'))[0])
    mins+=15         #The only different line
    secs = int((time.split(':'))[1])
    time = str(mins).zfill(2) + ":" + str(secs).zfill(2)
    self.lineEdit.setText(time)

def add10Min(self):
    global mins, secs, time
    time = self.lineEdit.text()
    mins = int((time.split(':'))[0])
    mins+=10         #The only different line
    secs = int((time.split(':'))[1])
    time = str(mins).zfill(2) + ":" + str(secs).zfill(2)
    self.lineEdit.setText(time)

def add5Min(self):
    global mins, secs, time
    time = self.lineEdit.text()
    mins = int((time.split(':'))[0])
    secs = int((time.split(':'))[1])
    mins+=5         #The only different line
    time = str(mins).zfill(2) + ":" + str(secs).zfill(2)
    self.lineEdit.setText(time)
subtleseeker
  • 4,415
  • 5
  • 29
  • 41

2 Answers2

1

if connect accepts single argument, you can use an anonymous function (lambda in python) like this:

self.add5m.clicked.connect(lambda: self.addMin(5))

def addMin(self, minutes):
    time = self.lineEdit.text()
    mins = int((time.split(':'))[0])
    secs = int((time.split(':'))[1])
    mins += minutes
    time = str(mins).zfill(2) + ":" + str(secs).zfill(2)
    self.lineEdit.setText(time)
Aprillion
  • 21,510
  • 5
  • 55
  • 89
1

You can create a general function and then use functools.partial to bind variables to parameters:

def addMin(self, mins_to_add):
    global mins, secs, time
    time = self.lineEdit.text()
    mins = int((time.split(':'))[0])
    secs = int((time.split(':'))[1])
    mins+=5         #The only different line
    time = str(mins).zfill(2) + ":" + str(secs).zfill(2)
    self.lineEdit.setText(time)

add5Min, add10Min, add15Min = [functools.partial(self.addMin, x) for x in range(5, 20, 5)]

or connect directly:

self.add15m.clicked.connect(partial(self.addMin, 5))
Netwave
  • 40,134
  • 6
  • 50
  • 93