In [12]:
class RV:
    def __init__ (self, _var, _card ):
        self.var = _var
        self.card = _card
        return
    
    def __iter__( self ):
        for v in self.var:
            yield v
            
    def __eq__( self, other ):
        return ( self.var == other.var )


class Factor:
    def __init__( self, _rvs, _stride, _vals ):
        # RVs
        if type(_rvs) is not list: raise Exception( "Constructor takes list of RV objects and stride info")
        if not _rvs: raise Exception( "Factor Info passed an empty array in constructor" )
        if type(_rvs[0]) is not RV: raise Exception( "Should be list of RV objects" )
        
        self.rvs = _rvs

        
        # Stride
        stride_type = type(_stride)
        if   stride_type is dict: self.stride = _stride
        elif stride_type is list: self.stride = {rv.var:_stride[idx] for idx, rv in enumerate( _rvs ) }
        else: raise Exception("Bad stride type")
            
        return
    #

    def __repr__( self ):
        return ( "Scope : {0.scope}\n" +
                 "Cards : {0.card}\n" +
                 "Stride: {0.stride}" ).format( self )
    #

    def __mul__( self, other ):
        new_rvs = self.rvs + other.rvs
        # Calc new strides
        # And new valies
        return Factor( new_rvs, new_stride )
    #
    
    def __iter__( self ):
        yield None
#
        

a = RV(0,2)
b = RV(1,2)
c = RV(2,3)

f1 = Factor( [a,b], [1, 2], [4,5,6,7] )
f2 = Factor( [b,c], [1, 3], [8,9,10,11,12,13] )
f2 * f1


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-28be2630d637> in <module>()
     56 f1 = Factor( [a,b], [1, 2], [4,5,6,7] )
     57 f2 = Factor( [b,c], [1, 3], [8,9,10,11,12,13] )
---> 58 f2 * f1

<ipython-input-12-28be2630d637> in __mul__(self, other)
     42         new_stride = self.stride.copy()
     43         new_stride.update( other.stride )
---> 44         return Factor( new_rvs, new_stride )
     45     #
     46 

TypeError: __init__() missing 1 required positional argument: '_vals'