Two Plus Two Publishing LLC Two Plus Two Publishing LLC
 

Go Back   Two Plus Two Poker Forums > Other Topics > Programming

Notices

Programming Discussions about computer programming

Reply
 
Thread Tools Display Modes
Old 07-23-2012, 08:43 AM   #16
newbie
 
WeAreSamurai's Avatar
 
Join Date: Nov 2010
Posts: 19
Re: Python Project: Binary Adding Machine

I'm not really an expert on circuits, so I'm not really sure. Did you mean to say EX-NOR, because the gates in the picture are NAND gates, but I think you're assuming that they are EX_NOR. In which case I think the C and D outputs would follow an oscillating pattern, and then I guess when you turn on X, C and D would stabilize at whatever value they were at at the time. If I were programming it I guess I'd have it return a random value, 1 or 0.

That's my guess just looking at it, but I'm not really one to ask.

And if you have anything you want to post feel free!
WeAreSamurai is offline   Reply With Quote
Old 07-23-2012, 11:19 AM   #17
journeyman
 
Join Date: Sep 2004
Posts: 360
Re: Python Project: Binary Adding Machine

Thanks, the gates were indeed EX-NOR (I couldn't find a correct picture).

I will try to build an actual circuit by using 2 lists:
1) objects (logic gates, lights, buttons, ...)
2) objects (wires)

Every wire has an input/output which needs to be attached to an object from the first list. All objects from the first list need wires to be attached to their inputs/outputs. (output to input and input to output)
After this proces I turn the objects from the first list on (from top to bottom), they check input and adjust output.

When an 'action' object from the first list is used (switch, clock, ...): I would adjust the state of the wire attached to the output and iterate through the first list adjusting output-wires until a steady-state was reached.

I think I might have problems with these 'simultaneous events'. But even besides that it's maybe not a correct way to build this (not a good representation of reality, ...).
cyberfish is offline   Reply With Quote
Old 07-23-2012, 11:28 PM   #18
S.A.G.E. Master
 
daveT's Avatar
 
Join Date: Jun 2005
Location: Why didn't I use Clojure instead?
Posts: 16,829
Re: Python Project: Binary Adding Machine

I decided to try this in the Python way, but I'm not going to go past where OP is at, so all I have is a framework of primitives here, thus my paltry excuse is that it isn't done. Regardless, Feel free to poke holes in this:

