0

for some reason this statement triggers no matter what the variable "msg" has stored. It should only react to what you see in the code. Please let me know if I have written this statement correctly or if I need to format it another way. Thank you

if (username == "ssj3goku878") or (username == "mgnlive") and msg == "!load": 
     keyholder.holdForSeconds("F7", 1);
if (username == "ssj3goku878") or (username == "mgnlive") and msg == "!save": 
     keyholder.holdForSeconds("F8", 1);
1

3 Answers 3

6

You need another set of brackets, i.e.

((username == "ssj3goku878") or (username == "mgnlive")) and msg == "!load": 
Sign up to request clarification or add additional context in comments.

1 Comment

Some explanation would benefit this answer.
4

Due to operator precedence or has lower binding precedence than does and. For example a similar expression to yours is:

a or b and c

which is interpreted as shown by the parentheses:

a or (b and c)

because and has higher precedence. In this case the expression will always be True if a is True, and the sub-expression (b and c) will not be evaluated. So it makes no difference what the sub-expression evaluates to and thus changing the value of c will not affect the result (N.B when a is True).

So, for your expression, whenever username == "ssj3goku878" is True, the value of msg has no bearing on the overall result and you will find that both if statements execute their bodies.

To correct this, you should explicitly add parentheses to override the default precedences:

if ((username == "ssj3goku878") or (username == "mgnlive")) and msg == "!load": 
     keyholder.holdForSeconds("F7", 1)

You probably have more than 2 users and would prefer not to have to alter your program whenever a new user is added, so this might be preferable:

users = ["ssj3goku878", "mgnlive", "user3"]
if username in users and msg == '!load':
    keyholder.holdForSeconds("F7", 1)

The users list can be populated from a file, database or other persistent source. In this case in has higher precedence than and so parentheses are not required, however, it is often easier to explicitly add parentheses than it is for you (or whomever is reading your code) to remember (or lookup) the precedences, so this is usually better:

if (username in users) and msg == '!load':

1 Comment

Excellent! This is definitely a better way to design this. Thank you!
1

Python evaluates and operators before or operators (unless they are in parentheses). So therefore, if you want the logic to be evaluated the way you intended, you should add parentheses, eg:

if ((username == "ssj3goku878") or (username == "mgnlive")) and msg == "!load":
     keyholder.holdForSeconds("F7", 1);

More information on the workings of these operators can be found here: https://docs.python.org/2/library/stdtypes.html#boolean-operations-and-or-not

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.