"""bases.py
Change of base functions
"""

def decimal(i):
    '''Return a string of decimal digits reprsenting the nonnegative integer i.
    Illustrates the repeated remainder and division algorithm.'''
    if i == 0:
        return "0"
    numeral = ""
    while i != 0:
        digit = i % 10
        numeral = str(digit) + numeral # add next digit on the LEFT
        i = i//10
    return numeral

def intToBaseList(i, base):
    """Return a list of coefficients for the expansion of i in powers of base,
    starting from the 0 power.

    >>> intToBaseList(235, 10) # 235 = 5 + 3*10 + 2*10**2
    [5, 3, 2]
    >>> intToBaseList(23, 2) # 23 = 1 + 1*2 + 1*2**2 + 0*2**3 + 1*2**4
    [1, 1, 1, 0, 1]
    """
    i = int(i)  # if i is a string, convert to int
    assert i >= 0, 'i must be nonnegative'
    assert base > 1, 'need base > 1'
    if i == 0:
        return [0]
    coef = []
    while i != 0:
        coef.append(i % base)
        i = i//base
    return coef

def baseListToInt(coefList, base):
    '''Return the sum of coefList[i]*base**i,
    the conversion back to a regular integer.

    >>> baseListToInt([5, 3, 2], 10)
    235
    >>> baseListToInt([1, 1, 1, 0, 1], 2)
    23
    '''
    tot = 0
    for c in reversed(coefList):
        tot = tot*base + c
    return tot
    
digitStr = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
def intToBase1(i, base):
    """Return a string representing the nonnegative integer i
    in the specified base, from 2 to 36.

    >>> intToBase(235, 10)
    '235'
    >>> intToBase(23, 2)
    '10111'
    >>> intToBase(254, 16)
    'FE'
    """
    coef = intToBaseList(i, base)
    coef.reverse() # handy for lists! .reverse(): in place, nothing returned
    numeral = ""
    for a in coef:
        numeral += digitStr[a]  
    return numeral

def intToBase(i, base):  # more concise version with list comprehension
    """Return a string representing the nonnegative integer i
    in the specified base, from 2 to 36.

    >>> intToBase(235, 10)
    '235'
    >>> intToBase(23, 2)
    '10111'
    >>> intToBase(254, 16)
    'FE'
    """
    coef = intToBaseList(i, base)   # reversed(seq):  reversed seq returned
    digitChar = [digitStr[x] for x in reversed(coef)] # list comprehension
    return "".join(digitChar)
    #sepStr.join(strSeq) join elements of strSeq with sepStr interleaved

if __name__ == '__main__': 
    import doctest
    doctest.testmod() #verbose=True) 
