Example #1
0
    def test_home_automation(self):
        """A simple example in the home automation domain"""
        brightness_1 = Input()
        brightness_2 = Input()
        brightness_sum = Node(action=lambda *args: sum(args),
                              inputs=Node.inputs(brightness_1, brightness_2))

        def inverse(value):
            """Return the inverse of a value in the range 0..510"""
            return 510 - value

        brightness_inverse = Node(action=inverse,
                                  inputs=Node.inputs(brightness_sum))

        lamp_power_changes = []

        def set_lamp_power(value):
            """Log changes to lamp power"""
            lamp_power_changes.append(value)

        _lamp_power = Node(action=set_lamp_power,
                           inputs=Node.inputs(brightness_inverse),
                           triggered=True)

        update_inputs_get_triggered([(brightness_1, 20), (brightness_2, 40)])

        self.assertEqual([450], lamp_power_changes)

        update_inputs_get_triggered([(brightness_1, 20), (brightness_2, 40)])

        self.assertEqual([450], lamp_power_changes)

        update_inputs_get_triggered([(brightness_1, 24), (brightness_2, 40)])

        self.assertEqual([450, 446], lamp_power_changes)
Example #2
0
 def inner():
     input_node = Input()
     output_node = Node(action=lambda value: value,
                        inputs=Node.inputs(input_node))
     self.assertEqual(set([output_node]), input_node._dependents)
     self.assertEqual((input_node, ), output_node._positional_inputs)
     return weakref.ref(input_node), weakref.ref(output_node)
Example #3
0
 def test_garbage_collection(self):
     """Interconnected nodes are garbage collected"""
     input_node = Input()
     output_node = Node(action=lambda value: value,
                        inputs=Node.inputs(input_node))
     self.assertEqual(set([output_node]), input_node._dependents)
     self.assertEqual((input_node, ), output_node._positional_inputs)
     input_ref = weakref.ref(input_node)
     output_ref = weakref.ref(output_node)
     del input_node
     del output_node
     gc.collect()
     self.assertEqual(None, input_ref())
     self.assertEqual(None, output_ref())
Example #4
0
    def test_garbage_collection_with_finalizer_values(self):
        """Interconnected nodes with gc-unfriendly values are gc'd"""
        class Val(object):
            def __del__(self):
                pass

        val = Val()
        input_node = Input(value=val)
        output_node = Node(action=lambda value: value,
                           inputs=Node.inputs(input_node))
        self.assertEqual(set([output_node]), input_node._dependents)
        self.assertEqual((input_node, ), output_node._positional_inputs)
        self.assertEqual(val, input_node._value)
        input_ref = weakref.ref(input_node)
        output_ref = weakref.ref(output_node)
        del input_node
        del output_node
        gc.collect()
        self.assertEqual(None, input_ref())
        self.assertEqual(None, output_ref())
Example #5
0
 def setUp(self):
     self.root = Input('root')
     self.dependent = ConstantNode('dependent', triggered=False)
     self.root._connect(self.dependent)
     self.triggered = ConstantNode('triggered', triggered=True)
     self.root._connect(self.triggered)
Example #6
0
class NodeDependentTestCase(TestCase):
    """Test case for triggered dependent Nodes"""
    def setUp(self):
        self.root = Input('root')
        self.dependent = ConstantNode('dependent', triggered=False)
        self.root._connect(self.dependent)
        self.triggered = ConstantNode('triggered', triggered=True)
        self.root._connect(self.triggered)

    def test_keep_dirty(self):
        """Setting a dirty Node as dirty doesn't trigger dependents"""
        triggered_nodes = self.root.set_value(DIRTY)
        self.assertEqual(set(), triggered_nodes)

    def test_set_value_triggers_dependents(self):
        """Setting a value to a dirty Node triggers dependents"""
        triggered_nodes = self.root.set_value(0)
        self.assertEqual({self.triggered}, triggered_nodes)

    def test_set_value_triggers_dependents(self):
        """Setting the previous value to an Input doesn't trigger dependents"""
        self.root.set_value(0)
        triggered_nodes = self.root.set_value(0)
        self.assertEqual(set(), triggered_nodes)

    def test_get_triggered_dependents(self):
        """Setting a value to a dirty Node triggers dependents"""
        triggered_nodes = self.root._get_triggered_dependents()
        self.assertEqual({self.triggered}, triggered_nodes)

    def test_get_deep_triggered_dependents(self):
        """Setting a value to a dirty Node triggers dependents tree"""
        child1 = ConstantNode('child1', triggered=True)
        child2 = ConstantNode('child2', triggered=True)
        self.triggered._connect(child1)
        self.triggered._connect(child2)
        triggered_nodes = self.root._get_triggered_dependents()
        self.assertEqual({self.triggered, child1, child2}, triggered_nodes)
Example #7
0
 def test_value_property_getter(self):
     """The value of a Node can be set with the .value property"""
     root = Input(value=5)
     leaf = Node(action=lambda value: value, inputs=Node.inputs(root))
     self.assertEqual(5, leaf.value)
