0

So I'm trying to implement the logical operator XOR in Python. I first ask the user for how many inputs they want to test (4 - TT, TF, FT, FF). I know that XOR evaluates T&T->F, T&F->T, F&T->T, F&F->F.

I store the first boolean that I get as input from the user in a variable P as a string. I then convert to boolean. As so...

    P = input("Enter boolean number 1: ")
    P = bool(P)

I don't cast the input as bool right away since any non-empty string will result in True regardless of the string being "False."

I have the XOR truth table established for the four possible conditions mentioned above as four separate if statements and then just print("P xor Q is False" or "P xor Q is True") all depending on the truth table for XOR.

All this logic is inside a for loop that counts down by 1 until 0 from the user's input of how many inputs they wanted to make.

When I run this program, regardless of what the user enters, the print statement is "P xor Q is False."

I just can't figure out why! I feel the solution is pretty simple which is what is bothering me, so any help in the right direction would be appreciated, thank you!

Here's my code:

numOfInputs = int(input("Enter the number of inputs: "))

for num in range(numOfInputs, 0, -1):
    print()

    P = input("Enter the first boolean: ")
    P = bool(P)
    Q = input("Enter the second boolean: ")
    Q = bool(Q)

    print()

    if(P == True and Q == True):
        print("P xor Q is False")
    if(P == True and Q == False):
        print("P xor Q is True")
    if(P == False and Q == True):
        print("P xor Q is True")
    if(P == False and Q == False):
        print("P xor Q is False")
S. Tolm
  • 1
  • 2
  • "I don't cast the input as bool" - but you do, in the line `P = bool(P)`. Why do you think you don't? – user2357112 Oct 04 '15 at 04:12
  • Is that still the same as P = bool(input(...)) then? I sorta figured that anything besides the empty string would be evaluated to "True" if casted right away. – S. Tolm Oct 04 '15 at 04:15
  • Any non-empty string will convert to True as a boolean. That doesn't change if you move the `bool` call to another line. – user2357112 Oct 04 '15 at 04:16
  • Makes sense. How should I change my approach then? – S. Tolm Oct 04 '15 at 04:20
  • Without actually posting your code , no one will be able to help you. – OozeMeister Oct 04 '15 at 04:28
  • Depends on what inputs should produce True or False. Something like `if P.lower() in ('t', 'true'): P = True` might be a start. – user2357112 Oct 04 '15 at 04:30
  • Possible duplicate of [Convert True/False value read from file to boolean](http://stackoverflow.com/questions/21732123/convert-true-false-value-read-from-file-to-boolean) – Peter Wood Oct 04 '15 at 05:13
  • It would help to have comments indicating the form of user input you expect. Is it just "True" or "False" for each prompt? If so, then Burhan Khalid's answer works. If they'll be supplying actual expressions, you'll have to use eval() or something (warning: POTENTIAL FOR MASSIVE SECURITY HOLES) to get it. Also, be aware that XOR gets confusing with more than 2 inputs. See discussion: http://mathworld.wolfram.com/XOR.html – Paul Gowder Oct 04 '15 at 05:20
  • 1
    @PaulGowder I've already posted an answer using [**`literal_eval`**](https://docs.python.org/2/library/ast.html#ast.literal_eval), which is safe. Using `eval` really isn't a good idea. – Peter Wood Oct 04 '15 at 05:22
  • Right, but by "actual expressions" I meant passing in something like "foo == bar" -- which, as I read the docs, literal_eval won't evaluate. – Paul Gowder Oct 04 '15 at 05:25
  • @PaulGowder You're the only person to mention expressions. – Peter Wood Oct 04 '15 at 05:27

2 Answers2

2

Both T and F are "true" as any non-empty string is "true" in Python. This might explain why your loop isn't working as expected.

The first step is to fix your casting:

p = input('Enter a boolean value, True or False: ')
if p.lower() == 'false':
   p = False
q = input('Enter the second boolean, True or False: ')
if q.lower() == 'false':
   q = False

Now, a XOR is simply when two values do not equal each other:

if p != q:
   print('p xor q is true')
else:
   print('p xor q is false')
Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
  • Just figured this out as well. Works! How would I implement it using only the logical operators (and/not/or), so no equal or not-equal signs? – S. Tolm Oct 04 '15 at 05:14
  • @S.Tolm Your comparison code is fine, it's just your inputs which needed fixing. – Peter Wood Oct 04 '15 at 05:15
  • 1
    There's no `p = True` or `q = True` case here. It happens to mostly work anyway, but it's pretty fragile. – user2357112 Oct 04 '15 at 05:34
0

Your code works fine if you use an empty string for False, i.e. just press return.

An empty string is the only string value which bool converts to False:

>>> bool('False')
True

>>> bool('0')
True

>>> bool('')
False

See the documentation.

If you're not using strings Python considers 0, {}, [], to all be equivalent to False, i.e. zero or empty containers. Most other things are True.

If you want to use any of those as input you can convert the string value to the actual type using ast.literal_eval, then convert to a bool to get True or False.

>>> import ast.literal_eval
>>> value = literal_eval('False')
>>> type(value)
bool
>>> value
False

>>> value = literal_eval('0')
>>> type(value)
int
>>> bool(value)
False

Your boolean comparisons can be simplified, e.g.:

if(P == True and Q == False):
    print("P xor Q is True")

could be:

if P and not Q:
    print("P xor Q is True")
Peter Wood
  • 23,859
  • 5
  • 60
  • 99