0

New to python. How do I verify a function implementing an n parameters xor when using the ^ operator? I extended the code to handle string input. To do so, I made the assumption that 0.0, '' and None would be 0, and any other value, positive or negative, would be 1. However, integer values would be handled in the usual way, so that 6^5 == 3. I'd prefer to coerce the input to integer where it can be coerced (e.g. 11.0 or '11' could be cast as int).

I've seen the issue of logical versus bitwise xor operations in python covered elsewhere, but their limitations are that the discussions are limited to inputs a and b only. I would like to verify a solution tested to an arbitrary number of arguments and coerced inputs.

Other solutions checked

I experimented with a few suggestions for logical xor from How do you get the logical xor of two variables in Python?. However, none of the solutions that I tried seemed to work. For example:

  • ^ doesn't work with strings, and isn't iterable.
  • int(bool(a) ^ bool(b)) doesn't work with n arguments.
  • (a and not b) or (not a and b) breaks if the input b is a string.

What I tried

I started with the following code.

Exhibit 1

def xor(*args):
    return int(any(args) != all(args))

Exhibit 1 has logic that only works for the case of two arguments, and I haven't figured out what it's truth table resembles in the case of more arguments. As a result, I tweaked the function to use the ^= operator, as follows.

Exhibit 2

def xor(*args, parity = True):
    exOr = False
    checker = list()
    for arg in args:
        # try to coerce arg to int, so that '11' = 11, 11.0 = 11
        exOr ^= arg if type(arg) == int else bool(arg)
        checker.append(bool(arg))
    exOr = 0 if all(checker) and not parity else exOr
    return int(exOr)

The logic for Exhibit 2 seems to work for any number of arguments I have tested, albeit writing down a truth table manually on paper and following along in python output is prone to error. Also, the code in Exhibit 2 doesn't coerce inputs at all where they can be coerced.

Why the parity parameter in Exhibit 2?

There seems to be some disagreement over two interpretations of xor logic for more than two inputs (xor - The Interesting Gate and How is an xor with more than two inputs supposed to work). It seems to me that a solution for more than two inputs should select between both options, since both are written into standards apparently, which is why I added the accumulator and the logic to invert all(checker).

Summary of Questions

I hope the above discussion makes sense. I don't know how to test the code efficiently, and I don't know how to coerce the input to int if it can be. For testing the code I feel like I need a better method than comparing paper notes with function output.

khelwood
  • 55,782
  • 14
  • 81
  • 108
DCommK
  • 11
  • 2

1 Answers1

0

This post regards a solution to the coercion part, using try: and except:. However, this doesn't answer the testing question.

In the original function:

def cInt(arg):
    tmp = arg
    try:
        arg = int(float(arg))
        if arg == float(tmp):
            return arg
        else:
            return tmp
    except:
        return tmp


def xor(*args, parity = True):
    exOr = False
    checker = list()
    for arg in args:
        arg = cInt(arg)
        exOr ^= arg if type(arg) == int else bool(arg)
        checker.append(bool(arg))
    exOr = 0 if all(checker) and not parity else exOr
    return int(exOr)

xor(1, '1.0', "1")
xor(1, '1.0', "1", parity = False)

1
0

DCommK
  • 11
  • 2
  • Turns out it's easy to search for a truth table for 4-bit xor. For example: https://www.mtholyoke.edu/courses/dstrahma/cs221/homework/logicworkshw.htm – DCommK Apr 20 '21 at 07:23
  • Replit.com has a python environment and a Unit Tests interface that can be setup to test code. I was able to generate tests through 4-bit binary as of this post. However, I'd prefer not to depend on a gui. – DCommK Apr 20 '21 at 07:28