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 appears, the results somehow aren’t what you expected?
    If so, the situation described below might be the cause.
    For reference, since I made this mistake myself, I’m writing it down as a note.

    The problematic program

    The problem arises when you write two conditions in the if and elif statements and build 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 the actual output is as follows.

    patern A
    patern B
    patern C
    patern B

    What 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 and write a program that you expect to output A, B, C, and D, the actual output is as follows.

    patern A
    patern D
    patern D
    patern D

    elif itself is used as shown below 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 involve 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 it worked until you actually look at the results.

    How to fix it

    When you want to branch into multiple cases using multiple conditions, avoid specifying multiple conditions in an 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 becomes more cumbersome, but doing it this way produces 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 not wrapping 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 solve 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 the same, but & also acts as a bitwise AND, so in the original program

    a >= 10 & b < 10

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

    It’s tricky, isn’t it…

  • 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 do you do when there are 10 or 20 branches (rare 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 under case 1 runs.
    When var is 2, the code under case 2 runs.
    When var is anything other than 1 or 2, the default block 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 default block does not need a break; because default is the last branch, so it is obvious that it is the final block.
    That said, writing one is not forbidden—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.
    The syntax isn’t difficult at all, so give it a try.