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.

Source: codewars | Difficulty: MEDIUM
Tags: Mathematics

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