Browse Source

Add new turmit using RPN expr to determine direction

Yann Weber 6 years ago
parent
commit
9439c6c95b
4 changed files with 209 additions and 0 deletions
  1. 2
    0
      gte/__init__.py
  2. 84
    0
      gte/turmit.py
  3. 0
    0
      tests/__init__.py
  4. 123
    0
      tests/test_turmit.py

+ 2
- 0
gte/__init__.py View File

@@ -0,0 +1,2 @@
1
+##@brief GTE Genetic Turmits Evolver
2
+

+ 84
- 0
gte/turmit.py View File

@@ -0,0 +1,84 @@
1
+import collections
2
+import inspect
3
+
4
+_op_list = collections.OrderedDict()
5
+
6
+def RpnOp(method):
7
+    ''' @brief Decorator for RPN operation that autodetect argument count
8
+        
9
+        Autodetect argument count and pop them from the stack. Then attempt
10
+        to push values from result as an array. If it fails result is push
11
+        as it.
12
+
13
+        @warning if result is None nothing is push
14
+    '''
15
+    def wrapped(self):
16
+        narg = len(inspect.signature(method).parameters)-1
17
+        args = [ self._pop() for _ in range(narg) ]
18
+        res = method(self, *args)
19
+        if res is None:
20
+            return None
21
+        try:
22
+            for topush in res:
23
+                self._push(topush)
24
+        except TypeError:
25
+            self._push(res)
26
+        return res
27
+    _op_list[method.__name__] = (method, wrapped)
28
+    return wrapped
29
+
30
+
31
+class Turmit(object):
32
+    ''' @brief Represent a turmit that act given an RPN expression with an
33
+        infinite looping stack with variable stack size.
34
+    '''
35
+    
36
+    def __init__(self, stack_size=8):
37
+        ## @brief List that represent a stack
38
+        self._stack = [ 0 for _ in range(stack_size)]
39
+        ## @brief Stack head index
40
+        self._cur = stack_size - 1
41
+
42
+    @property
43
+    def shead(self):
44
+        return self._stack[self._cur]
45
+
46
+    def _pop(self):
47
+        ''' @brief Pop a value from the stack
48
+            
49
+            If stack head is 0, set the stack head to len(self._stack) - 1
50
+
51
+            @return poped value
52
+        '''
53
+        res = self._stack[self._cur]
54
+        if self._cur == 0:
55
+            self._cur = len(self._stack) - 1
56
+        else:
57
+            self._cur -= 1
58
+        return res
59
+
60
+    def _push(self, val):
61
+        ''' @brief Push a value on the stack
62
+            
63
+            If no size left on the stack, the head is set to 0
64
+        '''
65
+        self._cur += 1
66
+        if self._cur >= len(self._stack):
67
+            self._cur = 0
68
+        self._stack[self._cur] = val
69
+
70
+    @RpnOp
71
+    def mem_sz(self, new_sz):
72
+        if new_sz < 2:
73
+            raise ValueError('New size sould be >= 2')
74
+        stksz = len(self._stack)
75
+        if new_sz > stksz:
76
+            self._stack += [ 0 for _ in range(new_sz - stksz) ]
77
+        elif new_sz < stksz:
78
+            self._stack = self._stack[0:new_sz]
79
+            if self._cur >= new_sz:
80
+                self._cur = 0
81
+    
82
+    @RpnOp
83
+    def add(self, a, b):
84
+        return a + b

+ 0
- 0
tests/__init__.py View File


+ 123
- 0
tests/test_turmit.py View File

@@ -0,0 +1,123 @@
1
+import unittest
2
+from unittest import skip
3
+
4
+from gte.turmit import Turmit
5
+
6
+class TurmitTestCase(unittest.TestCase):
7
+    
8
+    def test_init_class(self):
9
+        ''' Test Turmit class __init__ '''
10
+        t = Turmit(42)
11
+        self.assertEqual(len(t._stack), 42)
12
+        self.assertEqual(t.shead, 0)
13
+        self.assertEqual(len(t._stack) - 1 , t._cur)
14
+
15
+    def test_push(self):
16
+        ''' Test Turmit _push() method '''
17
+        t = Turmit()
18
+        t._push(1)
19
+        self.assertEqual(t.shead, 1)
20
+        t._push(2)
21
+        self.assertEqual(t.shead, 2)
22
+
23
+    def test_add(self):
24
+        ''' Test turmit add method '''
25
+        t = Turmit()
26
+
27
+        t._push(42)
28
+        t._push(8)
29
+        t.add()
30
+        self.assertEqual(t._cur, 0)
31
+        self.assertEqual(t.shead, 50)
32
+
33
+        t._push(42)
34
+        t._push(8)
35
+        t.add()
36
+        self.assertEqual(t._cur, 1)
37
+        self.assertEqual(t.shead, 50)
38
+
39
+        t.add()
40
+
41
+        self.assertEqual(t._cur, 0)
42
+        self.assertEqual(t.shead, 100)
43
+
44
+    def test_mem_sz(self):
45
+        ''' Test turmit mem_sz() operation '''
46
+        t = Turmit(8)
47
+        self.assertEqual(len(t._stack), 8)
48
+
49
+        t._push(42)
50
+        t.mem_sz()
51
+        self.assertEqual(len(t._stack), 42)
52
+        self.assertEqual(t._cur, 7)
53
+
54
+        t._push(42)
55
+        t._push(8)
56
+        t.mem_sz()
57
+        self.assertEqual(t._cur, 0)
58
+        self.assertEqual(t.shead, 42)
59
+
60
+
61
+    @skip('Need implementation')
62
+    def test_sub(self):
63
+        ''' Test turmit sub() method '''
64
+        t = Turmit()
65
+
66
+        t._push(50)
67
+        t._push(8)
68
+
69
+        t.sub()
70
+        self.assertEqual(t._cur, 0)
71
+        self.assertEqual(t.shead, 42)
72
+
73
+        t._push(50)
74
+        t._push(8)
75
+        t.sub()
76
+        self.assertEqual(t._cur, 1)
77
+        self.assertEqual(t.shead, 42)
78
+
79
+        t.sub()
80
+        self.assertEqual(t._cur, 0)
81
+        self.assertEqual(t.shead, 0)
82
+
83
+    @skip('Need implementation')
84
+    def test_mul(self):
85
+        ''' Test turmit mul() method '''
86
+        t = Turmit()
87
+
88
+        t._push(7)
89
+        t._push(6)
90
+
91
+        t.mul()
92
+        self.assertEqual(t._cur, 0)
93
+        self.assertEqual(t.shead, 42)
94
+
95
+        t._push(7)
96
+        t._push(6)
97
+        t.mul()
98
+        self.assertEqual(t._cur, 1)
99
+        self.assertEqual(t.shead, 42)
100
+
101
+        t.mul()
102
+        self.assertEqual(t._cur, 0)
103
+        self.assertEqual(t.shead, 42 *42)
104
+
105
+    @skip('Need implementation')
106
+    def test_mod(self):
107
+        ''' Test turmit mod() method '''
108
+        t = Turmit()
109
+        t._push(42)
110
+        t._push(4)
111
+
112
+        t.mod()
113
+        self.assertEqual(t._cur, 0)
114
+        self.assertEqual(t.shead, 2)
115
+
116
+    @skip('Need implementation')
117
+    def test_dup(self):
118
+        ''' Test turmit dup() method '''
119
+        t = Turmit()
120
+        t._push(42)
121
+        t.dup()
122
+        self.assertEqual(t._cur, 1)
123
+        sefl.assertEqual(t.shead, 42)

Loading…
Cancel
Save