# Read A Text File Describing A Digital Logic Circuit And Output The Truth Table For Circuit Assignment Solution

June 29, 2024
Isaac Connolly
Python
Isaac Connolly is an adept Python Assignment Expert with 12 years of experience, holding a prestigious Master's degree from a leading institution in Canada.
Key Topics
• Instructions
• Requirements and Specifications
Tip of the day
News

## Instructions

Objective
Write a program to read a text file that describes a digital logic circuit and output the truth table for the circuit.

## Requirements and Specifications

Your program should take a single command line argument specifying the path to an input file. The input file is a digital circuit description that lists how many input and output variables are in the circuit, the names of the input and output variables, and digital logic gates that describe how the output variables relate to the input variables.
• The first line of the file will look like this: "INPUTVAR 2 input0 input1". The number N indicates the number of Boolean input variables to the digital logic circuit. In this case N=2. The rest of the line lists the names of the input variables, separated by spaces.
• The second line of the file will look like this: "OUTPUTVAR 1 output0". The number M indicates the number of Boolean output variables from the digital logic circuit. In this case M=1. The rest of line lists the names of the output variables, separated by spaces.
• The remainder of the file will have lines describing digital logic gates. The gates have either a single input or two inputs:
• Single input gates include the "NOT" gate. A line describing such a gate will look like this: "NOT input0 temp0". This means the Boolean value of temp0 = ! input0. The intermediate Boolean variable temp0 is a variable in the circuit that is neither part of the inputs nor outputs of the digital circuit, but you need to keep track of temp0's value to calculate the circuit's truth table.
• Double input gates include the "AND", "NAND", "OR", "NOR", "XOR", and "XNOR" gates. A line describing such a gate will like this: "XNOR input1 temp0 output0". This means the Boolean value of output0 = input1 XNOR temp0.
For 2 inputs
The input format for the previous part, basicGates, carries over, with these important differences:
• Instead of double input gates, the input files now have multi-input gates that include the "AND", "NAND", "OR", and "NOR" gates. A line describing such a gate will like this: "AND 3 input1 input0 input1 temp0". The second entry on the line indicates that this AND gate takes three inputs, which are immediately listed before listing the single output variable. This means the Boolean value of temp0 = input1 AND input0 AND input1.
• The input files will no longer have "XOR" and "XNOR" gates as these gates do not have a strict definition for multiple inputs.
Screenshots of output

Source Code

Basic Gates

