Thhollev
Thhollev

Reputation: 83

Python if-else mess

Is there a cleaner way to create msg? For each event (Ping, Pull request, Issue, Issue comment, Repo, Create, Delete, Pull requset review, Push, Commit comment) is there an if clause that checks the event and creates a message according to it's action.

    data = request.json
    event = request.headers['X-Github-Event']
    msg = ""

    ...

   # Pull request
   elif event == "pull_request":
       if data['action'] == "opened":
           msg = PullRequest(data).opened()
       elif data['action'] == "closed":
           msg = PullRequest(data).closed()
       elif data['action'] == "assigned":
           msg = PullRequest(data).assigned()

   # Issue
   elif event == "issues":
        if data['action'] == "opened":
            msg = Issue(data).opened()
        elif data['action'] == "reopened":
            msg = Issue(data).reopened()
        elif data['action'] == "closed":
            msg = Issue(data).closed()
        elif data['action'] == "labeled":
            msg = Issue(data).labeled()
        elif data['action'] == "assigned":
            msg = Issue(data).assigned()
    ...

Upvotes: 1

Views: 97

Answers (2)

keepAlive
keepAlive

Reputation: 6655

What about doing so dynamically, e.g.

getattr(PullRequest(data), data['action'], lambda:None)()

In summary

elif event == "pull_request":
    getattr(PullRequest(data), data['action'], lambda:None)()
elif event == "issues":
    getattr(Issue(data), data['action'], lambda:None)()

Where the idea behind lambda:None is that it stands for a default callable if data['action'] is actually not a method of PullRequest(data) or Issue(data).


Or if you do not like if-else statements, something like

callables = {
    "pull_request":PullRequest,
    "issues":Issue,
}

getattr(callables[event](data), data['action'], lambda:None)()

Upvotes: 2

chepner
chepner

Reputation: 531135

Replace the conditionals with a dicts that map strings to the appropriate objects. (This is a generalization of what Kanak proposes, in the strings you care examining don't need to match the names of your methods.)

functions = {
    "pull_requests": {
        "opened" : methodcaller("opened"),
        "closed" : methodcaller("closed"),
        "assigned" : methodcaller("assigned")
    },
    "issues": {
        "opened" : methodcaller("opened"),
        "reopened" : methodcaller("reopened"),
        "closed" : methodcaller("closed"),
        "assigned" : methodcaller("assigned"),
        "labeled": methodcaller("labeled")
    }   
}

classes = {
    "pull_requests": PullRequest,
    "issues": Issue
}

obj = classes[event]
msg = functions[event][data['action']](obj)

Upvotes: 2

Related Questions