1

Here's an example of my question in python. Notice there's only a very subtle difference: changing an if to an elif. There's no difference in behavior; if the first if statement is executed, the second will never be reached. Is it better practice to use an if or an elif in this situation? (Which is better: Option 1 or Option 2?)

Option 1:

def add_two_numbers(a, b):
  if not isinstance(a, int):
    raise TypeError('a must be an int')
  if not isinstance(b, int):
    raise TypeError('b must be an int')
  return a + b

Option 2:

def add_two_numbers(a, b):
  if not isinstance(a, int):
    raise TypeError('a must be an int')
  elif not isinstance(b, int):
    raise TypeError('b must be an int')
  return a + b
blunova
  • 388
  • 1
  • 4
  • 16
jxmorris12
  • 153
  • 4
  • 1
    Does this answer your question? [How would you know if you've written readable and easily maintainable code?](https://softwareengineering.stackexchange.com/questions/141005/how-would-you-know-if-youve-written-readable-and-easily-maintainable-code) – gnat Feb 19 '20 at 15:58
  • No, sorry. This is a question about a specific design pattern: two independent if statements that are assertions. – jxmorris12 Feb 19 '20 at 16:00
  • 5
    What do you mean "better"? How would you judge one is better than the other? – BobDalgleish Feb 19 '20 at 16:04
  • 3
    Those are independent `assert isinstance(a, int), 'a must be an int'`s. So without `elif` seems best fitting. – Joop Eggen Feb 19 '20 at 16:05
  • Thanks for the advice @JoopEggen! I agree with your opinion. – jxmorris12 Feb 19 '20 at 16:05
  • If both assertions can happen, use an if. – gnasher729 Mar 01 '22 at 16:21

1 Answers1

7

As currently written there is no difference in behavior. But considering future changes, option 1 is most maintainable because it represent the logic better.

You are really performing two independent precondition checks. The use of else indicates that the second can only fail if the first succeeds, which is misleading. E.g. you might lift the first restriction while keeping the second unchanged, or you might add other checks or reorder them. Or maybe you decide to collect all precondition errors into a single exception. In all cases, it works better with independent if's.

You would use if-else in cases where the second check really is depending on the first check passing. E.g.

if not isinstance(a, int):
    raise TypeError('a must be an int')
  elif a <= 0:
    raise TypeError('a must be a positive number') 

Here the else is warranted because the checks are not independent. The second only makes sense if the first passes.

JacquesB
  • 57,310
  • 21
  • 127
  • 176