用Python写了一遍约束器

看了SICP第三章的约束器的例子,用Scheme实现了一遍,现在用Python以OO的方式再实现了一遍:

9C=5(F-32)

感觉上因为命令式用的比较多,还是OO方式比FP好理解。

class adder(object):
    def __init__(self, a1, a2, s):
        self.a1 = a1.connect(self)
        self.a2 = a2.connect(self)
        self.s = s.connect(self)

    def process_new_value(self):
        if self.a1.has_value() and self.a2.has_value():
            self.s.set_value(self.a1.value() + self.a2.value(), self)
        elif self.a1.has_value() and self.s.has_value():
            self.a2.set_value(self.s.value() - self.a1.value(), self)
        elif self.a2.has_value() and self.s.has_value():
            self.a1.set_value(self.s.value() - self.a2.value(), self)

    def process_forget_value(self):
        self.a1.forget_value(self)
        self.a2.forget_value(self)
        self.s.forget_value(self)
        self.process_new_value()

class multiplier(object):
    def __init__(self, a1, a2, p):
        self.a1 = a1.connect(self)
        self.a2 = a2.connect(self)
        self.p = p.connect(self)

    def process_new_value(self):
        if (self.a1.has_value() and self.a1.value() == 0) or (self.a2.has_value() and self.a2.value() == 0):
           self.p.set_value(0, self)

        if self.a1.has_value() and self.a2.has_value():
            self.p.set_value(self.a1.value() * self.a2.value(), self)
        elif self.a1.has_value() and self.p.has_value():
            self.a2.set_value(self.p.value() / self.a1.value(), self)
        elif self.a2.has_value() and self.p.has_value():
            self.a1.set_value(self.p.value() / self.a2.value(), self)

    def process_forget_value(self):
        self.a1.forget_value(self)
        self.a2.forget_value(self)
        self.p.forget_value(self)
        self.process_new_value()

class constant(object):
    def __init__(self, v, connector):
        connector.connect(self)
        connector.set_value(v, self)

    def process_new_value(self): pass
    def process_forget_value(self): pass

class connector(object):
    def __init__(self):
        self.myValue = None
        self.lastSetter = None
        self.constraints = set()

    def connect(self, constraint):
        self.constraints.add(constraint)
        return self

    def has_value(self):
        return self.myValue != None

    def value(self):
        return self.myValue

    def set_value(self, v, setter):
        if self.myValue is None:
            self.myValue, self.lastSetter = v, setter
            map(lambda x: x.process_new_value(),
                [each for each in self.constraints if each != setter])
        elif self.myValue != v:
            raise Exception, "Input confilicat!"

    def forget_value(self, cleaner):
        if self.lastSetter == cleaner:
            self.lastSetter = self.myValue = None
            map(lambda x: x.process_forget_value(), 
                [each for each in self.constraints if each != cleaner])

class probe(object):
    def __init__(self, name, connector):
        self.name = name
        self.connector = connector
        connector.connect(self)

    def output(self, value):
        if value is not None:
            print "Probe : %s = %d" % (self.name, value)
        else:
            print "Probe : %s = ?" % self.name

    def process_new_value(self):
        self.output(self.connector.value())

    def process_forget_value(self):
        self.output(None)

def celsius_fahreneit_converter(c, f):
    u, v, w, x, y = connector(), connector(), connector(), connector(), connector()
    multiplier(c, w, u)
    multiplier(v, x, u)
    adder(v, y, f)
    constant(9, w)
    constant(5, x)
    constant(32, y)

def main():
    c, f = connector(), connector()
    celsius_fahreneit_converter(c, f)
    probe("Celsius temp", c)
    probe("Fahrenheit temp", f)
    c.set_value(25, 'user')
    c.forget_value('user')
    f.set_value(212, 'user')

if __name__ == '__main__':
    main()


你可能感兴趣的:(python)