Tag: if文

  • My elif conditional branching isn’t working!! [Python]

    My elif conditional branching isn’t working!! [Python]

    Have you ever wanted to branch on multiple conditions with an if statement, tried using elif, and found that although no error was raised the results still weren’t right?
    If so, the situation described below might be what’s happening.
    I made this mistake myself, so I’m writing it down here for reference.

    The problematic program

    The problem arises when you write two conditions in the if and elif statements of a program that includes elif.

    def trable(a, b):
        if a >= 10 & b >= 10:
            print("patern A")
        elif a >= 10 & b < 10:
            print("patern B")
        elif a < 10 & b >= 10:
            print("patern C")
        else:
            print("patern D")
    
    trable(11, 11)
    trable(11, 9)
    trable(9, 11)
    trable(9, 9)

    When you run the program above, you might expect the cases to be sorted into patterns A, B, C, and D in order from the top, but what you actually get is the output below.

    patern A
    patern B
    patern C
    patern B

    So what happens if we swap the order?

    def trable(a, b):
        if a >= 10 & b >= 10:
            print("patern A")
        elif a < 10 & b < 10:
            print("patern B")
        elif a >= 10 & b >= 10:
            print("patern C")
        else:
            print("patern D")
    
    trable(11, 11)
    trable(9, 11)
    trable(11, 9)
    trable(9, 9)

    If you swap the code for patterns B and C, expecting the output to come out as A, B, C, D, what you actually get is the output below.

    patern A
    patern D
    patern D
    patern D

    elif itself is used as follows when you want to define multiple conditions.

    if 条件式A:
      条件式Aが真(True)となった場合の処理
    elif 条件式B:
      条件式Aが偽(False)で、条件式Bが真(True)となった場合の処理
    else:
      条件式Aが偽(False)で、条件式Bも偽(False)となった場合の処理

    However, once the conditional expressions in the if and elif statements contain two conditions, the problem described above is likely to occur.
    As a result, you don’t get the output you intended.

    The tricky part is that no error is raised, so you can’t tell whether things are working until you actually look at the results.

    How to fix it

    When you want to branch into multiple cases using compound conditions, avoid specifying multiple conditions in the elif statement.

    def resolve(a, b):
        if a>= 10:
            if b >= 10:
                print("patern A")
            else:
                print("patern B")
    
        else:
            if b >= 10:
                print("patern C")
            else:
                print("patern D")
    
    resolve(11, 11)
    resolve(11, 9)
    resolve(9, 11)
    resolve(9, 9)

    It’s more cumbersome, but doing it this way gives you exactly the output you expect.

    Programming has unexpected pitfalls like this, so it’s a good lesson in carefully checking the code you write.

    Addendum (August 2022)

    It turns out the problem was that I hadn’t wrapped the conditions in parentheses.

    def trable(a, b):
        if (a >= 10) & (b >= 10):
            print("patern A")
        elif (a < 10) & (b < 10):
            print("patern B")
        elif (a >= 10) & (b >= 10):
            print("patern C")
        else:
            print("patern D")

    With this change, the branching worked correctly.
    Alternatively, you can also fix it by writing and instead of &.

    def trable(a, b):
        if a >= 10 and b >= 10:
            print("patern A")
        elif a < 10 and b < 10:
            print("patern B")
        elif a >= 10 and b >= 10:
            print("patern C")
        else:
            print("patern D")

    & and and may seem equivalent, but & also acts as a bitwise AND, so in the original program

    a >= 10 & b < 10

    this apparently means a >= (10 & b) < 10, and
    with a=9, b=9 the inequality becomes
    9>=8<10, which evaluates to True.

    Tricky stuff…

  • The switch-case statement in the Arduino language

    The switch-case statement in the Arduino language

    When you want to branch on various conditions in Arduino, you probably write almost everything with if statements.
    But what should you do when you have 10 or 20 branches (unlikely as that may be)?

    C/C++ has a switch statement, and since the Arduino language is based on C/C++, you can use the same syntax.

    Here is an example program.

    switch (var) {
      case 1:
        // varが1のときに実行する処理
        break;
      case 2:
        // varが1のときに実行する処理
        break;
      default: 
        // どのcaseラベルにも一致しないときに実行する処理
        // defaultは、省略可能
      }

    Here var is a variable: when var is 1, the code in case 1 runs.
    When var is 2, the code in case 2 runs.
    When var is anything other than 1 or 2, the default code runs.

    The “break;” after the code in case 1 and case 2 indicates that the processing for that case has finished.
    Without it, you can run into errors.

    The reason break; is not needed in the default block is that default is the last branch, so it is obvious that it is the final block of code.
    That said, there is no rule against writing it—the program works fine either way.

    You can also omit default: itself.
    It feels much like omitting the else in an if-else statement.

    Personally, I find switch-case statements look tidier than if statements when you read the code.
    It is not particularly difficult code, so give it a try.