neonet
neonet

Reputation: 5

how to simplify boolean logic in if else statement?

I have 4 variables, some of them will be True and False, and for each combinations, i will have to call one or few functions. i am currently using a if else statement for each case and i would like to know if there is a nicer way to get the same result with a dictionary or something else.

Thank you

here is my code :

    if (self.cpe_ip and self.cpe_passwd) and self.phone and self.pppoe:
        print "launch ISP portal, modem and radius"
        if self.isp() == "east":
            self.launchbell()
        else:
            self.launchtelus()
        print 'check modem...'
        self.modemstatus()
        radius = sgp_radius.Radius(self.pppoe)
        print 'check radius logs...'
        self.data = radius.sgp()

        self.radius_save()

        #exit(0)
    elif (self.cpe_ip and self.cpe_passwd) and not self.phone and not self.pppoe:
        print "launch modem test only"
        self.modemstatus()


        #exit(0)
    elif not(self.cpe_ip and self.cpe_passwd) and self.phone and not self.pppoe:
        #print "only  Bell portal"
        if self.isp() == "east":
            self.launchbell()
        else:
            self.launchtelus()

    elif (self.cpe_ip and self.cpe_passwd) and not self.phone and self.pppoe:
        #print "launch modem and radius test."
        self.modemstatus()

        radius = sgp_radius.Radius(self.pppoe)
        print 'check radius logs...'
        self.data = radius.sgp()
        self.radius_save()

    elif not(self.cpe_ip and self.cpe_passwd) and not self.phone and self.pppoe:
        #print "only radius tests."
        radius = sgp_radius.Radius(self.pppoe)
        self.data = radius.sgp()

        self.radius_save()

    elif not(self.cpe_ip and self.cpe_passwd) and self.phone and self.pppoe:
        print "bell and radius tests."
        if self.isp() == "east":
            self.launchbell()
        else:
            self.launchtelus()

        radius = sgp_radius.Radius(self.pppoe)
        print 'check radius logs...'
        self.data = radius.sgp()
        self.radius_save()

    elif (self.cpe_ip and self.cpe_passwd) and self.phone and not self.pppoe:
        #print "launch modem and bell tests."
        if self.isp() == "east":
            self.launchbell()
        else:
            self.launchtelus()
        self.modemstatus()

    else:
        #print "test bell only"
        #launchbell(self.phone)
        exit(0)

Upvotes: 0

Views: 959

Answers (2)

GreenAsJade
GreenAsJade

Reputation: 14685

You implied in your question that some sort of lookup table for the logic might be the way to go, and there are many ways you could make something like that.

One way would be, as you say, with a dict, as shown below.

This way results in rather more complex looking code than the nice looking "simplify and factor out duplication" solution for your particular example, but this method extends more easily to the case where you have more different logic for the different cases... I'm not saying it's "better" ... just a different option!

def launch_isp_portal_and_radius():
   print "launch ISP portal, modem and radius"
   # etc

# etc

DecisionTable = {
 # cpe_ip cpe_passwd phone ppoe
   (True,  True,  True,  True ) : launch_isp_portal_and_radius,
   (True,  True,  False, False) : launch_modem_test_only,
   (False, False, True,  False) : only_Bell_portal,
   (False, True,  True,  False) : only_Bell_portal,
   (True,  False, True,  False) : only_Bell_portal,
   (True,  True,  False, True ) : launch_modem_and_radius_test,
   (False, False, False, False) : only_radius_tests,
   (False, True,  False, False) : only_radius_tests,
   (True,  False, False, False) : only_radius_tests,
   (False, False, True,  True ) : bell_and_radius_tests
   (False, True,  True,  True ) : bell_and_radius_tests,
   (True,  False, True,  True ) : bell_and_radius_tests,
   (True,  True,  True,  False) : launch_modem_and_bell_tests
}

action = DecisionTable.get((self.cpe_ip, self.cpe_passwd, self.phone, self.ppoe))

if action:
   action()
else:
   raise StandardError("Whoa, internal logic error!")

(And of course there are other ways to make a decision table - an array is another obvious option. The problem with an array is making the static declaration of it look readable for the logic it represents...)

(Edit: made the dict indexed on tuple, as per jons suggestion)

Upvotes: 2

jonrsharpe
jonrsharpe

Reputation: 121975

One way to simplify it would be to recognise and factor out the duplication:

if self.phone:
    if self.isp() == "east":
        self.launchbell()
    else:
        self.launchtelus()

if self.cpe_ip and self.cpe_passwd:
    print 'check modem...'
    self.modemstatus()

if self.pppoe:
    radius = sgp_radius.Radius(self.pppoe)
    print 'check radius logs...'
    self.data = radius.sgp()
    self.radius_save()

Upvotes: 5

Related Questions