(fwiw, I really hate the repetition of the gates, but I can't seem to ponder a better solution today.)

Code:
def objectState(x):
    return x

def reverse(x):
    if x == 0: return 1
    if x == 1: return 0
    
def logic(x, y):
    if x == y: return True
    else: return False





def andGate(inputA, inputB, output = 0):
    if logic(inputA, inputB) == True:
        output = inputA
    return output

def orGate(inputA, inputB, output = 1):
    if logic(inputA, inputB) == True:
        output = inputA
    return output

def norGate(inputA, inputB, output = 0):
    if logic(inputA, inputB) == True:
        output = reverse(inputA)
    return output

def nandGate(inputA, inputB, output = 1):
    if logic(inputA, inputB) == True:
        output = reverse(inputA)
    return output

def inverter(inputA, inputB = None):
    return reverse(inputA)





def gates(gateType, inputA, inputB = None): 
    return gateType(inputA, inputB)

def lightBulb(wire):
    if objectState(wire) == 1:
        print("Light is on!")
    else: print("Light is off!")
For connections, I'm going to create a function that creates a list of objects. I've written the prototype for that, which I'll show off at a later time.
daveT is offline   Reply With Quote
Old 07-25-2012, 07:30 PM   #19
Carpal \'Tunnel
 
clowntable's Avatar
 
Join Date: Jun 2006
Location: 39, 46, 56, 59, 191
Posts: 39,784
Re: Python Project: Binary Adding Machine

Just turbobrowsing (and I have picked up Code for reading on the train, read upto the relay chapter during the last couple of rides...seems like I'll really like the book). I guess I'd model a circuit as graphs with the nodes being gates and links being wires or smth like that. Might try hacking something up later

Conceptionally this seems extremly similar to the neural networks I coded during university. Each neuron having inputs/outputs stuff "propergating" through the net etc etc. so maybe if you're interested neural networks might be an interesting follow up project

Last edited by clowntable; 07-25-2012 at 07:35 PM.
clowntable is offline   Reply With Quote
Old 07-26-2012, 04:57 PM   #20
S.A.G.E. Master
 
daveT's Avatar
 
Join Date: Jun 2005
Location: Why didn't I use Clojure instead?
Posts: 16,829
Re: Python Project: Binary Adding Machine

Where is OP? I'm still waiting for the adders and stuff. I decided to work on this a little bit this morning and created the half adder, full adder and ripple adder. The ripple adder allows you the add n-bit characters. Right now, the ripple adder just takes strings because in Python land, 000100001 and [0001110001] are illegal, and if you do 0o0000100010 it will simply spit out a number, which isn't cool. Well, actually this feature makes debugging really easy.
daveT is offline   Reply With Quote
Old 07-26-2012, 10:23 PM   #21
newbie
 
WeAreSamurai's Avatar
 
Join Date: Nov 2010
Posts: 19
Re: Python Project: Binary Adding Machine

Hey I'm still here! I've actually finished everything up to the full adder and hoping to get around to posting them later today.

Quote:
Originally Posted by daveT View Post
I decided to try this in the Python way, but I'm not going to go past where OP is at, so all I have is a framework of primitives here, thus my paltry excuse is that it isn't done. Regardless, Feel free to poke holes in this:

(fwiw, I really hate the repetition of the gates, but I can't seem to ponder a better solution today.)

For connections, I'm going to create a function that creates a list of objects. I've written the prototype for that, which I'll show off at a later time.
I think it's really cool that you've decided to actually code this. I'm really curious how it'll turn out because with the lists and tuples I ran into a lot of trouble with referencing. I'm also interested in seeing a model where the pieces actually carry a charge variable, I think cyberfish was taking that approach too. Pretty early on I dropped that model for the current one that looks for complete circuits or incomplete circuits, and then turns every part in that circuit on or off respectively. I'm not sure which would have been better, but I'd be interested to see how certain problems were dealt with.

Quote:
Originally Posted by clowntable View Post
Just turbobrowsing (and I have picked up Code for reading on the train, read upto the relay chapter during the last couple of rides...seems like I'll really like the book). I guess I'd model a circuit as graphs with the nodes being gates and links being wires or smth like that. Might try hacking something up later

Conceptionally this seems extremly similar to the neural networks I coded during university. Each neuron having inputs/outputs stuff "propergating" through the net etc etc. so maybe if you're interested neural networks might be an interesting follow up project
That does sound really interesting! Glad you're enjoying the book.
WeAreSamurai is offline   Reply With Quote
Old 07-27-2012, 12:10 AM   #22
S.A.G.E. Master
 
daveT's Avatar
 
Join Date: Jun 2005
Location: Why didn't I use Clojure instead?
Posts: 16,829
Re: Python Project: Binary Adding Machine

Well, once you get yours posted, I'll post mine. Yeah, I can add in some probes to the program to show the wire- and object-states as they progress, but not today. Sort of burned out with the project I'm currently working on.

As for using lists: they'll be available to use for custom circuits and stuff like that but they aren't used in the primitives. They would be abstracted into a function, though of course, someone can use lists directly. I'll try to match the functionality of whatever you post after I see it and play around with it.

My program, at this point, only has the various gates, three adders, and a few helper functions. Still have to make the lightbulb, wires, and the connection function.
daveT is offline   Reply With Quote
Old 07-27-2012, 02:07 AM   #23
newbie
 
WeAreSamurai's Avatar
 
Join Date: Nov 2010
Posts: 19
Re: Python Project: Binary Adding Machine

Ok so here are the half adder and the full adder, and one more logic gate. But before that I'll explain what I'm trying to do with them.

If you don't know how binary numbers work, basically, in binary there's only 0's and 1's. There's no 2 - 9. Normally after 9, you've run out of unique numbers so you go to 10, essentially adding another digit and starting over with 0-9 except with a 1 in front (ie ten through nineteen). In binary you go 0, 1, and then you've run out of unique numbers so you add a new digit and start over. So you go to 10 which represents 2 in our normal decimal system. And from there you can count, 11 (3), 100 (4), 101 (5), 110 (6).

The advantage of using binary numbers is that you can use something like a switch or a light and when it's off or on, you can have that represent 0 or 1. And that's exactly what we're doing in this program. With the logic gates, we're taking in two inputs that we control with two switches, (switch on = 1, switch off = 0) and then returning a single output (light on = 1, light off = 0), who's result will depend on how the logic gates are wired. What we want is to wire them so that the inputs and resulting output will match what we would expect from adding two binary numbers.

For example, here's the simplest case adding two one digit numbers.
0+0=0 - switch1 off and switch2 off results in lightbulb off
1+0=1 - switch1 on and switch2 off results in lightbulb on
0+1=1 - switch1 off and switch2 on results in lightbulb on
1+1=10 - ?

The first three cases are straightforward, but what about 1+1. Well, each logic gate only has one output, so we want two logic gates, one for each digit of the result. So we have:
0+0=00
1+0=01
0+1=01
1+1=10

We want one gate which will output 0 (lightbulb off) in every case except when we have two inputs of 1 (both switches on). That would be the first digit. And then for the second digit we want the output 0 when both inputs are 0 or 1, and output 1 in the other cases. The first digit can be represented by the AND gate. The second digit is a little more complicated, it's represented by the XOR gate. I didn't have the XOR gate last time, but I've written the code and put it at the bottom of my module this time.

Here's what the XOR gate looks like:


So then the "half adder" is just two switches wired to an AND gate and XOR gate:


But it's called a half adder because it doesn't account for "carrying the one". Let's imagine we're adding two, two digit binary numbers.
11
+11

On the right side we just add two 1's and get 10. So we would write down the 0, but then "carry the 1". Now on the left side we're adding 1+1+1, where the last 1 is the carry-in. The full adder then will be able to account for the carry in. This is wired as follows:


So here's the module so far:
Code:
# parts: wire, switch, battery plus side (voltage), battery minus side (ground),
# lightbulb, electromagnet

circuits = set([])

class Parts(object):

    priority = 0

    def find_circuits(self):
        self.circuit_ins()
        self.circuit_outs()

    def circuit_ins(self):
        if str(self.wire_in) == "plus":
            circuits.add((Parts.priority, self.wire_in))
            return
        if str(self.wire_in) == "em":
            Parts.priority += 1
            self.wire_in.switch.find_circuits()
        if str(self.wire_in) == "switch" and self.wire_in.my_em:
            Parts.priority -= 1
            self.wire_in.my_em.find_circuits()
        self.wire_in.circuit_ins()
        Parts.priority = 0
        
    def circuit_outs(self):
        if str(self.wire_out) == "minus":
            return
        if str(self.wire_out) == "em":
            Parts.priority += 1
            self.wire_out.switch.find_circuits()
        if str(self.wire_out) == "switch" and self.wire_out.my_em:
            Parts.priority -= 1
            self.wire_out.my_em.find_circuits()
        self.wire_out.circuit_outs()
        Parts.priority = 0
                
    def on_off(self):
        for x in sorted(circuits):
            if x[1].check_switches() == "complete":
                x[1].circuit_on()
            elif x[1].check_switches() == "incomplete":
                x[1].circuit_off()
            
    def check_switches(self):
        if str(self.wire_out) == "switch" and self.wire_out.status == "open":
            return "incomplete"
        if str(self.wire_out) == "minus":
            return "complete"
        x = self.wire_out.check_switches()
        return x
        
    def circuit_on(self):
        self.activate()
        if str(self) in ("minus", "merge"):
            return
        self.wire_out.circuit_on()
            
    def circuit_off(self):
        self.deactivate()
        if str(self) in ("minus", "merge"):
            return
        self.wire_out.circuit_off()

    def activate(self):
        pass

    def deactivate(self):
        pass


class Wire(Parts):

    def connect(self, wire_out):
        self.wire_out = wire_out
        wire_out.connect_back(self)

    def connect_back(self, wire_in):
        self.wire_in = wire_in


class SplitWire(Wire):

    def __init__(self):
        self.wire_out1 = Wire()
        self.wire_out2 = Wire()
        self.wire_out1.wire_in = self
        self.wire_out2.wire_in = self

    def check_switches(self):
        if not "complete" in (self.wire_out1.check_switches(),
                                                      self.wire_out2.check_switches()):
            return "incomplete"
        return "complete"

    def circuit_on(self):
        self.wire_out1.circuit_on()
        self.wire_out2.circuit_on()

    def circuit_off(self):
        self.wire_out1.circuit_off()
        self.wire_out2.circuit_off()

    def circuit_outs(self):
        self.priority_old = Parts.priority
        self.wire_out1.circuit_outs()
        Parts.priority = self.priority_old
        self.wire_out2.circuit_outs()
        Parts.priority = self.priority_old
    
    def connect(self, wire_out1, wire_out2):
        self.wire_out1.connect(wire_out1)
        self.wire_out2 .connect(wire_out2)
        wire_out1.connect_back(self)
        wire_out2.connect_back(self)


class MergeWire(Wire):

    def __init__(self):
        self.input1 = Wire()
        self.input2 = Wire()
        self.input1.wire_out = self
        self.input2.wire_out = self
        self.wire_in1 = self.input1
        self.wire_in2 = self.input2
        self.charge = []
        
    def __str__(self):
        return "merge"

    def circuit_ins(self):
        self.priority_old = Parts.priority
        self.wire_in1.circuit_ins()
        Parts.priority = self.priority_old
        self.wire_in2.circuit_ins()
        Parts.priority = self.priority_old

    def activate(self):
        self.charge.append("on")
        if len(self.charge) > 1:
            if "on" in self.charge:
                self.wire_out.circuit_on()
            elif "on" not in self.charge:
                self.wire_out.circuit_off()
            del self.charge[:]
            
    def deactivate(self):
        self.charge.append("off")
        if len(self.charge) > 1:
            if "on" in self.charge:
                self.wire_out.circuit_on()
            elif "on" not in self.charge:
                self.wire_out.circuit_off()
            del self.charge[:]
            
        
class BattPlus(Wire):
        
    def __str__(self):
        return "plus"
    

class BattMinus(Wire):

    def __str__(self):
        return "minus"
    

class Electromagnet(Wire):

    def __init__(self, switch):
        self.switch = switch
        switch.my_em = self

    def __str__(self):
        return "em"
        
    def activate(self):
        if self.switch.default == "closed":
            self.switch.status = "open"
        elif self.switch.default == "open":
            self.switch.status = "closed"

    def deactivate(self):
        self.switch.status = self.switch.default


class Lightbulb(Wire):

    def __init__(self):
        self.status = "light off"
        
    def __str__(self):
        return "light"

    def activate(self):
        self.status = "light on!"

    def deactivate(self):
        self.status = "light off"
        
    def check(self):
        self.on_off()
        return self.status


class Switch(Wire):

    def __init__(self, default = "open"):
        self.default = default
        self.status = default
        self.my_em = None

    def  __str__(self):
        return "switch"

    def on(self):
        self.status = "closed"
        self.find_circuits()

    def off(self):
        self.status = "open"
        self.find_circuits()


#
# Relay and Inverter
#

class Relay(Wire):
    
    def __init__(self):
        # parts
        self.switch = Switch()
        self.input2 = self.switch
        self.em = Electromagnet(self.switch)
        self.input1 = self.em
        self.ground = BattMinus()
        self.voltage = BattPlus()
        
        #construction
        self.em.connect(self.ground)
        self.voltage.connect(self.switch)

    # fix connections
    def connect_back(self, wire_in):
            wire_in.wire_out = self.em
            self.em.wire_in = wire_in

    def connect(self, wire_out):
        self.switch.connect(wire_out)


class Inverter(Wire):
    
    def __init__(self):
        # parts
        self.switch = Switch("closed")
        self.input2 = self.switch
        self.em = Electromagnet(self.switch)
        self.input1 = self.em
        self.ground = BattMinus()
        self.voltage = BattPlus()
        
        #construction
        self.em.connect(self.ground)
        self.voltage.connect(self.switch)

    # fix connections
    def connect_back(self, wire_in):
            wire_in.wire_out = self.em
            self.em.wire_in = wire_in

    def connect(self, wire_out):
        self.switch.connect(wire_out)


#
# Logic Gates: AND, OR, NAND, NOR, XOR
#

class AndGate(Wire):

    def __init__(self):
        #parts
        self.relay1 = Relay()
        self.relay2 = Relay()
        self.input1 = self.relay1
        self.input2 = self.relay2

        #construction
        self.relay1.connect(self.relay2.input2)

    #fix connections
    def connect(self, wire_out):
        self.relay2.connect(wire_out)
        
    
class OrGate(Wire):
    
    def __init__(self):
        #parts
        self.relay1 = Relay()
        self.relay2 = Relay()
        self.merge = MergeWire()
        self.input1 = self.relay1
        self.input2 = self.relay2

        #construction
        self.relay1.connect(self.merge.input1)
        self.relay2.connect(self.merge.input2)

    #fix connections
    def connect(self, wire_out):
        self.merge.connect(wire_out)


class NandGate(Wire):
    
    def __init__(self):
        #parts
        self.invert1 = Inverter()
        self.invert2 = Inverter()
        self.merge = MergeWire()
        self.input1 = self.invert1
        self.input2 = self.invert2

        #construction
        self.invert1.connect(self.merge.input1)
        self.invert2.connect(self.merge.input2)

    #fix connections
    def connect(self, wire_out):
        self.merge.connect(wire_out)


class NorGate(Wire):

    def __init__(self):
        #parts
        self.invert1 = Inverter()
        self.invert2 = Inverter()
        self.input1 = self.invert1
        self.input2 = self.invert2

        #construction
        self.invert1.connect(self.invert2.input2)

    #fix connections
    def connect(self, wire_out):
        self.invert2.connect(wire_out)

                
class XorGate(Wire):

    def __init__(self):
        #parts
        self.split1 = SplitWire()
        self.split2 = SplitWire()
        self.or_gate = OrGate()
        self.nand_gate = NandGate()
        self.and_gate = AndGate()
        
        self.input1 = self.split1
        self.input2 = self.split2

        #construction
        self.split1.connect(self.or_gate.input1, self.nand_gate.input1)
        self.split2.connect(self.or_gate.input2, self.nand_gate.input2)
        self.or_gate.connect(self.and_gate.input1)
        self.nand_gate.connect(self.and_gate.input2)

    #fix connections
    def connect(self, wire_out):
        self.and_gate.connect(wire_out)


#
# Half Adder and Full Adder
#

class HalfAdder(Wire):

    def __init__(self):
        # parts
        self.split1 = SplitWire()
        self.split2 = SplitWire()
        self.xor_gate = XorGate()
        self.and_gate = AndGate()
        
        self.input1 = self.split1
        self.input2 = self.split2

        self.output1 = self.xor_gate
        self.output2 = self.and_gate

        # construction
        self.split1.connect(self.xor_gate.input1, self.and_gate.input1)
        self.split2.connect(self.xor_gate.input2, self.and_gate.input2)
        

class FullAdder(Wire):

    def __init__(self):
        # parts
        self.half_adder1 = HalfAdder()
        self.half_adder2 = HalfAdder()
        self.or_gate = OrGate()

        self.input1 = self.half_adder1.input1
        self.input2 = self.half_adder1.input2
        self.input3 = self.half_adder2.input1
        self.carry_in = self.input3

        self.output1 = self.half_adder2.output1
        self.sum_out = self.output1
        self.output2 = self.or_gate
        self.carry_out = self.output2

        # construction
        self.half_adder1.output1.connect(self.half_adder2.input2)
        self.half_adder1.output2.connect(self.or_gate.input2)
        self.half_adder2.output2.connect(self.or_gate.input1)
And here's the code a wrote up to test the half adder:
Code:
# half adder tester

from parts import *

# parts
v1 = BattPlus()
v2 = BattPlus()
s1 = Switch()
s2 = Switch()
light1 = Lightbulb()
light2 = Lightbulb()
g1 = BattMinus()
g2 = BattMinus()
half_adder = HalfAdder()

# construction
v1.connect(s1)
v2.connect(s2)
s1.connect(half_adder.input1)
s2.connect(half_adder.input2)
half_adder.output2.connect(light1)
half_adder.output1.connect(light2)
light1.connect(g1)
light2.connect(g2)

#operation
while 1:
    print "first switch: enter 1 to switch on, 0 to switch off"
    on_off1 = input("> ")
    if on_off1 == 1:
        s1.on()
    if on_off1 == 0:
        s1.off()
    print "second switch: enter 1 to switch on, 0 to switch off"
    on_off2 = input("> ")
    if on_off2 ==1:
        s2.on()
    if on_off2 == 0:
        s2.off()
    print light1.check(), light2.check()
    print ""
And the test for the full adder:
Code:
# full adder tester

from parts import *

# parts
v1 = BattPlus()
v2 = BattPlus()
v3 = BattPlus()
s1 = Switch()
s2 = Switch()
s3 = Switch()
light1 = Lightbulb()
light2 = Lightbulb()
g1 = BattMinus()
g2 = BattMinus()
full_adder = FullAdder()

# construction
v1.connect(s1)
v2.connect(s2)
v3.connect(s3)
s1.connect(full_adder.input1)
s2.connect(full_adder.input2)
s3.connect(full_adder.input3)
full_adder.output2.connect(light1)
full_adder.output1.connect(light2)
light1.connect(g1)
light2.connect(g2)

# operation
while 1:
    print "first switch: enter 1 to switch on, 0 to switch off"
    on_off1 = input("> ")
    if on_off1 == 1:
        s1.on()
    if on_off1 == 0:
        s1.off()
    print "second switch: enter 1 to switch on, 0 to switch off"
    on_off2 = input("> ")
    if on_off2 ==1:
        s2.on()
    if on_off2 == 0:
        s2.off()
    print "third switch: enter 1 to switch on, 0 to switch off"
    on_off3 = input("> ")
    if on_off3 ==1:
        s3.on()
    if on_off3 == 0:
        s3.off()
        
    print light1.check(), light2.check()
    print ""
At this point the adding machine is almost finished. The adding machine is basically just a bunch of full adders strung together, or what's called a ripple adder. Here's a picture of that:

All the adding machine really does is connect the switches (at the P's and Q's in the picture) and lightbulbs (at the S's in the picture).

I was hoping to be finished by this post, but I've decided to keep going and create a graphic interface for this program. It's my first time working with a graphics module and I'm pretty happy with the way it's turning out so far. I like the fact that using a GUI retains the feeling of using a machine more as opposed to using a program. I have a lot of it done already so it should be done before the weekend.
WeAreSamurai is offline   Reply With Quote
Old 07-27-2012, 05:28 PM   #24
S.A.G.E. Master
 
daveT's Avatar
 
Join Date: Jun 2005
Location: Why didn't I use Clojure instead?
Posts: 16,829
Re: Python Project: Binary Adding Machine

When it the light supposed to turn on? Or can you give me an explanation of what is happening here?

Code:
>>> 
first switch: enter 1 to switch on, 0 to switch off
> 1
second switch: enter 1 to switch on, 0 to switch off
> 1
light off light off

first switch: enter 1 to switch on, 0 to switch off
> 0
second switch: enter 1 to switch on, 0 to switch off
> 0
light off light off

first switch: enter 1 to switch on, 0 to switch off
> 1
second switch: enter 1 to switch on, 0 to switch off
> 0
light off light off

first switch: enter 1 to switch on, 0 to switch off
> 0
second switch: enter 1 to switch on, 0 to switch off
> 1
light off light off
Test the adder:

Code:
first switch: enter 1 to switch on, 0 to switch off
> 1
second switch: enter 1 to switch on, 0 to switch off
> 1
third switch: enter 1 to switch on, 0 to switch off
> 1
light off light off

first switch: enter 1 to switch on, 0 to switch off
> 0
second switch: enter 1 to switch on, 0 to switch off
> 0
third switch: enter 1 to switch on, 0 to switch off
> 0
light off light off

first switch: enter 1 to switch on, 0 to switch off
> 1
second switch: enter 1 to switch on, 0 to switch off
> 0
third switch: enter 1 to switch on, 0 to switch off
> 1
light off light off

first switch: enter 1 to switch on, 0 to switch off
> 0
second switch: enter 1 to switch on, 0 to switch off
> 1
third switch: enter 1 to switch on, 0 to switch off
> 0
light off light off
daveT is offline   Reply With Quote
Old 07-28-2012, 10:03 PM   #25
S.A.G.E. Master
 
daveT's Avatar
 
Join Date: Jun 2005
Location: Why didn't I use Clojure instead?
Posts: 16,829
Re: Python Project: Binary Adding Machine

Code:
def reverse(x):
    if x == 0: return 1
    if x == 1: return 0
    
def logic(x, y, z):
    if x == y: return x 
    else: return z



def andGate(inputA, inputB, output = 0):
    return logic(inputA, inputB, output)
    
def orGate(inputA, inputB, output = 1):
    return logic(inputA, inputB, output)
        
def norGate(inputA, inputB, output = 1):
        return reverse(logic(inputA, inputB, output))

def nandGate(inputA, inputB, output = 0):
        return reverse(logic(inputA, inputB, output))

def inverter(inputA, output = None):
    return reverse(inputA)




def halfAdder(wire1, wire2):
    h1 = andGate(wire1,wire2)
    return andGate(orGate(wire1,wire2), inverter(h1)), h1

def fullAdder(wire1, wire2, cin):
    h1 = halfAdder(wire2, cin)
    h2 = halfAdder(wire1, h1[0])
    cout = orGate(h1[1], h2[1])
    return h2[0], cout

def rippleAdder(num1, num2, sumWires = '', cin = 0):
    if len(num1) != len(num2):
        return print('your objects are not the same length\n', len(num1), len(num2))
    if len(num1) == 0:
        return sumWires, cin
    else:
        h1 = int(num1[0])
        h2 = int(num2[0])
        s, c = fullAdder(h1, h2, cin)
        sumWires+=str(s)
        return rippleAdder(num1[1:], num2[1:], sumWires, c)

def lightbulb(wire):
    for i in wire:
        if i == 1: print('Light On!')
        else: print('Light Off!')




def start():
    gateDict = {1:andGate, 2:orGate, 3:nandGate, 4:norGate, 5:inverter}
    adderDict = {1:halfAdder, 2:fullAdder, 3:rippleAdder}
    chooseType = int(input('Press 1 for Gate, Press 2 for Adder :'))
    if chooseType == 1:
        chooseGate = int(input('''
                           Press 1 for And Gate
                           Press 2 for Or Gate 
                           Press 3 for Nand Gate 
                           Press 4 for Nor Gate 
                           Press 5 for Inverter
                           >>>'''))
        if chooseGate == 1 or chooseGate == 2 or chooseGate == 3 or chooseGate == 4: 
            onOff1 = int(input('press 0 to turn off wire1, press 1 to turn on wire1'))
            onOff2 = int(input('press 0 to turn off wire2, press 1 to turn on wire2'))
            lightbulb(gateDict[chooseGate](onOff1, onOff2))
        elif chooseGate == 5:
            onOff1 = int(input('press 0 to turn off wire1, press 1 to turn on wire1'))
            lightbulb(gateDict[chooseGate](onOff1))   
    if chooseType == 2:
        chooseAdder = int(input('''
                                Press 1 for Half Adder 
                                Press 2 for Full Adder 
                                Press 3 for Ripple Adder
                                >>>'''))
        if chooseAdder == 1:
            onOff1 = int(input('press 0 to turn off wire1, press 1 to turn on wire1'))
            onOff2 = int(input('press 0 to turn off wire2, press 1 to turn on wire2'))
            lightbulb(adderDict[chooseAdder](onOff1, onOff2))
        if chooseAdder == 2:
            onOff1 = int(input('press 0 to turn off wire1, press 1 to turn on wire1'))
            onOff2 = int(input('press 0 to turn off wire2, press 1 to turn on wire2'))
            onOff3 = int(input('press 0 to turn off carrier, press 1 to turn on carrier'))
            lightbulb(adderDict[chooseAdder](onOff1, onOff2, onOff3))
        if chooseAdder == 3:
           pass    


                           

start()
This basically gives you the light on / light off feature, but only on the gates and the half-adder and full-adder.

I think it's interesting that WeAreSamurai and I have very different approaches to the problem set. I don't know which is better or which is worse. As I said, I already did something like this, and that was from a book that is hard-core functional programming. Most of that translates okay to Python, but there's some things to work around.

I know, the start() function could use some improvement, but I think that you can see at least how I plan to tie things together.

The Ripple Adder works just as expected. I used this simulation to test against. The ripple adder in the simulation does only 8-bit. If you do test mine against his, remember that his reads from right to left and mine reads from left to right. My Ripple Adder is supposed to work with n-bits, so if you really feel inspired to run 128 bits, have at it, but I can't guarantee the results.

To use the Ripple Adder, comment out the start() at the bottom, run the program and go to your command prompt:

Code:
>>> rippleAdder('0011', '1010')
('1000', 1)
>>> rippleAdder('0011', '1010', cin = 1)
('0100', 1)
>>>
The carry-in (here called cin) defaults to zero. Notice that you have to specify cin = 1 to turn on the carry. If you attempt other ways, everything sort of bugs.

So, aside from the ripple adder, I think I haven't went past WeAreSamurai.
daveT is offline   Reply With Quote
Old 08-06-2012, 10:26 PM   #26
S.A.G.E. Master
 
daveT's Avatar
 
Join Date: Jun 2005
Location: Why didn't I use Clojure instead?
Posts: 16,829
Re: Python Project: Binary Adding Machine

*bump* Anyone making progress?
daveT is offline   Reply With Quote
Old 08-07-2012, 08:36 AM   #27
journeyman
 
Join Date: Sep 2004
Posts: 360
Re: Python Project: Binary Adding Machine

I'll finish my project in a few weeks (not enough time atm) and if someone is interested I could provide a github-link to source.
Atm I coded what I described in my prev. post (I found a better way to update circuit-state).
To do: add javadoc, gui, handle exceptions, check for loops, ...
And last but not least create the binary adding machine, but it should be possible to simulate any kind of digital circuit.
cyberfish is offline   Reply With Quote
Old 08-21-2012, 08:09 AM   #28
journeyman
 
Join Date: Sep 2004
Posts: 360
Re: Python Project: Binary Adding Machine

I'll give the github-link to my java-source files:
https://github.com/L8Fish/Circuits

This is not finished at all, the code in the initial commits illustrates how I approached the problem. I coded it in a short amount of time.
I made the commits also to experiment with git (which is new to me).

Now I plan to pick it up again and tune/expand the code until it becomes a decent project including javadoc, gui, ... .

I would appreciate any comments.
cyberfish is offline   Reply With Quote
Old 08-22-2012, 01:25 AM   #29
S.A.G.E. Master
 
daveT's Avatar
 
Join Date: Jun 2005
Location: Why didn't I use Clojure instead?
Posts: 16,829
Re: Python Project: Binary Adding Machine

Wow. I just downloaded and stared at the java code and it all looks Herculean, thus I am afraid to ask how I can run it...

I mean, I know how to run java code, but I don't know what file to start with.

Nice work. I feel really lazy after looking at it. Hopefully someone here can review the work and give you some suggestions. I don't know any Java, so I have nothing to say but nice work.
daveT is offline   Reply With Quote
Old 08-22-2012, 05:04 AM   #30
journeyman
 
Join Date: Sep 2004
Posts: 360
Re: Python Project: Binary Adding Machine

That's the reason why I need to do more of these projects:
Keep it well structured, ... and documented (not just make it work). I'm not satisfied with some implementations and javadoc has to be added.

But some quick info:
Component (interface)
Element (abstract class implements Component)
Wire (class implements Component)
Input, Logic, Output (abstract class extends Element)

InputAction, OutputAction (interface)

AndGate, OrGate, NotGate (class extends Logic)
Battery (class extends Input)
Light (class extends Output implements OutputAction)
Switch (class extends Logic implements InputAction)

Circuit

TestCircuit (method main)

Code:
the example:
batt0 --- switch0 --- not0 ---
                                            
                                             and0 --- light0                         
batt1 --- switch1 ---                 
                                or0 ---
batt2 --- switch2 ---

test.makeAction(pos,act);//uses the switches
//pos = 3, 4 or 5 
//act = 0 or 1 
//instead of 3, 4 or 5 I should use the reference to the correct InputAction-object
//instead of 0 or 1 I should use a final variable

Last edited by cyberfish; 08-22-2012 at 05:23 AM.
cyberfish is offline   Reply With Quote

Reply
      

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off



All times are GMT -4. The time now is 06:50 PM.


Powered by vBulletin®
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.6.0 ©2011, Crawlability, Inc.
Copyright © 2008-2010, Two Plus Two Interactive