2014年7月16日水曜日

開発環境

JavaScript - 個数*単価 = 代金, 代金 = 個数*単価 ( @AXION_CAVOK , @dankogai )

クラスベースのオブジェクト指向(今回は python 3.4 )と、どちらが書きやすいか、比較のために書いてみた。(今回はかけ算じゃなくて足し算で。)

コード(BBEdit, Emacs)

constraint_system.py

#!/usr/bin/env python3
#-*- coding: utf-8 -*-

class Constraint:
    def __init__(self): pass
    def process_new_value(self): pass
    def process_forget_value(self): pass

class Connector:
    def __init__(self):
        self.value = None
        self.informant = None
        self.constraints = []

    @staticmethod
    def for_each_except(exception, bln, items):
        for item in items:
            if item != exception:
                if bln:
                    item.process_new_value()
                else:
                    item.process_forget_value()
        return 'done'

    @property
    def has_value(self):
        return self.informant != None
    
    def set_value(self, newval, setter):
        if not self.has_value:
            self.value = newval
            self.informant = setter
            return self.for_each_except(setter, True, self.constraints)
        if self.value != newval:
            raise Exception('Contradiction {0}, {1}'.format(self.value, newval))
        return 'ignored'
    
    def forget_value(self, retractor):
        if retractor == self.informant:
            self.informant = None
            return self.for_each_except(
                retractor, False, self.constraints)
        return 'ignored'
    
    def connect(self, constraint):
        try:
            self.constraints.index(constraint)
        except:
            self.constraints.insert(0, constraint)
        if self.has_value:
            constraint.process_new_value()
        return 'done'
    def probe(self, name):
        p = Probe(name, self)
        self.connect(p)

class Probe(Constraint):
    def __init__(self, name, connector):
        self.name = name
        self.connector = connector
        
    def print_probe(self, value):
        print('Probe: {0} = {1}'.format(self.name, value))
        
    def process_new_value(self):
        self.print_probe(self.connector.value)
        
    def process_forget_value(self):
        self.print_probe('?')
        
class Adder(Constraint):
    def __init__(self, a1, a2, s):
        self.a1 = a1
        self.a2 = a2
        self.s = s
        self.a1.connect(self)
        self.a2.connect(self)
        self.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.s.forget_value(self)
        self.a1.forget_value(self)
        self.a2.forget_value(self)
        self.process_new_value()

if __name__ == '__main__':
    a1 = Connector()
    a2 = Connector()
    s = Connector()
    adder = Adder(a1, a2, s)
    i = 'kamimura'
    a1.probe('a1')
    a2.probe('a2')
    s.probe('sum')
    try:
        a1.set_value(10, i)
        a2.set_value(20, i)
        a1.forget_value(i)
        s.set_value(100, i)
        s.set_value(200, i)
    except Exception as err:
        print(err)

入出力結果(Terminal, IPython)

$ ipython
Python 3.4.1 (default, May 21 2014, 01:39:38) 
Type "copyright", "credits" or "license" for more information.

IPython 2.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: from constraint_system import *

In [2]: a1 = Connector()

In [3]: a2 = Connector()

In [4]: s = Connector()

In [5]: adder = Adder(a1, a2, s)

In [6]: i = 'kamimura'

In [7]: a1.probe('a1')

In [8]: a2.probe('a2')

In [9]: s.probe('sum')

In [10]: a1.set_value(10, i)
Probe: a1 = 10
Out[10]: 'done'

In [11]: a2.set_value(20, i)
Probe: a2 = 20
Probe: sum = 30
Out[11]: 'done'

In [12]: a1.forget_value(i)
Probe: a1 = ?
Probe: sum = ?
Out[12]: 'done'

In [13]: s.set_value(100, i)
Probe: sum = 100
Probe: a1 = 80
Out[13]: 'done'

In [14]: s.set_value(100, i)
Out[14]: 'ignored'

In [15]: quit()
$ ./constraint_system.py
Probe: a1 = 10
Probe: a2 = 20
Probe: sum = 30
Probe: a1 = ?
Probe: sum = ?
Probe: sum = 100
Probe: a1 = 80
Contradiction 100, 200
$

単純に、好みによるかな〜

0 コメント:

コメントを投稿