Example #8
0
    print ('Measuring distance from ({x}, {y}) to {t[x]}'
           .format(x=x, y=y, t=TARGET))
    dx = x - TARGET['x']
    dy = y - TARGET['y']
    return math.sqrt(dx ** 2 + dy ** 2)


def is_close_to_target(distance):
    return distance < RADIUS


def get_distance_description(is_close):
    return "INSIDE" if is_close else "OUTSIDE"


mousex = Input(name='mouse x')
mousey = Input(name='mouse y')
distance = Node(
    name='distance',
    action=get_distance,
    inputs=Node.inputs(mousex, mousey))
is_close = Node(
    name='is close',
    action=is_close_to_target,
    inputs=Node.inputs(distance))
alert = Node(
    name='alert',
    action=get_distance_description,
    inputs=Node.inputs(is_close))

from lusmu.core import Input, Node, update_inputs
from lusmu.visualization import visualize_graph
import math
import operator

a = Input(name='length of cathetus a')
b = Input(name='length of cathetus b')


def square(x):
    return x**2


def sum_(*args):
    return sum(args)


def sqrt(square):
    print '** taking square root of {:.2f}'.format(square)
    return math.sqrt(square)


area_a = Node(name='square of a', action=square, inputs=Node.inputs(a))
area_b = Node(name='square of b', action=square, inputs=Node.inputs(b))
area_hypothenuse = Node(name='square of hypothenuse',
                        action=sum_,
                        inputs=Node.inputs(area_a, area_b))
hypothenuse = Node(name='length of hypothenuse',
                   action=sqrt,
                   inputs=Node.inputs(area_hypothenuse))
sin_alpha = Node(name='sin of alpha',
Example #10
0
 def setUp(self):
     self.input = Input()
Example #11
0
 def test_set_value(self):
     """A value set to a dirty Node is stored in the object"""
     node = Input('name')
     node.set_value(0)
     self.assertEqual(0, node._value)
Example #12
0
 def setUp(self):
     self.root = Input('root')
     self.dependent = ConstantNode('dependent', triggered=False)
     self.root._connect(self.dependent)
     self.triggered = ConstantNode('triggered', triggered=True)
     self.root._connect(self.triggered)
Example #13
0
class NodeDependentTestCase(TestCase):
    """Test case for triggered dependent Nodes"""

    def setUp(self):
        self.root = Input('root')
        self.dependent = ConstantNode('dependent', triggered=False)
        self.root._connect(self.dependent)
        self.triggered = ConstantNode('triggered', triggered=True)
        self.root._connect(self.triggered)

    def test_keep_dirty(self):
        """Setting a dirty Node as dirty doesn't trigger dependents"""
        triggered_nodes = self.root.set_value(DIRTY)
        self.assertEqual(set(), triggered_nodes)

    def test_set_value_triggers_dependents(self):
        """Setting a value to a dirty Node triggers dependents"""
        triggered_nodes = self.root.set_value(0)
        self.assertEqual({self.triggered}, triggered_nodes)

    def test_set_value_triggers_dependents(self):
        """Setting the previous value to an Input doesn't trigger dependents"""
        self.root.set_value(0)
        triggered_nodes = self.root.set_value(0)
        self.assertEqual(set(), triggered_nodes)

    def test_get_triggered_dependents(self):
        """Setting a value to a dirty Node triggers dependents"""
        triggered_nodes = self.root._get_triggered_dependents()
        self.assertEqual({self.triggered}, triggered_nodes)

    def test_get_deep_triggered_dependents(self):
        """Setting a value to a dirty Node triggers dependents tree"""
        child1 = ConstantNode('child1', triggered=True)
        child2 = ConstantNode('child2', triggered=True)
        self.triggered._connect(child1)
        self.triggered._connect(child2)
        triggered_nodes = self.root._get_triggered_dependents()
        self.assertEqual({self.triggered, child1, child2}, triggered_nodes)
Example #14
0
 def test_value_property_setter(self):
     """The value of a Node can be set with the .value property"""
     root = Input()
     leaf = Node(action=lambda value: value, inputs=Node.inputs(root))
     root.value = 5
     self.assertEqual(5, leaf.get_value())
Example #15
0
 def test_set_value(self):
     """A value set to a dirty Node is stored in the object"""
     node = Input('name')
     node.set_value(0)
     self.assertEqual(0, node._value)
Example #16
0
 def test_initial_value(self):
     """The initial value of an Input can be set in the constructor"""
     node = Input(value=5)
     self.assertEqual(5, node._value)
Example #17
0
    def build_fragment(self, x, y):
        print "diff between {} and {}".format(x, y)
        return x - y


class Addition(Fragment):
    def build_fragment(self, x, y):
        return x + y


class Power(Fragment):
    def build_fragment(self, x, p):
        return x**p


x = Input(name='x-value')
y = Input(name='y-value')
p = Input(name='power')

difference = Difference(inputs=Node.inputs(x, y))
difference2 = Difference(inputs=Node.inputs(p, p))
addition = Addition(inputs=Node.inputs(difference, difference2))
power = Power(inputs=Node.inputs(difference, p))

update_inputs([(p, 10), (x, 5), (y, 10)])

# print power.value
print addition.value

print "changing y"
update_inputs([(y, 5)])