Logic Gates Circuit Simulation Workshop in Python
2021-03-01 19:26
标签:help exit creat put unit under npoi open alc Logic Gates circuit is the foundamental structure that build up the calculation and processing of a computer. It had been believed that with proper arrangement of logic gates, any computer could be built with an increase in complexity. This article would try to demonstrate how a logic circuit workshop could be implemented using Python. 1, Introduction Before we begin, we need to understand the components of a logic gate circuit The input button, which is where the power enters the circuit. The output button, where the power should be released from the circuit. The NOT gate, which converts 1 into 0, and 0 into 1. The AND gate, which would only allow current to flow through when both attachments are powered on. The OR gate, which would allow current to flow through as long as one of the gates are powered on. 2, Method In order to complete such task, tkinter was applied for drawing. Object of the three gates were first claimed, and then drawn on canvas. A class "gate" was first applied in order to control all applications on gates. After that, classes correcponding to different gates are declared and inherit the class of Gate. After that, by importing tkinter, the drawing functions would be declared. Given the static codes are implemented, the interface control codes could take advantage of them. When application functions are set, there could be functions that deal with the save/delete, which are loading functions. 1 class Gate(object):
2 #initialization
3 def __init__(self):
4 self.inputGates=[]
5 self.outputGates=[]
6 self.inputVals=None
7 self.inputValues = []
8 self.outputValue=None
9 self.maxInputGates=1
10 self.transform()
11 #create the list of inputValues
12 def transform(self):
13 if(self.inputVals == None):
14 return []
15 self.inputValues = []
16 for (key,val) in self.inputVals.items():
17 if((key,val) in self.inputValues):
18 continue
19 self.inputValues += [(key,val)]
20
21 pass
22 #connect two gates
23 def connectTo(self,gate):
24 if(len(gate.inputGates) gate.maxInputGates):
25 if gate not in self.outputGates:
26 self.outputGates.append(gate)
27 if self not in gate.inputGates:
28 gate.inputGates.append(self)
29 if gate.inputVals == None: gate.inputVals = dict()
30 gate.inputVals[self] = self.outputValue
31 if type(self) == Output:
32 pass
33 self.transform()
34 #use input to decide output
35 def inputToOutput(self):
36 if self.inputVals!=None:
37 self.outputValue=False
38 elif self.inputVals==None:
39 self.outputValue=None
40 return
41 if type(self) == Or: self.orGate()
42 elif type(self) == And: self.andGate()
43 elif type(self) == Not:
44 for key in self.inputVals:
45 self.outputValue = not self.inputVals[key]
46 elif type(self) == Output or type(self) == Input:
47 for key in self.inputVals:
48 self.outputValue = self.inputVals[key]
49 self.transform()
50 return
51 #Or type helper function
52 def orGate(self):
53 if len(self.inputVals)==2:
54 for key in self.inputVals:
55 if self.inputVals[key]==True:
56 self.outputValue=True
57 break
58 #None type is more priviledged than all types
59 for key in self.inputVals:
60 if self.inputVals[key] == None:
61 self.outputValue = None
62 return
63 else:
64 self.outputValue=None
65 self.transform()
66 #And type helper function
67 def andGate(self):
68 if len(self.inputVals)==2:
69 for key in self.inputVals:
70 if self.inputVals[key]==True: self.outputValue=True
71 else:
72 self.outputValue=False
73 break
74 for key in self.inputVals:
75 if self.inputVals[key] == None:
76 self.outputValue = None
77 return
78 else: self.outputValue=None
79 self.transform()
80 #set the input values
81 def setInputValue(self,gate,TorF):
82 try:
83 if self.inputVals==None:
84 self.inputVals=dict()
85 self.inputVals[gate]=TorF
86 self.inputToOutput()#generate its output
87 for index in range(len(self.outputGates)):
88 self.outputGates[index].setInputValue(self,self.outputValue)
89
90 self.transform()
91 except: return
92 #return inputgates
93 def getInputGates(self):
94 self.transform()
95 return self.inputGates
96 #return maximum numbers of inputgates
97 def getMaxInputGates(self):
98 self.transform()
99 return self.maxInputGates
100 #return outputgates
101 def getOutputGates(self):
102 self.transform()
103 return self.outputGates
1 class Input(Gate):
2 #initialization
3 def __init__(self):
4 self.inputGates=[]
5 self.outputGates=[]
6 self.inputVals=None
7 self.outputValue=None
8 self.inputValues = []
9 self.maxInputGates=0
10 self.transform()
11
12 class Output(Gate):
13 #all covered in Gate class
14 pass
15
16 class And(Gate):
17 #initialization
18 def __init__(self):
19 self.inputGates=[]
20 self.outputGates=[]
21 self.inputVals=None
22 self.outputValue=None
23 self.inputValues = []
24 self.maxInputGates=2
25 self.transform()
26
27 class Or(Gate):
28 #initialization
29 def __init__(self):
30 self.inputGates=[]
31 self.outputGates=[]
32 self.inputVals=None
33 self.outputValue=None
34 self.inputValues = []
35 self.maxInputGates=2
36 self.transform()
37
38 class Not(Gate):
39 #initialization
40 def __init__(self):
41 self.inputGates=[]
42 self.outputGates=[]
43 self.inputVals=None
44 self.outputValue=None
45 self.inputValues = []
46 self.maxInputGates=1
47 self.transform()
1 from tkinter import *
2 #initialization
3 def init(data):
4 data.buttonDict=dict()
5 data.button=None
6 data.r=5 #r for radius, simplified
7 data.unit=10
8 data.input=0
9 data.errorBound=10
10 data.threadResidue=6
11 data.inpointList=[]
12 data.outpointList=[]
13 data.lineList=[]
14 data.connectLine=[]
15 data.inputButtons=[]
16 data.power=False
17 data.save=False
18 data.path="circuit.txt"
19 data.contents=""
20 data.read=""
21 data.location=[]
22 data.gate=[]
23 #draw the Gate
24 def drawGate(canvas,data):#draw gates based on their names
25 d,r,l=data.unit, data.r, data.threadResidue
26 for key in data.buttonDict:
27 for i in range(len(data.buttonDict[key])):
28 x=int(data.buttonDict[key][i][0])
29 y=int(data.buttonDict[key][i][1])
30 if key=="input":
31 canvas.create_oval(x-r,y-r,x+r,y+r,fill="black",outline="red")
32 canvas.create_line(x+r,y,x+r+l,y,fill="red")
33 elif key=="output":
34 canvas.create_oval(x-r,y-r,x+r,y+r,fill="black",outline="green")
35 canvas.create_line(x-r-l,y,x-r,y,fill="green")
36 elif key=="and":
37 canvas.create_rectangle(x-d,y-d,x+d,y+d,fill="white")
38 canvas.create_oval(x,y-d,x+2*d,y+d,fill="white")
39 canvas.create_rectangle(x-d+1,y-d+1,x+d-1,y+d-1,fill="white",
40 outline="white")
41 canvas.create_line(x-d-l,y-d+r,x-d,y-d+r, fill="green")
42 canvas.create_line(x-d-l,y+d-r,x-d,y+d-r, fill="green")
43 canvas.create_line(x+2*d,y,x+2*d+l,y,fill="red")
44 #draw the other gate
45 def drawGateAdd(canvas,data):
46 d,r,l=data.unit, data.r, data.threadResidue
47 for key in data.buttonDict:
48 for i in range(len(data.buttonDict[key])):
49 x=int(data.buttonDict[key][i][0])
50 y=int(data.buttonDict[key][i][1])
51 if key=="or":
52 canvas.create_polygon(x-d-r,y-d,x-d-r+l/2,y-d+l,x-d-r+l/2,
53 y+d-l,x-d-r,y+d,x,y+d, x+d+r,y,x,y-d,fill="white",outline="black")
54 canvas.create_line(x-d-r-l/2,y-d+l,x-d-r+l/2,y-d+l,
55 fill="green")
56 canvas.create_line(x-d-r-l/2,y+d-l,x-d-r+l/2,y+d-l,
57 fill="green")
58 canvas.create_line(x+d+r,y,x+d+r+l,y, fill="red")
59 elif key=="not":
60 canvas.create_line(x-l-d,y,x+d+2*r,y)
61 canvas.create_polygon(x-d,y-d/2,x-d,y+d/2,x+d,y,fill="white",
62 outline="black")
63 canvas.create_oval(x+d,y-2,x+d+r-1,y+2,fill="white",
64 outline="black")
65
66 #draw the power input session
67 def drawPowerInput(canvas,data):
68 #change the color of the input button when it has power
69 for index in range(len(data.inputButtons)):
70 if data.inputButtons[index][2].outputValue==True:
71 x=int(data.inputButtons[index][0])
72 y=int(data.inputButtons[index][1])
73 r=data.r
74 canvas.create_oval(x-r,y-r,x+r,y+r,fill="red",width=0)
75
76 #draw the power lines
77 def drawPowerLine(canvas,data):
78 for index in range(len(data.lineList)):
79 xL=int(data.lineList[index][0][0])
80 yL=int(data.lineList[index][0][1])
81 xR=int(data.lineList[index][1][0])
82 yR=int(data.lineList[index][1][1])
83 if data.lineList[index][0][2].outputValue==True:
84 canvas.create_line(xL,yL,xR,yR,fill="red")
85 else:
86 canvas.create_line(xL,yL,xR,yR,fill="black")
87
88
89 #draw top buttons and left buttons (And)
90 def drawButtonAnd(canvas,data):
91 r,l=data.r,data.threadResidue
92 a,b,c,d,e=50,100,200,data.unit,data.r
93 for index in range(1,r+1):
94 canvas.create_rectangle(index*b,0,(index+1)*b,b,fill="white")
95 drawSave(canvas,data)
96 if data.power==True:
97 canvas.create_rectangle(2*c+e,e,2*c+b-e,b-e,outline="gray",width=d)
98 canvas.create_text(a+b,a,text="Save",font="Harrington 18")
99 canvas.create_text(a+c,a,text="Load",font="Harrington 18")
100 canvas.create_text(a+b+c,a,text="Clear",font="Harrington 18")
101 canvas.create_text(a+2*c,a,text="Power",font="Harrington 18")
102 canvas.create_text(a+2*c+b,a-d,text="Tianyuan Du",font="Harrington 12 bold")
103 canvas.create_text(a+2*c+b,a+d,text="tianyuad",font="Harrington 12")
104
105 #draw left button (Or)
106 def drawButtonOr(canvas,data):
107 r,l=data.r,data.threadResidue
108 a,b,c,d=50,100,200,data.unit
109 canvas.create_rectangle(b+l,b+l,2*c+2*b,2*c+2*b,fill="wheat",outline="blue")
110 canvas.create_line(b,b,b,2*b+2*c)
111 canvas.create_line(0,b,b,b)
112 canvas.create_oval(a-r,a+b-r,a+r,a+b+r,fill="black",outline="red")
113 canvas.create_line(a+r,a+b,a+r+l,a+b,fill="red",width=2)
114 canvas.create_text(a,a+b+2*d,text="input", font="Time 12 bold")
115 canvas.create_line(0,c,b,c)
116 canvas.create_oval(a-r,a+c-r,a+r,a+c+r,fill="black", outline="green")
117 canvas.create_line(a-r-l,a+c,a-r,a+c,fill="green",width=2)
118 canvas.create_text(a,a+c+2*d,text="output", font="Time 12 bold")
119 canvas.create_line(0,b+c,b,b+c)
120 canvas.create_line(a-l-d,a+b+c,a+d+2*r,a+b+c)
121 canvas.create_polygon(a-d,a+b+c-d/2,a-d,a+b+c+d/2,a+d,a+b+c,fill="white",
122 outline="black")
123 canvas.create_oval(a+d,a+b+c-2,a+d+4,a+b+c+2,fill="white", outline="black")
124 canvas.create_text(a,a+b+c+2*d,text="not", font="Time 12 bold")
125 canvas.create_line(0,2*c,b,2*c)
126
127 #draw left button (Not)
128 def drawButtonNot(canvas,data):
129 r,l=data.r,data.threadResidue
130 a,b,c,d=50,100,200,data.unit
131 canvas.create_rectangle(a-d,a+2*c-d,a+d,a+2*c+d, fill="white")
132 canvas.create_oval(a,a+2*c-d,a+2*d,a+2*c+d,fill="white")
133 canvas.create_rectangle(a-d+1,a+2*c-d+1,a+d-1,a+2*c+d-1, fill="white",
134 outline="white")
135 canvas.create_line(a-d-l,a+2*c-d+r,a-d,a+2*c-d+r,fill="green")
136 canvas.create_line(a-d-l,a+2*c+d-r,a-d,a+2*c+d-r,fill="green")
137 canvas.create_line(a+2*d,a+2*c,a+2*d+l,a+2*c,fill="red")
138 canvas.create_text(a,a+2*c+2*d,text="and", font="Time 12 bold")
139 canvas.create_line(0,2*c+b,b,2*c+b)
140 canvas.create_polygon(a-d-r,a+b+2*c-d,a-d-r+l/2,a+b+2*c-d+l,a-d-r+l/2,
141 a+b+2*c+d-l,a-d-r,a+b+2*c+d,a,a+b+2*c+d,a+d+r,a+b+2*c,a,a+b+2*c-d,
142 fill="white",outline="black")
143 canvas.create_line(a-d-r-l/2,a+b+2*c-d+l,a-d-r+l/2,a+b+2*c-d+l,fill="green")
144 canvas.create_line(a-d-r-l/2,a+b+2*c+d-l,a-d-r+l/2,a+b+2*c+d-l,fill="green")
145 canvas.create_line(a+d+r,a+b+2*c,a+d+r+l,a+b+2*c, fill="red")
146 canvas.create_text(a,a+b+2*c+2*d,text="or", font="Time 12 bold")
1 #draw phenomenon when buttons are pressed
2 def drawButtonPressed(canvas,data):
3 r,l=data.r,data.threadResidue
4 a,b,c,d=50,100,200,data.unit
5 if data.button=="input":canvas.create_rectangle(d/2,b+d/2,b-d/2,c-d/2,
6 fill="white",outline="gray",width=d)
7 elif data.button=="output": canvas.create_rectangle(d/2,c+d/2,b-d/2,b+c-d/2,
8 fill="white",outline="gray",width=d)
9 elif data.button=="not": canvas.create_rectangle(d/2,b+c+d/2,b-d/2,2*c-d/2,
10 fill="white",outline="gray",width=d)
11 elif data.button=="and": canvas.create_rectangle(d/2,2*c+d/2,b-d/2,2*c+b-d/2
12 ,fill="white",outline="gray",width=d)
13 elif data.button=="or": canvas.create_rectangle(d/2,2*c+b+d/2,b-d/2,
14 2*c+2*b-d/2,fill="white",outline="gray",width=d)
15
16 #draw if press Save
17 def drawSave(canvas,data):
18 a,b,c,d=50,100,200,data.unit
19 if data.save==True:
20 canvas.create_rectangle(b+d/2,d/2,c-d/2,b-d/2,fill="white",
21 outline="gray",width=d)
22
23 #helper function of save pressed
24 def drawSaveAdd(canvas,data):
25 if data.save==True:
26 a,b,c=50,100,200
27 canvas.create_text(a+b+c,a+b+c,text="Saved!!", font="Time 40 bold")
28
29 #location of buttons
30 def buttonPoint(data,x,y):
31 #set r,l,d to calculate their position in a small area
32 r,l,d=data.r,data.threadResidue,data.unit
33 #append four elements in the list
34 if data.button=="input":
35 input1=Input()
36 data.outpointList.append([x+r+l,y,input1,"input"])
37 data.inputButtons.append([x,y,input1,"input"])
38 elif data.button=="output":
39 data.inpointList.append([x-r-l,y,Output(),"output"])
40 elif data.button=="and":
41 and1=And()
42 data.inpointList.append([x-d-l,y-d+r,and1,"and"])
43 data.inpointList.append([x-d-l,y+d-r,and1,"and"])
44 data.outpointList.append([x+2*d+l,y,and1,"and"])
45 else: buttonPointAdd(data,x,y)
46 #other buttons stored
47 def buttonPointAdd(data,x,y):
48 r,l,d=data.r,data.threadResidue,data.unit
49 if data.button=="or":
50 or1=Or()
51 data.inpointList.append([x-d-r-l/2,y-d+l,or1,"or"])
52 data.inpointList.append([x-d-r-l/2,y+d-l,or1,"or"])
53 data.outpointList.append([x+d+r+l,y,or1,"or"])
54 elif data.button=="not":
55 not1=Not()
56 data.inpointList.append([x-l-d,y,not1,"not"])
57 data.outpointList.append([x+d+2*r,y,not1,"not"])
58 #helper function gets distance
59 def distance(a,b):
60 return ((a[0]-b[0])**2+(a[1]-b[1])**2)**(0.5)
61
62 #mouse pressed to select gates
63 def mousePressedLeftButton(event,data):
64 a,b,c,d=50,100,200,data.unit
65 if event.y >b and event.yc:
66 data.button = "input"
67 elif event.y> c and event.yc:
68 data.button = "output"
69 elif event.y>b+c and event.y c:
70 data.button = "not"
71 elif event.y>2*c and event.yb:
72 data.button="and"
73 elif event.y>2*c+b and event.yb:
74 data.button="or"
75
76 #mouse pressed to set gates
77 def mousePressedSetGates(event,data):
78 if data.button in data.buttonDict:
79 data.buttonDict[data.button].append((event.x, event.y))
80 else:
81 data.buttonDict[data.button]=[(event.x,event.y)]
82 buttonPoint(data,event.x,event.y)
83 data.button=None
84
85 #line connection
86 def connectLine(event,data):
87 a,b,c,d=50,100,200,data.unit
88 minDistance=b*data.unit
89 if data.connectLine==[]:
90 for point in data.outpointList:
91 if distance([(point[0]),(point[1])],[event.x,event.y])minDistance:
92 minDistance=distance([(point[0]),(point[1])],[event.x,event.y])
93 minPoint=point
94 if minDistancedata.errorBound: data.connectLine.append(minPoint)
95 else:
96 for point in data.inpointList:
97 if distance(point,[event.x,event.y])minDistance:
98 minDistance=distance(point,[event.x,event.y])
99 minPoint=point
100 if minDistancedata.errorBound:
101 data.connectLine.append(minPoint)
102 data.inpointList.remove(minPoint)
103 data.lineList.append(data.connectLine)
104 data.connectLine[0][2].connectTo(data.connectLine[1][2])
105 data.connectLine=[]
106
107 #switch the power state as user click power.
108 def powerSwitch(event,data):
109 if data.power==False:#not gate works
110 for index in range(len(data.inputButtons)):
111 data.inputButtons[index][2].setInputValue(None,False)
112 else:
113 for index in range(len(data.inpointList)):
114 data.inpointList[index][2].inputVals=None
115 data.inpointList[index][2].outputValue=None
116 for index in range(len(data.outpointList)):
117 data.outpointList[index][2].inputVals=None
118 data.outpointList[index][2].outputValue=None
119 data.power= not data.power #switch the power state
120
121 #control when power is get
122 def powerGet(event,data):
123 b=100
124 minDistance=b*data.unit
125 for index in range(len(data.inputButtons)):
126 xi,yi=int(data.inputButtons[index][0]),int(data.inputButtons[index][1])
127 if distance([xi,yi],[event.x,event.y])minDistance:
128 minDistance=distance([xi,yi],[event.x,event.y])
129 minPoint=data.inputButtons[index]
130 if minDistancedata.errorBound:
131 minPoint[2].setInputValue(None,not minPoint[2].outputValue)
132 #control when mouse is pressed
133 def mousePressed(event, data):
134 a,b,c,d=50,100,200,data.unit
135 if event.x and data.power==False: mousePressedLeftButton(event,data)
136 elif event.x>b and event.xand event.y>b and data.power==False:
137 if data.button!=None: mousePressedSetGates(event,data)
138 else:connectLine(event,data)
139 elif event.x>b+c and event.xand event.yb:
140 clear(data)
141 elif event.x>2*c and event.xand event.yb:
142 powerSwitch(event,data)
143 else:
144 if data.power==True:
145 #when power is on
146 if event.x>b and event.xand event.y>b:
147 powerGet(event,data)
148 elif event.x>c and event.xand event.yb:
149 init(data)
150 load(data)
151 elif event.x>b and event.x
1 #clear out the data
2 def clear(data):
3 init(data)
4
5 #load the files
6 def readFile(data):
7 with open(data.path, "rt") as f:
8 data.read=f.read()
9 return
10 #load data
11 def load(data):
12 readFile(data)
13 loadinput(data)
14 loadInpoint(data)
15 loadOutpointList(data)
16 loadlineList(data)
17 loaddict(data)
18 #helper function gets the gate
19 def getGate(name):
20 gate = None
21 if(name == "input"):
22 gate = Input()
23 elif(name == "output"):
24 gate = Output()
25 elif(name == "and"):
26 gate = And()
27 elif(name == "or"):
28 gate = Or()
29 elif(name == "not"):
30 gate = Not()#create a new object in the list data.gate
31 return gate
32 #load input
33 def loadinput(data):
34 length=len("#below are inputButtons\n")
35 startPoint=data.read.find("#below are inputButtons\n")+length
36 endPoint=data.read.find("#below are inpointList")
37 inputStr=data.read[startPoint:endPoint]
38 for lines in inputStr.splitlines():
39 inputs=lines.split(",")
40 inputs[0],inputs[1]=int(inputs[0]),int(inputs[1])
41 if inputs[2] not in data.location:
42 data.location.append(inputs[2])
43 k=(inputs[-1][1:])#inputs[-1][1:] is actually the "input"
44 gate = getGate(k)
45 data.gate.append(gate)
46 index=data.location.index(inputs[2])
47 inputs[2]=data.gate[index]
48 data.inputButtons.append(inputs)#recover the inputButton list
49 #below are similar to the first function
50 def loadInpoint(data):
51 length=len("#below are inpointList\n")
52 startPoint=data.read.find("#below are inpointList\n")+length
53
文章标题:Logic Gates Circuit Simulation Workshop in Python
文章链接:http://soscw.com/index.php/essay/58686.html