I want o create a calculator that can add (and multiply, divide, etc) numbers in base 12 and with different limits at the different digits.
Base 12 sequence: [0,1,2,3,4,5,6,7,8,9,"A","B"]
The limits must be:
First digit: limit "B"
Second digit: limit 4
Third digit: limit "B"
(The idea would be that it follows the hourly System limits but in base 12 so for example in base 12 there are 50 seconds in a minute)
That means you would count like this:[1,2,3,4,5,6,7,8,9,A,B,10,11,...48,49,4A,4B,100,101,...14B,200,201,...B4B,1000,1001..]
So I made the following code
import string
digs = string.digits + string.ascii_uppercasedef converter(number):#split number in figuresfigures = [int(i,12) for i in str(number)]#invert oder of figures (lowest count first)figures = figures[::-1]result = 0#loop over all figuresfor i in range(len(figures)):#add the contirbution of the i-th figureresult += figures[i]*12**ireturn resultdef int2base(x):if x < 0:sign = -1elif x == 0:return digs[0]else:sign = 1x *= signdigits = []while x:digits.append(digs[int(x % 12)])x = int(x / 12)if sign < 0:digits.append('-')digits.reverse()return ''.join(digits)def calculator (entry1, operation, entry2):value1=float(converter(entry1))value2=float(converter(entry2))if operation == "suma" or "+":resultvalue=value1+value2else:print("operación no encontrada, porfavor ingrese +,-,")result=int2base(resultvalue)return resultprint(calculator(input("Ingrese primer valor"), input("ingrese operación"), input("Ingrese segundo valor")))
The thing is that I dont know how to establish the limits to the different digits
If someone could help me I would be extreamly greatful
You can define two converters:
class Base12Convert:d = {hex(te)[2:].upper():te for te in range(0,12)}d.update({val:key for key,val in d.items()})d["-"] = "-"@staticmethoddef text_to_int(text):"""Converts a base-12 text into an int."""if not isinstance(text,str):raise ValueError(f"Only strings allowed: '{text}' of type '{type(text)}' is invalid")t = text.strip().upper()if any (x not in Base12Convert.d for x in t):raise ValueError(f"Only [-0123456789abAB] allowed in string: '{t}' is invalid") if "-" in t.lstrip("-"):raise ValueError(f"Sign '-' only allowed in front. '{t}' is invalid")# easy wayreturn int(t,12)# self-calculated way# return sum(Base12Convert.d[num]*12**idx for idx,num in enumerate(t[::-1]))@staticmethoddef int_to_text(num):"""Converts an int into a base-12 string."""sign = ""if not isinstance(num,int):raise ValueError(f"Only integer as input allowed: '{num} of type {type(num)}' is invalid")if num < 0:sign = "-"num *= -1# get highest possible numberp = 1while p < num:p *= 12# create string rv = [sign]while True:p /= 12div = num // pnum -= div*prv.append(Base12Convert.d[div])if p == 1:breakreturn ''.join(rv)
Then you can use them to convert what you want:
text = "14:54:31" # some time # convert each int of the time into base12 - join with | again
base12 = '|'.join(Base12Convert.int_to_text (int(t)) for t in text.split(":"))# split base12 at |, convert to int, make str from int and join with | again
base10 = '|'.join(map(str,(Base12Convert.text_to_int (b12) for b12 in base12.split("|"))))# print all 3
print(text,base12,base10,sep="\n")
Output:
14:54:31
12|46|27
14|54|31
and enforce whatever restrictions you have on your "digits" using normal ints. You should split up your "digits" of a clock ... 14b
(203 in base 10) does not make sense, 1:4b
might if you mean 1:59 hours/minutes.