Skip to content

Instantly share code, notes, and snippets.

@timeopochin
Last active May 2, 2021 23:58
Show Gist options
  • Save timeopochin/cffef82b3f659b937bd8a1c5acc58a04 to your computer and use it in GitHub Desktop.
Save timeopochin/cffef82b3f659b937bd8a1c5acc58a04 to your computer and use it in GitHub Desktop.
A Dozenal Reverse Polish Calculator
# A reverse polish calculator for the dozenal system
def dozToDec(doz):
dozenal = None
if '.' in doz:
doz, dozenal = doz.split('.')
sum = 0
for i in range(len(doz)):
addition = DOZ_DIGITS.index(doz[len(doz) - i - 1])
for _ in range(i):
addition *= 12
sum += addition
if dozenal:
for i in range(len(dozenal)):
addition = DOZ_DIGITS.index(dozenal[i])
for _ in range(i + 1):
addition /= 12
sum += addition
return sum
def decimalToDoz(decimal):
doz = ""
for i in range(DPRCSN):
doz += DOZ_DIGITS[int(decimal*12)]
decimal = decimal*12 % 1
if decimal < 1/(10**(DPRCSN - i)):
break
return doz
def decToDoz(dec):
if type(dec) == complex:
real = decToDoz(dec.real)
imag = decToDoz(dec.imag)
return real + ' ' + imag + " i * +"
decimal = None
if dec % 1:
decimal = dec % 1
dec = int(dec)
doz = ""
while dec > 0:
doz = DOZ_DIGITS[dec % 12] + doz
dec //= 12
if decimal:
doz += '.' + decimalToDoz(decimal)
elif doz == "":
doz = "0"
return doz
def splitExpr(expr):
split = []
num = ""
for char in expr:
if char in DOZ_DIGITS or (char == '.' and '.' not in num):
num += char
elif char in OPS + COMMANDS:
if len(num) > 0:
split.append(num)
num = ""
split.append(char)
elif char == ' ':
if len(num) > 0:
split.append(num)
num = ""
else:
print("Error: `{}` is not a valid syntax".format(char))
return []
if num:
split.append(num)
return split
def processExpr(stack, expr):
for item in splitExpr(expr):
if item in COMMANDS:
if item in "pd":
if len(stack) == 0:
print("Stack is empty")
elif item == 'p':
print(decToDoz(stack[-1]))
elif item == 'd':
print("{} ({})".format(decToDoz(stack[-1]), stack[-1]))
elif item == 'c':
stack.clear()
clearScreen()
elif item == 'q':
exit()
elif item in OPS:
if len(stack) < 2:
print("Not enough items in the stack: ignoring `{}`".format(item))
else:
second = stack.pop()
first = stack[-1]
if item == '+':
result = first + second
elif item == '-':
result = first - second
elif item == '*':
result = first*second
elif item == '/':
result = first/second
elif item == '^':
result = first**second
stack[-1] = result
else:
stack.append(dozToDec(item))
def clearScreen():
print("\x1b[2J\x1b[1;1H")
DPRCSN = 12
DOZ_DIGITS = "0123456789XE"
OPS = "+-*/^"
COMMANDS = "pdcq"
# TODO: implement constants
CONSTS = {
"$pi": 3.141592653589793,
"$e": 2.718281828459045
}
if __name__ == "__main__":
stack = []
while True:
expr = input()
processExpr(stack, expr)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment