Add new turmit using RPN expr to determine direction

This commit is contained in:
Yann Weber 2018-04-24 20:50:36 +02:00
commit 9439c6c95b
4 changed files with 209 additions and 0 deletions

2
gte/__init__.py Normal file
View file

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

84
gte/turmit.py Normal file
View 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
View file

123
tests/test_turmit.py Normal file
View 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)