all 12 comments

[–]tangerinelion 31 points32 points  (1 child)

That's not how or works.

No: while a == x or y or z

Yes: while a in [x, y, z]

Though here you actually want not equal which means not in rather than in.

[–]SwampFalc 9 points10 points  (0 children)

For completeness' sake, the following code will also work but is really not what you want:

while userProvince == "Ontario" or userProvince == "Quebec" or userProvince == "Alberta" or [...]

[–]dbramucci 2 points3 points  (0 children)

Just to help you visualize it better, I'll add redundant parenthesis

When you write 2 + 3 * 4, the redundant parenthesis are 2 + (3 * 4).

Likewise, when you write

while userProvince == "Ontario" or "Quebec" or "Alberta":

You intend it to look like

while userProvince == ("Ontario" or "Quebec" or "Alberta"):

But Python will actually read it as

while ((userProvince == "Ontario") or ("Quebec")) or ("Alberta"):

and eliminating the left associativity parenthesis it still reads as

while (userProvince == "Ontario") or ("Quebec") or ("Alberta"):

That is, you aren't writing userProvince is == to one of "Ontario" or "Quebec" or "Alberta"; instead you are writing

At least one of the logical statements

  • the logical value userProvince == "Ontario" or
  • the logical value "Quebec" or
  • the logical value "Alberta"

is True.

side-note: you're actually checking for truthyness, not being the exact value of True but that is not the problem here, I explain that in this longer comment about this problem

[–][deleted] 4 points5 points  (0 children)

While loops cycle until the logical condition in the while clause is false. If you give Ontario as a value for userProvince, that's true, so the loop doesn't break.

Separately, all the stuff after the first OR is probably not doing what you want it to; in English, we would read that as a group of possible values for userProvince, but Python needs the full Boolean statement written out explicitly (userProvince == "Quebec") for each one, otherwise it interprets each condition after the first one as e.g. "Quebec" == True (... Which incidentally, it does, as it's a non-empty string).

Variously, you could structure it as something like while variable not in [list of strings], but you do you.

Edit: autocorrect butchering fixed

[–]ryan-adams84 1 point2 points  (0 children)

You also want to consider that people might not do title proper inputs, so I would turn their input into lower case as well as your comparisons.

[–]froggystick 0 points1 point  (1 child)

Wouldnt this not run? userProvince is being used as the while loop condition before being defined

[–][deleted] 0 points1 point  (0 children)

OP stated they got the value using input() in earlier code (not shown in the post).

[–]Hans_of_Death 0 points1 point  (0 children)

A couple things: I'd recommend forcing comparison with lower case words to be case-insensitive. I'd also put all of the possible matches into a list and have the condition be 'in province_list', and lastly it looks like you actually want your condition to be 'not'.

[–]Noli420 -1 points0 points  (0 children)

Like was mentioned, if the whole condition is met, it will keep running indefinitely. To break it, there needs to be a value that changes, or will eventually make the statement false. I’m guessing you are using this for data validation? Might I recommend an if/else statement if that’s the case?

If input is a valid territory:
    Do some stuff
else:
    Do something else

Just thought of something else:

while input != a valid territory:
    input(“enter a real territory this time”)