You should also consider using && and || instead of & and |. The difference is that && and || can "short circuit" the evaluation as soon as it discovers what the result must be. As an example, if you have an expression (x && y) and x evaluates as false, then y is never even evaluated. Similarly for the expression (x || y) evaluates x as true, then y is not evaluated.
Some of us old timers have the advantage (?) of coming from a COBOL background. The language lets you leave out certain repetitious parts of the syntax for brevity:
Of course humans say "if a not 1 or 2 or 3" so we coded it wrong about half the time - exactly as you did. After a few thousand errors - stare at the code for a day and not see why it doesn't work - we all learn to stop and look at these things twice before going on. So welcome aboard! If you learned to stop and examine any "and" and "or" code on the first error you're way ahead!
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi