Your task in this kata is to implement the function `create_number_class` which will take a string parameter `alphabet` and return a class representing a number composed of this alphabet.

The class number will implement the four classical arithmetic operations (`+`, `-`, `*`, `//`), a method to convert itself to string, and a `convert_to` method which will take another class number as parameter and will return the value of the actual class number converted to the equivalent value with tha alphabet of the parameter class (return a new instance of this one).

Example:

```python
BinClass = create_number_class('01')
HexClass = create_number_class('0123456789ABCDEF')

x = BinClass('1010')
y = BinClass('10')

print(x+y)                   => '1100'
isinstance(x+y, BinClass)    => True
print(x.convert_to(HexClass) => 'A'
```

___Notes:___

* Only positives integers will be used (either as parameters or results of calculations).
* You'll never encounter invalid calculations (divisions by zero or things like that).
* Alphabets will contain at least 2 characters.

Difficulty: interview

Starter code:

def create_number_class(alphabet):
	

Solutions:
def create_number_class(alphabet):
    n = len(alphabet)

    class Number(object):
        def __init__(self, s):
            if isinstance(s, str):
                v = 0
                for c in s:
                    v = v * n + alphabet.index(c)
            else:
                v = s
            self.value = v

        def __add__(self, other):
            return Number(self.value + other.value)

        def __sub__(self, other):
            return Number(self.value - other.value)

        def __mul__(self, other):
            return Number(self.value * other.value)

        def __floordiv__(self, other):
            return Number(self.value // other.value)

        def __str__(self):
            ret = []
            v = int(self.value)
            while v:
                (v, r) = divmod(v, n)
                ret.append(alphabet[r])
            return ''.join(reversed(ret or alphabet[0]))

        def convert_to(self, cls):
            return cls(self.value)

    return Number



funcs = [
'__int__', '__index__', '__floor__', '__ceil__', '__trunc__', '__round__',

'__abs__',
'__pos__', '__neg__', '__invert__',

'__add__', '__sub__', '__mul__', '__floordiv__', '__truediv__', '__mod__', '__pow__',
'__and__', '__or__', '__xor__', '__lshift__', '__rshift__',

'__radd__', '__rsub__', '__rmul__', '__rfloordiv__', '__rtruediv__', '__rmod__', '__rpow__',
'__rand__', '__ror__', '__rxor__', '__rlshift__', '__rrshift__',

'__eq__', '__ne__', '__ge__', '__le__', '__gt__', '__lt__',

'numerator', 'denominator', 'real', 'imag', 'conjugate', 'bit_length', 'from_bytes']

CastedInt = type('', (int,), {func: lambda self, *args, func=func, **kwargs:
    self.__class__(getattr(super(CastedInt, self), func)(*args, **kwargs)) for func in funcs})

BaseNumber = type('', (CastedInt,), {
    '__new__': lambda cls, n: super(BaseNumber, cls).__new__(
                                    cls, n if isinstance(n, int) else
                                       sum(cls.alphabet.index(c) * cls.base ** i for i, c in enumerate(n[::-1]))),
    '__str__': lambda self: self and str(self//self.base).lstrip(self.alphabet[0]) + self.alphabet[self%self.base] or self.alphabet[0],
    'convert_to': lambda self, other: other(self)
})

create_number_class = lambda alphabet: type('', (BaseNumber,), {'base': len(alphabet), 'alphabet': alphabet})

def create_number_class(alphabet):
    class CNum:
        
        doc = { e:i for i, e in enumerate(alphabet)}
        sdc = { v:k for k, v in doc.items() }
        l   = len(doc)
        
        def __init__(self,val):
            self.val = val
            self.int = self.to_int(val)
        
        def __str__(self):
            return str(self.val)
        
        def convert_to(self, mod):
            return self.to_str(self.int, mod.sdc, mod.l)
            
        def to_int(self, val):
            return sum(self.doc[e]*(self.l**i) for i, e in enumerate(val[::-1]) )

        def customer(f):
            def wrap(cls, *args):
                return CNum(cls.to_str(f(cls,*args) , cls.sdc, cls.l))
            return wrap
        
        @customer 
        def __add__(self, o):
            return self.int + o.int 
        
        @customer 
        def __sub__(self, o):
            return self.int - o.int 
        
        @customer 
        def __mul__(self, o):
            return self.int * o.int 
        
        @customer 
        def __floordiv__(self, o):
            return self.int // o.int 
           
        @staticmethod
        def to_str(val, dic, l, cnum = ''):
            while val:
                cnum += dic[val%l]
                val //= l
            return dic[val] if not cnum else cnum[::-1]
        
    return CNum

def create_number_class(alp):
    alphabet = {j: i for i, j in enumerate(alp)}
    class BinClass:
        def __init__(self, text) : self.text = text
        __add__ = lambda self, other:self.op(self.text,other.text,'+')
        __sub__ = lambda self, other:self.op(self.text,other.text,'-')
        __mul__ = lambda self, other:self.op(self.text,other.text,'*')
        __floordiv__ = lambda self, other:self.op(self.text,other.text,'//')
        __str__ = lambda self:self.text  
        
        op = lambda self,a,b,sign:BinClass(self.from_decimal(eval('{} {} {}'.format(self.to_decimal(a),sign,self.to_decimal(b)))) or alp[0])
        convert_to = lambda self, base:base(self.text).from_decimal(self.to_decimal(self.text))
        to_decimal = lambda self, s:sum(alphabet[j] * (len(alp) ** (len(s)-1 - i)) for i, j in enumerate(s))
        from_decimal = lambda self,s ,li=[]:self.from_decimal(s//len(alp),li+[s%len(alp)]) if s else ''.join([alp[int(i)] for i in li[::-1]])
    return BinClass 

def create_number_class(alphabet):
    jinwei = len(alphabet)
    def str2dec(string : str) -> int:
        dec, base = 0, 1
        for dig in reversed(string):
            dec += base * alphabet.index(dig)
            base *= jinwei
        return dec
    def dec2str(dec : int) -> str:
        string = ''
        while 1:
            string += alphabet[dec % jinwei]
            dec = dec // jinwei
            if 0 is dec: return string[::-1]
    class number:
        def __init__(self, str_or_dec):
            if isinstance(str_or_dec, str):
                self.str = str_or_dec
                self.dec = str2dec(self.str)
            else:
                self.dec = str_or_dec
                self.str = dec2str(self.dec)
        def convert_to(self, _class):
            return _class(self.dec)
        def __str__(self):
            return self.str
        def __add__(self, x):
            return number(self.dec + x.dec)
        def __sub__(self, x):
            return number(self.dec - x.dec)
        def __mul__(self, x):
            return number(self.dec * x.dec)
        def __floordiv__(self, x):
            return number(self.dec // x.dec)
    return number

def create_number_class(alphabet):
    class C():
        alph = alphabet
        def __init__(self, num):
            self.n = sum(C.alph.find(num[i]) * len(C.alph)**(len(num) - i - 1) for i in range(len(num)))
        def __str__(self):
            return to_str(self.n, C.alph)
        def __add__(self, c):
            inst = C(to_str(self.n + c.n, C.alph))
            return inst
        def __sub__(self, c):
            inst = C(to_str(self.n - c.n, C.alph))
            return inst
        def __mul__(self, c):
            inst = C(to_str(self.n * c.n, C.alph))
            return inst
        def __floordiv__(self, c):
            inst = C(to_str(self.n // c.n, C.alph))
            return inst
        def convert_to(self, Cl):
            inst = Cl(to_str(self.n, Cl.alph))
            return inst
    return C

def to_str(k, alphabet):
    if k == 0:
        return alphabet[0]
    res = ''
    while k > 0:
        res = alphabet[k % len(alphabet)] + res
        k = k // len(alphabet)
    return res

def create_number_class(alphabet):
    n = len(alphabet)
    class C(int):
        def __new__(cls, s):
            return super().__new__(
                cls, sum(alphabet.index(c) * n**i for i, c in enumerate(s[::-1]))
            )
        
        def __str__(self):
            s = ""
            while self > 0:
                self, d = divmod(self, n)
                s = alphabet[d] + s
            return s or alphabet[0]
            
        for op in ['__add__', '__sub__', '__mul__', '__floordiv__']:
            locals()[op] = lambda self, other, op=op: int.__new__(type(self), getattr(int, op)(self, other))
            
        def convert_to(self, c):
            return int.__new__(c, self)
    return C

import copy
class NumClass:
    def __init__(self, alphabet):
        self.base = len(alphabet)
        self.alphabet = alphabet

    def set_value_str(self, value):
        self.str_value = value
        self.int_value = 0
        for c in value:
            self.int_value = self.int_value * self.base
            self.int_value += self.alphabet.index(c)
    
    def set_value_int(self, value):
        self.int_value = value
        self.str_value = ''
        while value > 0:
            self.str_value = self.alphabet[value % self.base] + self.str_value
            value = value // self.base
        if len(self.str_value) == 0:
            self.str_value = self.alphabet[0]
    def __str__(self):
        return self.str_value

def create_number_class(alphabet):
    def __init__(self, value = None):
        NumClass.__init__(self, alphabet)
        if value != None:
            self.set_value_str(value)
        else:
            self.set_value_int(0)
    
    def __add__(self, other):
        result = copy.deepcopy(self)
        result.set_value_int(self.int_value + other.int_value)
        return result
    
    def __sub__(self, other):
        result = copy.deepcopy(self)
        result.set_value_int(self.int_value - other.int_value)
        return result

    def __mul__(self, other):
        result = copy.deepcopy(self)
        result.set_value_int(self.int_value * other.int_value)
        return result

    def __floordiv__(self, other):
        result = copy.deepcopy(self)
        result.set_value_int(self.int_value // other.int_value)
        return result
    
    def convert_to(self, convert_type):
        ret = convert_type()
        ret.set_value_int(self.int_value)
        return ret

    newclass = type('NumClass' + str(len(alphabet)), (NumClass, ), 
    {"__init__":__init__, "__add__":__add__, "__sub__":__sub__, "__mul__":__mul__, "__floordiv__":__floordiv__, "convert_to":convert_to})
    return newclass

def create_number_class(alphabet):
    class Number():
        alph = alphabet
        def __init__(self, numb):
            if type(numb) == str:
                self.value = Number.conv(numb)
            else: self.value = numb
        
        def conv(n):
            base = len(Number.alph)
            r, m = 0, 1
            for i in range(1, len(n)+1):
                r += m * Number.alph.index(n[-i])
                m *= base
            return r
        
        def vnoc(nu):
            r = ''
            base = len(Number.alph)
            if nu == 0:
                return Number.alph[0]
            else:
                while nu > 0:
                    r += Number.alph[nu % base]
                    nu //= base
                return r[::-1]
        
        def convert_to(self, NumClass):
            return NumClass(self.value)
        
        def __add__(self, other):
            return Number(self.value + other.value)
        
        def __sub__(self, other):
            return Number(self.value - other.value)
        
        def __mul__(self, other):
            return Number(self.value * other.value)
        
        def __floordiv__(self, other):
            return Number(self.value // other.value)
        
        def __str__(self):
            return Number.vnoc(self.value)
        
    return Number

def create_number_class(alphabets):
    bases = len(alphabets)
    class numbers:
        base = bases
        alphabet = alphabets
        def __init__(self, num):
            self.value = num
            print((self.value, self.base, self.alphabet))
        def __add__(self, other):
            a = decimal(self.value, self.alphabet, self.base)
            b = decimal(other.value, other.alphabet, self.base)
            print((a, b))
            return numbers(to_base(a+b, self.base, self.alphabet))
        def __sub__(self, other):
            a = decimal(self.value, self.alphabet, self.base)
            b = decimal(other.value, other.alphabet, self.base)
            return numbers(to_base(a-b, self.base, self.alphabet))
        def __mul__(self, other):
            a = decimal(self.value, self.alphabet, self.base)
            b = decimal(other.value, other.alphabet, self.base)
            return numbers(to_base(a*b, self.base, self.alphabet))
        def __floordiv__(self, other):
            a = decimal(self.value, self.alphabet, self.base)
            b = decimal(other.value, other.alphabet, self.base)
            return numbers(to_base(a//b, self.base, self.alphabet))
        def __str__(self):
            return str(self.value)
        def convert_to(self, other):
            num = decimal(self.value, self.alphabet, self.base)
            num = to_base(num, other.base, other.alphabet)
            print(num)
            return numbers(num)
    return numbers

def to_base(num, base, alphabet):
    conv = []
    num = int(num)
    while num >= base:
        conv.append(alphabet[num%base])
        num = num//base
    conv.append(alphabet[num])
    conv.reverse()
    return "".join([str(i) for i in conv]) 

def decimal(num, alphabet, base):
    dec = list(num)
    new = list(range(0, len(alphabet)))
    for i in new:
        for x in range(0, len(dec)):
            if dec[x] == alphabet[i]:
                dec[x] = i
    print(dec)
    dec.reverse()
    decimal = 0
    for i, n in enumerate(dec):
        decimal += n * base**i
    print(decimal)
    return decimal