solution_147.py

#!/usr/bin/python3
# --------------------------------------------------------------------
# convert a number to a different base (positive integers only)
# do not us any math modules - break it down yourself
# --------------------------------------------------------------------

import sys
import user_interface as ui


DIGITS = '0123456789abcdef'     # digit characters


# --------------------------------------------------------------------
# ---- convert a number string to an integer
# ---- base      number string's base (integer)
# ---- num_str   number string
# ---- return integer
# --------------------------------------------------------------------

def convert_string_to_integer(base,num_str):

    digits = DIGITS[:base]

    num_int = 0                  # intial numeric value

    for char in num_str.lower(): # for each character in the string

        idx = digits.find(char)
        
        if idx < 0:
            print()
            print(f'illegal number string character ({char})')
            return (False,0)

        num_int = num_int * base + idx

    return (True,num_int)


# --------------------------------------------------------------------
# ---- convert an integer to a string of a given base
# ---- base      output base (integer)
# ---- num_int   integer
# ---- return a string
# --------------------------------------------------------------------

def convert_integer_to_string(base,num_int):

    digits = DIGITS[:base]

    num_str = ''

    while num_int > 0:

        ##print(f'num_int={num_int} base={base}')

        char = digits[num_int % base]
        
        idx = digits.find(char)

        if idx < 0:
            print()
            print(f'illegal number string character ({char})')
            return (False,0)

        num_str = digits[idx] + num_str

        num_int = int(num_int/base)

    return (True,num_str)
    

# --------------------------------------------------------------------
# ---- ask the user for the output base
# ---- return the number as a string (in the selected base)
# --------------------------------------------------------------------

def get_integer_string_value(num_int):

    while True:

        print()
        base_str = ui.get_user_input('Enter output base: ')

        if not base_str: sys.exit()  # empty string?

        tf,base = ui.is_integer(base_str)

        if not tf:
            print('unknown or bad base entered ({base})')
            continue

        # --- verify base

        if base < 2 or base > len(DIGITS):
            print()
            print(f'illegal base entered ({base})')
            continue

        break

    return convert_integer_to_string(base,num_int)


# --------------------------------------------------------------------
# ---- ask the user for the input base and number (string)
# ---- return the number's value
# --------------------------------------------------------------------

def get_string_integer_value():

    # ---- ask the user for the input number's base

    while True:
        
        print()
        base_str = ui.get_user_input('Enter input base: ')

        if not base_str: sys.exit()  # empty string?

        tf,base = ui.is_integer(base_str)

        if not tf:
            print('unknown or bad base entered ({base})')
            continue

        # --- verify the base

        if base < 2 or base > len(DIGITS):
            print()
            print(f'illegal base entered ({base})')
            continue

        break

    # ---- ask the user for the input number (string)

    print()
    num_str = ui.get_user_input('Enter input number: ')

    if not num_str: sys.exit()

    # ---- return string's numeric value

    return convert_string_to_integer(base,num_str)


# --------------------------------------------------------------------
# ---- main
# --------------------------------------------------------------------

if __name__ == '__main__':

    while True:        

        tf,num_int = get_string_integer_value()

        if not tf: continue

        print()
        print(f'integer\'s base 10 value is {num_int}')

        tf,num_str = get_integer_string_value(num_int)

        if not tf: continue

        print()
        print(f'integer\'s string value is {num_str}')