`#!/usr/bin/python3import os import datetimeimport randomimport subprocessdef generate_test ( filenum, inCount=1, gateCount=0, outCount=1, path="./" ):    inVars = [ "input"+str(i) for i in range(inCount) ]    gates = ("NOT", "AND", "NAND", "OR", "NOR", "XOR", "XNOR")    tempCount = 0    tempVars = inVars.copy()    circuit = []    outVars = []    for i in range(gateCount):        in0 = random.choice(tempVars)        in1 = random.choice(tempVars)        gate = random.choice(gates)        out = "temp"+str(tempCount)        tempCount += 1        circuit.append({ "in0":in0, "in1":in1, "gate":gate, "out":out })        tempVars.append(out)        for i in range(outCount):        in0 = random.choice(tempVars)        in1 = random.choice(tempVars)        gate = random.choice(gates)        out = "output"+str(i)        circuit.append({ "in0":in0, "in1":in1, "gate":gate, "out":out })        outVars.append(out)        with open("{}tests/test{}.txt".format(path,filenum), "w") as infile:         infile.write("INPUTVAR {}".format(inCount))        for inVar in inVars:            infile.write(" "+inVar)        infile.write("\n")        infile.write("OUTPUTVAR {}".format(outCount))        for outVar in outVars:            infile.write(" "+outVar)        infile.write("\n")        for gate in circuit:            if gate["gate"] is "NOT":                infile.write( "NOT {} {}\n".format( gate["in0"], gate["out"] ) )            else:                infile.write( "{} {} {} {}\n".format( gate["gate"], gate["in0"], gate["in1"], gate["out"] ) )                with open("{}answers/answer{}.txt".format(path,filenum), "w") as outfile:                for i in range(2**inCount):            state = {}            for bit, inVar in enumerate(inVars):                state[inVar] = bool(1&i>>bit)               for gate in circuit:                inState0 = state[gate["in0"]]                inState1 = state[gate["in1"]]                if gate["gate"] is "NOT":                    outState = not inState0                elif gate["gate"] is "AND":                    outState = inState0 and inState1                elif gate["gate"] is "NAND":                    outState = not(inState0 and inState1)                elif gate["gate"] is "OR":                    outState = inState0 or inState1                elif gate["gate"] is "NOR":                    outState = not(inState0 or inState1)                elif gate["gate"] is "XOR":                    outState = inState0!=inState1                elif gate["gate"] is "XNOR":                    outState = inState0==inState1                else:                    error()                state[gate["out"]] = outState            for inVar in inVars:                outfile.write("{} ".format(int(state[inVar])))            for outVar in outVars:                outfile.write("{} ".format(int(state[outVar])))            outfile.write("\n")def generate_test_suite():    os.makedirs("tests", exist_ok=True)    os.makedirs("answers", exist_ok=True)    generate_test ( 0, inCount=1, gateCount=0, outCount=1, path="./" )    generate_test ( 1, inCount=2, gateCount=1, outCount=1, path="./" )    generate_test ( 2, inCount=2, gateCount=2, outCount=2, path="./" )    generate_test ( 3, inCount=2, gateCount=4, outCount=2, path="./" )    generate_test ( 4, inCount=4, gateCount=8, outCount=4, path="./" )    generate_test ( 5, inCount=4, gateCount=16, outCount=4, path="./" )def test_basicGates ( filenum, path="./", verbose=False ):    try:        with open("{}answers/answer{}.txt".format(path,filenum), "r") as outfile:            answerSet = set()            for line in outfile.read().split("\n"):                row = []                for string in line.split(" "):                    if string is not "":                        row.append(int(string))                if line is not "":                    answerSet.add(tuple(row))    except EnvironmentError: # parent of IOError, OSError        print ("answers/answer{}.txt missing".format(filenum))    try:        result = subprocess.run(            ["./basicGates", "tests/test{}.txt".format(filenum)],            cwd=path,            check=True,            stdout=subprocess.PIPE,            stderr=subprocess.STDOUT,            encoding="ASCII",            timeout=datetime.timedelta(seconds=4).total_seconds(),        )        resultSet = set()        for line in result.stdout.split("\n"):            row = []            for string in line.split(" "):                if string is not "":                    row.append(int(string))            if line is not "":                resultSet.add(tuple(row))        if verbose:            print (' '.join(result.args))            # print ("answer")            # print (answerSet)            # print ("result")            # print (result.stdout)        assert resultSet == answerSet, "The circuit simulation result doesn't match answers/answer{}.txt.".format(filenum)        return True    except subprocess.CalledProcessError as e:        print (e.output)        print ("Calling ./basicGates returned non-zero exit status.")    except ValueError as e:        print (result.stdout)        print ("Please check your output formatting.")    except AssertionError as e:        print (result.stdout)        print (e.args[0])    return Falsedef grade_basicGates( path="./", verbose=False ):    score = 0    try:        subprocess.run( ["make", "-B"], cwd=path, check=True, )    except subprocess.CalledProcessError as e:        print ("Couldn't compile basicGates.")        return score    if test_basicGates(0,path,verbose):        score += 5        if test_basicGates(1,path,verbose):            score += 5            if test_basicGates(2,path,verbose):                score += 5                if test_basicGates(3,path,verbose):                    score+= 5                    if test_basicGates(4,path,verbose):                        score += 5                        if test_basicGates(5,path,verbose):                            score += 5                            for filenum in range(6,16):                                generate_test ( filenum, inCount=8, gateCount=16, outCount=8, path=path )                                if test_basicGates(filenum,path,verbose):                                    score += 1                                else:                                    break    print ("Score on basicGates: {} out of 40.".format(score))    return scoreif __name__ == '__main__':    # generate_test_suite()    grade_basicGates(verbose=True)    exit()`

Multi Input

