Last active
April 12, 2024 13:13
-
-
Save ZCG-coder/174817cfb7150a8a3f3c5e8103ebe943 to your computer and use it in GitHub Desktop.
Python script to convert decimals to any bases and back
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
NAMES = { | |
2: "binary", | |
3: "trinary", | |
4: "quaternary", | |
8: "octadecimal", | |
10: "decimal", | |
16: "hexadecimal" | |
} | |
def _get_name(base: int) -> str: | |
name = "" | |
if base in NAMES.keys(): | |
name = NAMES[base] | |
if base < 0: | |
name = f"nega{name}" | |
return name | |
name = f"base-{'negative-' if base < 0 else ''}{abs(base)}" | |
return name | |
def _convert_to_base(number: int, base: int, print_steps: bool = True) -> str: | |
if abs(base) == 1 or base == 0: | |
print("Conversion impossible") | |
return "E" | |
if number == 0: | |
return "0" | |
digits = [] | |
lhs_length = 0 | |
rhs_length = 0 | |
if print_steps: | |
print( | |
f"We're converting {number} to {_get_name(base)}:" | |
) | |
while number != 0: | |
quotient, rem = divmod(number, base) | |
if rem < 0: | |
rem += abs(base) | |
quotient += 1 | |
rem_final = str(rem) | |
if rem > 9: # Represent properly | |
orig_rem = rem | |
rem = chr(65 + rem - 10) | |
if not rem.isupper(): | |
print("Error: Cannot represent remainder. Please try another number.") | |
return "E" | |
rem_final = f"{orig_rem} ({rem})" | |
lhs = f"{number} \u00F7 {base}" | |
rhs = str(quotient) | |
# Print the step | |
if print_steps: | |
if not lhs_length or rhs_length: | |
lhs_length = len(lhs) + 2 | |
rhs_length = len(rhs) + 2 | |
rem_length = len(str(base)) + 2 | |
print( | |
f"{lhs:>{lhs_length}} = {rhs:>{rhs_length}} ...{rem_final:<{rem_length}}" | |
) | |
digits.append(str(rem)) | |
number = quotient | |
return "".join(digits[::-1]) | |
def _convert_to_decimal(number: str, base: int): | |
result = 0 | |
lhs_length = 0 | |
rhs_length = 0 | |
for index, digit in enumerate(reversed(number)): | |
place = 0 | |
if digit.isdigit(): | |
place = int(digit) | |
else: | |
digit = digit.upper() | |
place = ord(digit) - 65 + 10 | |
if place > base: | |
print() | |
value = place * base ** index | |
lhs = f"Place {index + 1}" | |
rhs = f"{place} * {base} ^ {index}" | |
if not lhs_length or rhs_length: | |
lhs_length = len(lhs) + 2 | |
rhs_length = len(rhs) + 2 | |
print(f"{lhs:<{lhs_length}} = {rhs:>{rhs_length}}") | |
result += value | |
return result | |
def convert_to_base(): | |
number, base = "", "" | |
while True: | |
number = input("Number to Convert: ") | |
base = input("Base : ") | |
try: | |
number, base = int(number), int(base) | |
break | |
except ValueError: | |
continue | |
result = _convert_to_base(number, base) | |
result_str = ( | |
f"{number} in {_get_name(base)} is {result}" | |
) | |
print() | |
print(result_str) | |
print(f'{"^" * (len(str(result))):>{len(result_str)}}') # Squiggles | |
def convert_to_decimal(): | |
number, base = "", "" | |
while True: | |
number = input("Number to Convert: ") | |
base = input("Base : ") | |
try: | |
base = int(base) | |
break | |
except ValueError: | |
continue | |
result = _convert_to_decimal(number, base) | |
result_str = ( | |
f"{number} in {_get_name(base)} is {result}" | |
) | |
print() | |
print(result_str) | |
print(f'{"^" * (len(str(result))):>{len(result_str)}}') # Squiggles | |
if __name__ == "__main__": | |
choice = "" | |
while True: | |
choice = input("""\ | |
Convertion | |
========================== | |
A) Convert to any base | |
B) Convert to decimal | |
Q) Quit | |
> \ | |
""") | |
choice = choice.upper() | |
match choice: | |
case "A": | |
convert_to_base() | |
case "B": | |
convert_to_decimal() | |
case "Q": | |
exit() | |
case _: | |
print("Error: Try again") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment