0

This is some code that I wrote up to generate a set of numbers;

def _tnry(x,y,z):
    a = None

    if((y == 0 & z == 0) | (x == 0 & y == 0) | (x == 0 & z == 0)):
        a = 1

    if((y == 1 & z == 1) | (x == 1 & y == 1) | (x == 1 & z == 1)):
        a = 2

    if((y == 2 & z == 2) | (x == 2 & y == 2) | (x == 2 & z == 2)):
        a = 0

    print(x,y,z,'ternary =',a )

I am having some problems with the output when you give the input of the following:

_tnry(0,1,2)
_tnry(0,2,1)
_tnry(1,0,2)
_tnry(1,2,0)
_tnry(2,0,1)
_tnry(2,1,0)

As far as I can see in my code a should not ever come out as being equal to 0, 1 or 2. I want to force it to always be None in the examples given.

All other output from the script is how I want it to come out.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Whitequill Riclo
  • 788
  • 2
  • 8
  • 19
  • Did you mean `or` instead of `|`, and `and` instead of `&`? – cs95 Aug 10 '17 at 04:11
  • yes I did mean | and & . A good explaination is at the following link [https://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is-in-python](https://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is-in-python) – Whitequill Riclo Aug 10 '17 at 04:17
  • why use `&` instead of `and` ? – Jasen Aug 10 '17 at 04:36

3 Answers3

2

Bitwise operators & have higher precedence over other operators, so

y == 0 & z == 0

is actually interpreted as

y == (0 & z) == 0

Which ends up becoming

y == 0 == 0

Which is different from what you want. This applies to all your conditions.

You'll want to fix this by using another layer of parens:

(y == 0) & (z == 0)
cs95
  • 379,657
  • 97
  • 704
  • 746
  • or use `and` instead of `&` – Jasen Aug 10 '17 at 04:23
  • @Jasen Which I thought at first but apparently OP knows what they're doing. – cs95 Aug 10 '17 at 04:24
  • @cᴏʟᴅsᴘᴇᴇᴅ: Thank you! I didn't know that was how Python read the code internally. That is exactly what I needed to know to fix the issue. – Whitequill Riclo Aug 10 '17 at 04:28
  • @cᴏʟᴅsᴘᴇᴇᴅ: do you know where I can read more about how Python works internally so I can optimize the code I write in the future? – Whitequill Riclo Aug 10 '17 at 04:32
  • @WhitequillRiclo Glad to help. As for the inner machinations of python, you should start by perusing the docs. 95% of what you need to know is there. The rest of it can be found in the cpython developers mailing lists :) – cs95 Aug 10 '17 at 04:33
  • @cᴏʟᴅsᴘᴇᴇᴅ: I will look over the docs. I've never read the documentation before. I will also consider joining the developers mailing list. I'm more a Python programmer than a dev, so I hadn't considered joining the mailing list before. – Whitequill Riclo Aug 10 '17 at 04:45
0

Here's a shorter and easier-to-debug, although maybe less clear, way to approach it (assumes all inputs are 0,1, or 2, and that you do in fact mean or and and rather than bitwise):

def _tnry(x,y,z):

    if len({x,y,z}) < 3: #at least two are the same:
        return (sorted([x,y,z])[1] + 1) % 3

If at least two are the same, then the middle one when they're sorted will be from the majority. Returns None by default, like all Python functions.

perigon
  • 2,160
  • 11
  • 16
0

use and for logical and.

def _tnry(x,y,z):
    a = None
    if((y == 0 and z == 0) | (x == 0 and y == 0) | (x == 0 and z == 0)):
        a = 1
    if((y == 1 and z == 1) | (x == 1 and y == 1) | (x == 1 and z == 1)):
        a = 2
    if((y == 2 and z == 2) | (x == 2 and y == 2) | (x == 2 and z == 2)):
        a = 0
    print(x,y,z,'ternary =',a )

if there's no need to constrain the input to 0,1,2 I would write it like this:

def _tnry(x,y,z):
    if y == z or x == z :
        a = z
    elif x == y : 
        a = x
    else:
        a = None
    print(x,y,z,'ternary =',a )
Jasen
  • 11,837
  • 2
  • 30
  • 48