`#!/usr/bin/python3import osimport datetimeimport randomimport subprocessdef generate_test ( filenum, circuitInCount=1, gateInMax=4, gateCount=0, circuitOutCount=1, path="./" ):    inVars = [ "input"+str(i) for i in range(circuitInCount) ]    gates = ("NOT", "AND", "NAND", "OR", "NOR")    tempCount = 0    tempVars = inVars.copy()    circuit = []    outVars = []    for i in range(gateCount):        gate = random.choice(gates)        if gate is "NOT":            gateInCount = 1        elif gate in ("AND", "NAND", "OR", "NOR"):            gateInCount = random.randint(2,gateInMax)        gateIn = random.choices(tempVars,k=gateInCount)        gateOut = "temp"+str(tempCount)        tempCount += 1        circuit.append({ "inCount":gateInCount, "gateIn":gateIn, "gate":gate, "gateOut":gateOut })        tempVars.append(gateOut)    for i in range(circuitOutCount):        gate = random.choice(gates)        if gate is "NOT":            gateInCount = 1        elif gate in ("AND", "NAND", "OR", "NOR"):            gateInCount = random.randint(2,gateInMax)        gateIn = random.choices(tempVars,k=gateInCount)        gateOut = "output"+str(i)        circuit.append({ "inCount":gateInCount, "gateIn":gateIn, "gate":gate, "gateOut":gateOut })        outVars.append(gateOut)    with open("{}tests/test{}.txt".format(path,filenum), "w") as infile:        infile.write("INPUTVAR {}".format(circuitInCount))        for inVar in inVars:            infile.write(" "+inVar)        infile.write("\n")        infile.write("OUTPUTVAR {}".format(circuitOutCount))        for outVar in outVars:            infile.write(" "+outVar)        infile.write("\n")        for gate in circuit:            if gate["gate"] is "NOT":                infile.write( "NOT {} {}\n".format( ' '.join(map(str, gate["gateIn"])), gate["gateOut"] ) )            else:                infile.write( "{} {} {} {}\n".format( gate["gate"], gate["inCount"], ' '.join(map(str, gate["gateIn"])), gate["gateOut"] ) )    with open("{}answers/answer{}.txt".format(path,filenum), "w") as outfile:        for i in range(2**circuitInCount):            state = {}            for bit, inVar in enumerate(inVars):                state[inVar] = bool(1&i>>bit)            for gate in circuit:                inStates = [ state[gateIn] for gateIn in gate["gateIn"] ]                if gate["gate"] is "NOT":                    outState = not inStates[0]                elif gate["gate"] is "AND":                    outState = True                    for inState in inStates:                        outState = outState and inState                elif gate["gate"] is "NAND":                    outState = True                    for inState in inStates:                        outState = outState and inState                    outState = not outState                elif gate["gate"] is "OR":                    outState = False                    for inState in inStates:                        outState = outState or inState                elif gate["gate"] is "NOR":                    outState = False                    for inState in inStates:                        outState = outState or inState                    outState = not outState                else:                    sys.exit("Invalid gate.")                state[gate["gateOut"]] = outState            for inVar in inVars:                outfile.write("{} ".format(int(state[inVar])))            for outVar in outVars:                outfile.write("{} ".format(int(state[outVar])))            outfile.write("\n")def generate_test_suite():    os.makedirs("tests", exist_ok=True)    os.makedirs("answers", exist_ok=True)    generate_test ( 0, circuitInCount=1, gateInMax=2, gateCount=0, circuitOutCount=1, path="./" )    generate_test ( 1, circuitInCount=2, gateInMax=2, gateCount=1, circuitOutCount=1, path="./" )    generate_test ( 2, circuitInCount=2, gateInMax=3, gateCount=2, circuitOutCount=2, path="./" )    generate_test ( 3, circuitInCount=2, gateInMax=4, gateCount=4, circuitOutCount=2, path="./" )    generate_test ( 4, circuitInCount=4, gateInMax=5, gateCount=8, circuitOutCount=4, path="./" )    generate_test ( 5, circuitInCount=4, gateInMax=6, gateCount=16, circuitOutCount=4, path="./" )def test_multiInput ( filenum, path="./", verbose=False ):    try:        with open("{}answers/answer{}.txt".format(path,filenum), "r") as outfile:            answerSet = set()            for line in outfile.read().split("\n"):                row = []                for string in line.split(" "):                    if string is not "":                        row.append(int(string))                if line is not "":                    answerSet.add(tuple(row))    except EnvironmentError: # parent of IOError, OSError        print ("answers/answer{}.txt missing".format(filenum))    try:        result = subprocess.run(            ["./multiInput", "tests/test{}.txt".format(filenum)],            cwd=path,            check=True,            stdout=subprocess.PIPE,            stderr=subprocess.STDOUT,            encoding="ASCII",            timeout=datetime.timedelta(seconds=4).total_seconds(),        )        resultSet = set()        for line in result.stdout.split("\n"):            row = []            for string in line.split(" "):                if string is not "":                    row.append(int(string))            if line is not "":                resultSet.add(tuple(row))        if verbose:            print (' '.join(result.args))            # print ("answer")            # print (answerSet)            # print ("result")            # print (result.stdout)        assert resultSet == answerSet, "The circuit simulation result doesn't match answers/answer{}.txt.".format(filenum)        return True    except subprocess.CalledProcessError as e:        print (e.output)        print ("Calling ./multiInput returned non-zero exit status.")    except ValueError as e:        print (result.stdout)        print ("Please check your output formatting.")    except AssertionError as e:        print (result.stdout)        print (e.args[0])    return Falsedef grade_multiInput( path="./", verbose=False ):    score = 0    try:        subprocess.run( ["make", "-B"], cwd=path, check=True, )    except subprocess.CalledProcessError as e:        print ("Couldn't compile multiInput.")        return score    if test_multiInput(0,path,verbose):        score += 5        if test_multiInput(1,path,verbose):            score += 5            if test_multiInput(2,path,verbose):                score += 5                if test_multiInput(3,path,verbose):                    score+= 5                    if test_multiInput(4,path,verbose):                        score += 5                        if test_multiInput(5,path,verbose):                            score += 5                            for filenum in range(6,16):                                generate_test ( filenum, circuitInCount=8, gateInMax=8, gateCount=16, circuitOutCount=8, path=path )                                if test_multiInput(filenum,path,verbose):                                    score += 1                                else:                                    break    print ("Score on multiInput: {} out of 0. (extra credit)".format(score))    return scoreif __name__ == '__main__':    # generate_test_suite()    grade_multiInput(verbose=True)    exit()`

## Related Samples

Explore our collection of Python Assignments samples, which cover a range of topics including data structures, algorithms, functions, and key libraries such as NumPy and Pandas. These examples provide clear explanations and code snippets to help students excel in Python programming assignments and projects, enhancing their understanding and practical skills.