import operator import functools import random def foldl(func, acc, xs): return functools.reduce(func, xs, acc) foldl(operator.add, 0, [1,2,3,4,5,6,7,8,9,10]) # parity check, function = xor, acc = 0 sequece, 0s and 1s random.seed(1) print(" Bitstirng | Parity ") print("-"*34) #generating a random 12-digit binary string for _ in range(1): seq = [random.randint(0,1) for _ in range(12)] print(f"{''.join(str(b) for b in seq)} | {foldl(operator.xor, 0, seq)}") random.seed(1) def traceXOR(a,b): """ shows the intermediate steps of xor function on a sequence """ result = operator.xor(a, b) print(f"{a} XOR {b} = {result}") return result print(foldl(traceXOR, 0, [1, 0, 0, 1, 1])) """ The math behind the above XOR operations is '0' is the initial accumulator value so 0 XOR 1 == 1 now the accumulator value has been changed to 1 so the second operation 1 XOR 0 = 1 1 XOR 0 = 1 1 XOR 1 = 0 0 XOR 1 = 1 1----> is the final accumulator value """