Add new turmit using RPN expr to determine direction
This commit is contained in:
parent
d25381a607
commit
9439c6c95b
4 changed files with 209 additions and 0 deletions
2
gte/__init__.py
Normal file
2
gte/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
##@brief GTE Genetic Turmits Evolver
|
||||
|
||||
84
gte/turmit.py
Normal file
84
gte/turmit.py
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
import collections
|
||||
import inspect
|
||||
|
||||
_op_list = collections.OrderedDict()
|
||||
|
||||
def RpnOp(method):
|
||||
''' @brief Decorator for RPN operation that autodetect argument count
|
||||
|
||||
Autodetect argument count and pop them from the stack. Then attempt
|
||||
to push values from result as an array. If it fails result is push
|
||||
as it.
|
||||
|
||||
@warning if result is None nothing is push
|
||||
'''
|
||||
def wrapped(self):
|
||||
narg = len(inspect.signature(method).parameters)-1
|
||||
args = [ self._pop() for _ in range(narg) ]
|
||||
res = method(self, *args)
|
||||
if res is None:
|
||||
return None
|
||||
try:
|
||||
for topush in res:
|
||||
self._push(topush)
|
||||
except TypeError:
|
||||
self._push(res)
|
||||
return res
|
||||
_op_list[method.__name__] = (method, wrapped)
|
||||
return wrapped
|
||||
|
||||
|
||||
class Turmit(object):
|
||||
''' @brief Represent a turmit that act given an RPN expression with an
|
||||
infinite looping stack with variable stack size.
|
||||
'''
|
||||
|
||||
def __init__(self, stack_size=8):
|
||||
## @brief List that represent a stack
|
||||
self._stack = [ 0 for _ in range(stack_size)]
|
||||
## @brief Stack head index
|
||||
self._cur = stack_size - 1
|
||||
|
||||
@property
|
||||
def shead(self):
|
||||
return self._stack[self._cur]
|
||||
|
||||
def _pop(self):
|
||||
''' @brief Pop a value from the stack
|
||||
|
||||
If stack head is 0, set the stack head to len(self._stack) - 1
|
||||
|
||||
@return poped value
|
||||
'''
|
||||
res = self._stack[self._cur]
|
||||
if self._cur == 0:
|
||||
self._cur = len(self._stack) - 1
|
||||
else:
|
||||
self._cur -= 1
|
||||
return res
|
||||
|
||||
def _push(self, val):
|
||||
''' @brief Push a value on the stack
|
||||
|
||||
If no size left on the stack, the head is set to 0
|
||||
'''
|
||||
self._cur += 1
|
||||
if self._cur >= len(self._stack):
|
||||
self._cur = 0
|
||||
self._stack[self._cur] = val
|
||||
|
||||
@RpnOp
|
||||
def mem_sz(self, new_sz):
|
||||
if new_sz < 2:
|
||||
raise ValueError('New size sould be >= 2')
|
||||
stksz = len(self._stack)
|
||||
if new_sz > stksz:
|
||||
self._stack += [ 0 for _ in range(new_sz - stksz) ]
|
||||
elif new_sz < stksz:
|
||||
self._stack = self._stack[0:new_sz]
|
||||
if self._cur >= new_sz:
|
||||
self._cur = 0
|
||||
|
||||
@RpnOp
|
||||
def add(self, a, b):
|
||||
return a + b
|
||||
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
123
tests/test_turmit.py
Normal file
123
tests/test_turmit.py
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
import unittest
|
||||
from unittest import skip
|
||||
|
||||
from gte.turmit import Turmit
|
||||
|
||||
class TurmitTestCase(unittest.TestCase):
|
||||
|
||||
def test_init_class(self):
|
||||
''' Test Turmit class __init__ '''
|
||||
t = Turmit(42)
|
||||
self.assertEqual(len(t._stack), 42)
|
||||
self.assertEqual(t.shead, 0)
|
||||
self.assertEqual(len(t._stack) - 1 , t._cur)
|
||||
|
||||
def test_push(self):
|
||||
''' Test Turmit _push() method '''
|
||||
t = Turmit()
|
||||
t._push(1)
|
||||
self.assertEqual(t.shead, 1)
|
||||
t._push(2)
|
||||
self.assertEqual(t.shead, 2)
|
||||
|
||||
def test_add(self):
|
||||
''' Test turmit add method '''
|
||||
t = Turmit()
|
||||
|
||||
t._push(42)
|
||||
t._push(8)
|
||||
t.add()
|
||||
self.assertEqual(t._cur, 0)
|
||||
self.assertEqual(t.shead, 50)
|
||||
|
||||
t._push(42)
|
||||
t._push(8)
|
||||
t.add()
|
||||
self.assertEqual(t._cur, 1)
|
||||
self.assertEqual(t.shead, 50)
|
||||
|
||||
t.add()
|
||||
|
||||
self.assertEqual(t._cur, 0)
|
||||
self.assertEqual(t.shead, 100)
|
||||
|
||||
def test_mem_sz(self):
|
||||
''' Test turmit mem_sz() operation '''
|
||||
t = Turmit(8)
|
||||
self.assertEqual(len(t._stack), 8)
|
||||
|
||||
t._push(42)
|
||||
t.mem_sz()
|
||||
self.assertEqual(len(t._stack), 42)
|
||||
self.assertEqual(t._cur, 7)
|
||||
|
||||
t._push(42)
|
||||
t._push(8)
|
||||
t.mem_sz()
|
||||
self.assertEqual(t._cur, 0)
|
||||
self.assertEqual(t.shead, 42)
|
||||
|
||||
|
||||
@skip('Need implementation')
|
||||
def test_sub(self):
|
||||
''' Test turmit sub() method '''
|
||||
t = Turmit()
|
||||
|
||||
t._push(50)
|
||||
t._push(8)
|
||||
|
||||
t.sub()
|
||||
self.assertEqual(t._cur, 0)
|
||||
self.assertEqual(t.shead, 42)
|
||||
|
||||
t._push(50)
|
||||
t._push(8)
|
||||
t.sub()
|
||||
self.assertEqual(t._cur, 1)
|
||||
self.assertEqual(t.shead, 42)
|
||||
|
||||
t.sub()
|
||||
self.assertEqual(t._cur, 0)
|
||||
self.assertEqual(t.shead, 0)
|
||||
|
||||
@skip('Need implementation')
|
||||
def test_mul(self):
|
||||
''' Test turmit mul() method '''
|
||||
t = Turmit()
|
||||
|
||||
t._push(7)
|
||||
t._push(6)
|
||||
|
||||
t.mul()
|
||||
self.assertEqual(t._cur, 0)
|
||||
self.assertEqual(t.shead, 42)
|
||||
|
||||
t._push(7)
|
||||
t._push(6)
|
||||
t.mul()
|
||||
self.assertEqual(t._cur, 1)
|
||||
self.assertEqual(t.shead, 42)
|
||||
|
||||
t.mul()
|
||||
self.assertEqual(t._cur, 0)
|
||||
self.assertEqual(t.shead, 42 *42)
|
||||
|
||||
@skip('Need implementation')
|
||||
def test_mod(self):
|
||||
''' Test turmit mod() method '''
|
||||
t = Turmit()
|
||||
t._push(42)
|
||||
t._push(4)
|
||||
|
||||
t.mod()
|
||||
self.assertEqual(t._cur, 0)
|
||||
self.assertEqual(t.shead, 2)
|
||||
|
||||
@skip('Need implementation')
|
||||
def test_dup(self):
|
||||
''' Test turmit dup() method '''
|
||||
t = Turmit()
|
||||
t._push(42)
|
||||
t.dup()
|
||||
self.assertEqual(t._cur, 1)
|
||||
sefl.assertEqual(t.shead, 42)
|
||||
Loading…
Add table
Add a link
Reference in a new issue