<commit_before># gglogic boolean logic device simulations for ggmath

from ggmath import MathApp, _MathDynamic
from abc import ABCMeta, abstractmethod


# decorator for _getvalue or any value handler that may experience recursion
def recursiontrap(handler):
    def trapmagic(self):
        if not self.ingetvalue:
            self.ingetvalue = True
            self.lastget = handler(self)
            self.ingetvalue = False
            return self.lastget
        else:
            self.ingetvalue = False
            return self.lastget
            
    return trapmagic 


class _BoolDevice(_MathDynamic, metaclass=ABCMeta):

    def __init__(self, mininputqty, *args, **kwargs):
        """
        Required Inputs
        
        * **mininputqty** minimum number of inputs possible
        
        Optional keyword arguments
        
        * **namedinputs** list of input names
        """
        self.In = [None]*mininputqty
        self.Enable = True
        namedinputs = kwargs.get('namedinputs', [])
        self._indict = {name:self.Eval(None) for name in namedinputs}
        self.ingetvalue = False
        self.lastget = None
        

    @property
    def In(self):
        return self._input
    
    @In.setter
    def In(self, val):
        try:
            self._input = [self.Eval(v) for v in list(val)]
        except TypeError:
            self._input = [self.Eval(val)]
            
    # Enable attribute controls the "tri-state" of output
    @property
    def Enable(self):
        return self._enable
    
    @Enable.setter
    def Enable(self, val):
        self._enable = self.Eval(val)
        
    @abstractmethod
    @recursiontrap     # MUST use with any implementation that may recurse!
    def _getvalue(self):
        return None
    
    def _inputState(self, value):
        """
        interprets a value that could be single input or a list of inputs!
        """
        try:
            inputs = [].extend(value)
        except TypeError:
            inputs = [value]
        scalars = [v() for v in inputs]
        ones = scalars.count(True) + scalars.count(1)
        zeros = scalars.count(False) + scalars.count(0)
        if ones > 0 and zeros > 0:
            raise ValueError("Conflicting inputs found")
        if ones > 0:
            return True
        elif zeros > 0:
            return False
        else: 
            return None
    
    def __call__(self):
        if self.Enable:
            return self._getvalue()
        else:
            return None
    
    def GetInput(self, inputname):
        return self._inputState(self._indict[inputname])

    def SetInput(self, inputname, reference):
        self._indict[inputname] = self.Eval(reference)
    


class _BoolOneInput(_BoolDevice):

    def __init__(self, *args, **kwargs):
        """ 
        No Required Inputs
        """
        super().__init__(1, *args, **kwargs)

    
class _BoolMultiInput(_BoolDevice):

    def __init__(self, *args, **kwargs):
        """ 
        No Required Inputs
        """
        super().__init__(2, *args, **kwargs)


class BoolNOT(_BoolOneInput):

    @recursiontrap
    def _getvalue(self):
        inval = self._inputState(self.In[0])
        if inval == None:
            return True  # equivalent to an "open" input
        else:
            return not inval


class BoolAND(_BoolMultiInput):
    
    @recursiontrap
    def _getvalue(self):
        for v in self._input:
            if not self._inputState(v):
                return False
        return True
        
class BoolNOR(_BoolMultiInput):
    
    @recursiontrap
    def _getvalue(self):
        for v in self._input:
            if self._inputState(v):
                return False
        return True
        
class BoolNAND(_BoolMultiInput):
    
    @recursiontrap
    def _getvalue(self):
        for v in self._input:
            if not self._inputState(v):
                return True
        return False
        <commit_msg>Updated from Brython Server: 8/17/2018 5:54:28 PM<commit_after># gglogic boolean logic device simulations for ggmath

from ggmath import MathApp, _MathDynamic
from abc import ABCMeta, abstractmethod


# decorator for _getvalue or any value handler that may experience recursion
def recursiontrap(handler):
    def trapmagic(self):
        if not self.ingetvalue:
            self.ingetvalue = True
            self.lastget = handler(self)
            self.ingetvalue = False
            return self.lastget
        else:
            self.ingetvalue = False
            return self.lastget
            
    return trapmagic 


class _BoolDevice(_MathDynamic, metaclass=ABCMeta):

    def __init__(self, mininputqty, *args, **kwargs):
        """
        Required Inputs
        
        * **mininputqty** minimum number of inputs possible
        
        Optional keyword arguments
        
        * **namedinputs** list of input names
        """
        self.In = [None]*mininputqty
        self.Enable = True
        namedinputs = kwargs.get('namedinputs', [])
        self._indict = {name:self.Eval(None) for name in namedinputs}
        self.ingetvalue = False
        self.lastget = None
        

    @property
    def In(self):
        return self._input
    
    @In.setter
    def In(self, val):
        try:
            self._input = [self.Eval(v) for v in list(val)]
        except TypeError:
            self._input = [self.Eval(val)]
            
    # Enable attribute controls the "tri-state" of output
    @property
    def Enable(self):
        return self._enable
    
    @Enable.setter
    def Enable(self, val):
        self._enable = self.Eval(val)
        
    @abstractmethod
    @recursiontrap     # MUST use with any implementation that may recurse!
    def _getvalue(self):
        return None
    
    def _inputState(self, value):
        """
        interprets a value that could be single input or a list of inputs!
        """
        try:
            inputs = [].extend(value)
        except TypeError:
            inputs = [value]
        scalars = [v() for v in inputs]
        ones = scalars.count(True) + scalars.count(1)
        zeros = scalars.count(False) + scalars.count(0)
        if ones > 0 and zeros > 0:
            raise ValueError("Conflicting inputs found")
        if ones > 0:
            return True
        elif zeros > 0:
            return False
        else: 
            return None
    
    def __call__(self):
        if self.Enable:
            return self._getvalue()
        else:
            return None
    
    def GetInput(self, inputname):
        return self._inputState(self._indict[inputname])

    def SetInput(self, inputname, reference):
        self._indict[inputname] = self.Eval(reference)
    


class _BoolOneInput(_BoolDevice):

    def __init__(self, *args, **kwargs):
        """ 
        No Required Inputs
        """
        super().__init__(1, *args, **kwargs)

    
class _BoolMultiInput(_BoolDevice):

    def __init__(self, *args, **kwargs):
        """ 
        No Required Inputs
        """
        super().__init__(2, *args, **kwargs)


class BoolNOT(_BoolOneInput):

    @recursiontrap
    def _getvalue(self):
        inval = self._inputState(self.In[0])
        if inval == None:
            return True  # equivalent to an "open" input
        else:
            return not inval


class BoolAND(_BoolMultiInput):
    
    @recursiontrap
    def _getvalue(self):
        for v in self._input:
            if not self._inputState(v):
                return False
        return True
        
class BoolNOR(_BoolMultiInput):
    
    @recursiontrap
    def _getvalue(self):
        for v in self._input:
            if self._inputState(v):
                return False
        return True
        
class BoolNAND(_BoolMultiInput):
    
    @recursiontrap
    def _getvalue(self):
        print('getting NAND output')
        for v in self._input:
            if not self._inputState(v):
                return True
        return False
        
{'fraction_non_alphanumeric': 0.08657089319175515, 'fraction_numerical': 0.0037476577139287947, 'mean_word_length': 1.8091228070175438, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '850931', 'n_tokens_mistral': 2315, 'n_tokens_neox': 2227, 'n_words': 635}