from functools import cache
from functools import lru_cache
from functools import partial
from functools import wraps
import builtins
class Converter:
class Utils:
@staticmethod
def _lookupBasePrefix(base):
if base == 8: return '0'
elif base == 0x10: return '0x'
elif base == 2: return '0b'
return ''
@staticmethod
def _check_base(n, base):
if base <= 0 or base > 36:
raise Exception("Base %s is not a valid base" % (base))
minus = True if n < 0 else False
return minus
# idea: singleton is a cached "instance" ! multi-threaded !? :/ .
# .. is this working !? :/
@cache
def __init__(self, base):
self.__p = partial(lambda n: Converter.asString(n, base))
def __call__(self, n):
return self.__p(n)
# lru_cache should be used,
# ... to optimize a bit ... !? :( - we try it, we'd have to "tweak it" :Ooo
@staticmethod
def _asString_naive(n, base):
x = ''
while True:
cipher = n % base
y = str(cipher) if cipher < 10 else chr(ord('a') + cipher - 10)
(x, n) = (y + x, int(n / base))
if (n == 0): break
return x
@staticmethod
@lru_cache
def asString(n, base = 10):
minus = Converter.Utils._check_base(n, base)
if minus == True: n = -n
x = Converter.Utils._lookupBasePrefix(base) \
+ Converter._asString_naive(n, base)
if minus: x = '-' + x
return x
# here's a simple trick as to "transform".. resulting "strings" into a "chars tuple" .
def tuple(func):
@wraps(func)
def wrapper(*args, **kwds):
return builtins.tuple( func(*args, **kwds) )
return wrapper
# here we get some shortcuts - and we split the "strings"
@staticmethod
@tuple
def bits(n):
return Converter(2)(n)
@staticmethod
@tuple
def octals(n):
return Converter(8)(n)
@staticmethod
@tuple
def hexed(n):
return Converter(16)(n)
@staticmethod
@tuple
def base_10(n):
return Converter(10)(n)
# global level shorcuts with "nice names" ..
def static_into_globals(method, into = None):
if into == None:
into = method.__name__
globals()[into] = method
static_into_globals(Converter.bits)
static_into_globals(Converter.octals)
static_into_globals(Converter.hexed)
static_into_globals(Converter.base_10)
# no need, for a main section, to verify at module load !?
__join = lambda t: "".join(t) # a very neat util, to print a tuple into a ""-sep-string
print(bits(-20))
print(octals(10))
print(hexed(40))
print(base_10(-123456789))