0

I'm trying to make some code that I wrote hastily with a lot of copy/pastes a little cleaner. I noticed that I have two functions that are irritatingly close to doing the same thing. Here's the gists of them:

def determine_risk(difference):
    if difference > ON_TRACK:
        return 'On Track'
    elif difference < HIGH_RISK:
        return 'High Risk'
    else:
        return 'Low Risk'

def determine_completeness(pct_complete):
    if pct_complete == UNSTARTED:
        return 'Unstarted'
    elif pct_complete > READY:
        return 'Ready'
    else:
        return 'In Process'

I'd love to turn this into one function. Something like

def determine_condition(metric, [list_of_conditions], [list_of_outcomes], fallback)
    for condition, outcome in zip(list_of_conditions, list_of_outomes):
         if metric satisfies condition:
              return outcome
    return fallback

The problem is I don't think it's possible to store conditional checks in a list like that! Posting here in case someone can show me a way, or sees an alternative approach to combining these similar types of function into one

HarlandMason
  • 779
  • 5
  • 17

1 Answers1

2

You could store conditions as an array of lambda expressions, e.g.:

a = lambda x: x > 1
b = lambda x: x < 5
conditions = [a, b]

But to be honest, I wouldn't. There's absolutely nothing wrong with the two functions in your first example - they have sensible names, and I can clearly tell when reading them what they do.

If you refactored your code to use the second example, you lose this. Whenever I see a call to determine_condition, I have to go and read what the function does, and figure out that it's just a generic way of checking a bunch of conditions.

Sometimes it's better to sacrifice brevity at the altar of readability, and for me this is one of those times.

Edit

The lambda examples I gave didn't return booleans which is what you'd need - modified so they do

Rob Gwynn-Jones
  • 677
  • 1
  • 4
  • 14
  • Don't use a lambda expression as a one-line `def` statement. – chepner Dec 14 '17 at 00:50
  • @chepner that's the simplest example I could think of to demonstrate how the OP might achieve what he was trying to do. My overall point is that I don't think you should do things like this :) – Rob Gwynn-Jones Dec 14 '17 at 00:52
  • 3
    I consider this a great answer. "Here's how you can do what you're trying to do, but here's why you shouldn't do that at all" is a pretty common pattern for SO answers, and I don't mind there being some code that might get flagged in review in the block of "This works, but don't do it" code. – Adam Smith Dec 14 '17 at 00:52
  • 1
    I agree. Learning about philosophy of writing good code is as welcome as neat tricks to streamline code. Thank you @RobGwynn-Jones – HarlandMason Dec 14 '17 at 01:00