2

I commonly use a boolean condition/variable when it's something too big or complicated and takes too much space by itself inside ifs - basically to avoid repeatability and thus improve readability. E.g. has_three_repeated_digits = len(some_number) == 4 and len(set(some_number[1:]) and set(some_number[:-1])) != 1 and ... etc. So it is used as if has_three_repeated_digits:...

However, I've noticed it is quite common to use boolean-returning functions instead:

def has_three_repeated_digits(number):
    return len(number) == 4  # ... etc 

And it is used as if has_three_repeated_digits(some_number): ...

So, when should I turn my boolean variable has_foo into a function has_foo(bar)? My initial suspicion is that I should do it whenever this variable will be used inside another method, or at a similar situation (as making a boolean variable global would be quite... ugly?). But I'm not sure.

1
  • In addition to the answers below, turning the conditions into functions makes it easier/faster to debug and test your code.
    – jfaccioni
    Jun 23, 2020 at 12:16

5 Answers 5

2

There are no hard rules for when to extract boolean conditions into their own function. It depends a lot on the logic happening in the code, how much code there is in the method, how readable the code is, if you need to reuse the condition some place else, etc.

If you need the same conditional check in multiple places, then the answer it pretty much straight forward. It's a good idea to extract the condition in a function and reuse it.

Other cases are not as clear cut as the reusability situation. Too many conditions in the code can make the code hard to read and can obscure the logic as you need to concentrate on each condition to see the execution paths. You can then extract the conditions in variables to better expose the logic, so your brain doesn't need to focus on each condition evaluation (a properly named variable better expresses this). But if you have a lot of these variables, even if the logic would be easier to read with them, you can still have a large function. Size of functions adds to them being less readable. So it might now make sense to replace those variables with a function call. You will then have smaller functions, doing less things, thus easier to read. Sometimes you can even replace related conditions with a single function. There is a lot to say about it so I'll stop here and instead leave you with some resources to read that do a far better job at explaining various situations than I could in this answer:

  • Martin Fowler's book on Refactoring has a full chapter (Ch. 9) dedicated to simplifying conditionals;
  • if you don't have the refactoring book, you can read about the techniques here.
1

I'd prefer extracting the complex condition to a function.

Why?

By introducing well-named classes, methods, functions and so on, we create the application-specific language that we want to express our solution in.

Being able to just call has_three_repeated_digits(some_number) serves that goal better than filling multiple lines of code in the higher-level function with the boolean expression that implements the concept.

0

You said you use such computed boolean variables for avoiding redundancy and improving readability. So, instead of computing it again and again you just compute it once, store it, and use it as required.

The same logic needs to be applied when deciding whether to use a variable or a function. The goal is to make the code non-redundant and, as a result, improve readability.

Answer: If the computation is to be done only once and within a single function/method only, a variable should be used. Otherwise, a function/method should be used.

0

If there is lots of code to evaluate the Boolean expression, at some point you should extract it just because of the amount of code. I assume that’s not the case.

Something like “hasThreeRepeatedDigits”: What the code does and its purpose are the same. If someone else needs to check for three repeated digits, duplicating the code is just a tiny inefficiency, not a problem. There is no need to extract this as a function.

But there are cases where the purpose is not obvious, even when the code itself is. And if I write code for the same purpose, I could do it differently which would be a bug. In that case you should have a separate function. Same if the actual code to test for the purpose might change.

0

In addition to your desire to be DRY you should consider scope. You may isolate your expression in a method but it will end up being out of place and noisy to other scopes, which will see it but to which it will be meaningless. Therefore I would be hesitant to put it in a method if it would not save a whole lot of repetition.

If you do wrap it in a method you should consider in what class. Your example would fit well in a class named StringStats or something and should be static. It is always tempting to put these things in the class where you happen to need them and sometimes that won't hurt. If you do this make sure the method is private and static so it does not polute your class's interface.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.