0

Greetings everyone. I have been working on a script to convert a number from any base to any base up to base62. The user supplies the original number, the starting base, and the end base. My problem arises when converting the fractional part from base10 to the end base; the script returns an empty string and for the life of me I cannot figure out how to fix it. Any help or advice is greatly appreciated. Code follows.

myinput = raw_input("Number: ")
mystart = int(raw_input("Starting base: "))
myend = int(raw_input("Ending base: "))
intlist = []
fraclist = []
intresult = ""
fracresult = ""
mydict1 = {"A" : 10, "B" : 11, "C" : 12, "D" : 13, "E" : 14, "F" : 15, "G" : 16,
         "H" : 17, "I" : 18, "J" : 19, "K" : 20, "L" : 21, "M" : 22, "N" : 23,
         "O" : 24, "P" : 25, "Q" : 26, "R" : 27, "S" : 28, "T" : 29, "U" : 30,
         "V" : 31, "W" : 32, "X" : 33, "Y" : 34, "Z" : 35, "a" : 36, "b" : 37,
         "c" : 38, "d" : 39, "e" : 40, "f" : 41, "g" : 42, "h" : 43, "i" : 44,
         "j" : 45, "k" : 46, "l" : 47, "m" : 48, "n" : 49, "o" : 50, "p" : 51,
         "q" : 52, "r" : 53, "s" : 54, "t" : 55, "u" : 56, "v" : 57, "w" : 58,
         "x" : 59, "y" : 60, "z" : 61}
mydict2 = {10 : "A", 11 : "B", 12 : "C", 13 : "D", 14 : "E", 15 : "F", 16 : "G",
           17 : "H", 18 : "I", 19 : "J", 20 : "K", 21 : "L", 22 : "M", 23 : "N",
           24 : "O", 25 : "P", 26 : "Q", 27 : "R", 28 : "S", 29 : "T", 30 : "U",
           31 : "V", 32 : "W", 33 : "X", 34 : "Y", 35 : "Z", 36 : "a", 37 : "b",
           38 : "c", 39 : "d", 40 : "e", 41 : "f", 42 : "g", 43 : "h", 44 : "i",
           45 : "j", 46 : "k", 47 : "l", 48 : "m", 49 : "n", 50 : "o", 51 : "p",
           52 : "q", 53 : "r", 54 : "s", 55 : "t", 56 : "u", 57 : "v", 58 : "w",
           59 : "x", 60 : "y", 61 : "z"}
#need to create another yes/no loop so user can continue/quit
if myinput.count(".") == 1:
    (a, b) = myinput.split(".")
    for x in a:
        if x in mydict1:
            x = mydict1[x]
            intlist.append(x)
        else:
            intlist.append(int(x))
    f = 0    
    g = len(intlist)
    while f < (g - 1):
        if f == 0:
            decint = (intlist[0] * mystart) + intlist[1]
        else:
            decint = (decint * mystart) + intlist[f + 1]
        f = f + 1 
    while decint > 0:
        endint = decint % myend
        if endint > 9:
            endint = mydict2[endint]
            intresult = endint + intresult
        else:
            intresult = str(endint) + intresult
        decint = decint / myend
    for x in b:
        if x in mydict1:
            x = mydict1[x]
            fraclist.append(int(x))
        else:
            fraclist.append(x)
    z = 1
    decfrac = int(fraclist[-1])
    w = len(fraclist)
    while z <= w:
        if z == w:
            n = 0
        else:
            n = int(fraclist[-1 - z])
        decfrac = (decfrac * mystart) + n
        z = z + 1    
    if len(str(decfrac)) > 10:
        decfrac = decfrac[:11]
    decfrac = decfrac / (10 ** (len(str(decfrac))))
    while decfrac < 1 and decfrac > 0:
        decfrac = decfrac * myend
        s = decfrac // 1
        if s > 9:
            s = mydict2[s]
            fracresult = fracresult + s
        else:
            fracresult = fracresult + str(s)
        decfrac = decfrac - s
elif myinput.count(".") == 0:  
    for x in myinput:
        if x in mydict1:
            x = mydict1[x]
            intlist.append(x)
        else:
            intlist.append(int(x))
    f = 0    
    g = len(intlist)
    while f < (g - 1):
        if f == 0:
            decint = (intlist[0] * mystart) + intlist[1]
        else:
            decint = (decint * mystart) + intlist[f + 1]
        f = f + 1 
    while decint > 0:
        endint = decint % myend
        if endint > 9:
            endint = mydict2[endint]
            intresult = endint + intresult
        else:
            intresult = str(endint) + intresult
        decint = decint / myend
else:
    print "There is an error in the syntax of your input.  The program will now end."

P.S. The variable names for the result strings are intresult and fracresult respectively. Thanks again.

2
Contributors
1
Reply
3
Views
9 Years
Discussion Span
Last Post by jrcagle
0

Hi. A couple of suggestions.

(1) (minor) mydict2 should be generated dynamically from mydict1 so that if you ever decide to change mydict1, it will automagically change along with it.

Here's how. Replace the entirety of mydict2 with this line:

mydict2 = dict(zip(mydict1.values, mydict1.keys))

This will make a bunch of tuple pairs out of the values and keys from mydict1, and then create a dictionary from them. The order is guaranteed to match according to the Python docs.

(2) Add the digits '0' - '9' to your dictionary. That way, you won't have to have separate conditionals to check for digits v. letters. Remember that both "letters" and "digits" are intended to be just "digits" in whatever base.

(3) You've written code that decodes the number from one base and simultaneously encodes it into another base. That's trying to do too much at once.

Instead, write two separate functions:

from_base(string, base)
to_base(value, base)

from_base will convert the string into a number; to_base will convert the number into a string.

Solving each of those problems is a shorter task and much easier to debug.

(4) The code for converting the fractional part is too complicated. In particular, resorting to the fraclist is not necessary, because can compute the result in place.

I've rewritten that little part below, along with putting in (1) and (2). It will help you greatly to walk through the process of writing functions for (3).

Hope it helps!

myinput = raw_input("Number: ")
mystart = int(raw_input("Starting base: "))
myend = int(raw_input("Ending base: "))
intlist = []
fraclist = []
intresult = ""
fracresult = ""
mydict1 = {"0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7":7,
         "8": 8, "9": 9,
         "A" : 10, "B" : 11, "C" : 12, "D" : 13, "E" : 14, "F" : 15, "G" : 16,
         "H" : 17, "I" : 18, "J" : 19, "K" : 20, "L" : 21, "M" : 22, "N" : 23,
         "O" : 24, "P" : 25, "Q" : 26, "R" : 27, "S" : 28, "T" : 29, "U" : 30,
         "V" : 31, "W" : 32, "X" : 33, "Y" : 34, "Z" : 35, "a" : 36, "b" : 37,
         "c" : 38, "d" : 39, "e" : 40, "f" : 41, "g" : 42, "h" : 43, "i" : 44,
         "j" : 45, "k" : 46, "l" : 47, "m" : 48, "n" : 49, "o" : 50, "p" : 51,
         "q" : 52, "r" : 53, "s" : 54, "t" : 55, "u" : 56, "v" : 57, "w" : 58,
         "x" : 59, "y" : 60, "z" : 61}
# do this dynamically:

mydict2 = dict(zip(mydict1.values(), mydict1.keys()))

intresult = fracresult = ""
#need to create another yes/no loop so user can continue/quit
if myinput.count(".") == 1:
    (a, b) = myinput.split(".")
    for x in a:
        if x in mydict1:
            x = mydict1[x]
            intlist.append(x)
        else:
            intlist.append(int(x))
    f = 0    
    g = len(intlist)
    while f < (g - 1):
        if f == 0:
            decint = (intlist[0] * mystart) + intlist[1]
        else:
            decint = (decint * mystart) + intlist[f + 1]
        f = f + 1 
    while decint > 0:
        endint = decint % myend
        if endint > 9:
            endint = mydict2[endint]
            intresult = endint + intresult
        else:
            intresult = str(endint) + intresult
        decint = decint / myend

    fracp = 0.0
    placevalue = 1./mystart
    for i in range(len(b)):     # walk down the digits of b
        fracp += mydict1[b] * placevalue 
        placevalue /= mystart   # progressively reduce the placevalue

    fracresult = ""
    while fracp:
        fracp *= myend  # shift fracp up one place in base myend
        remainder = int(fracp)
        fracp %= 1      # finds the decimal part of fracp
        fracresult += mydict2[remainder]
        
elif myinput.count(".") == 0:
    for x in myinput:
        if x in mydict1:
            x = mydict1[x]
            intlist.append(x)
        else:
            intlist.append(int(x))
    f = 0    
    g = len(intlist)
    while f < (g - 1):
        if f == 0:
            decint = (intlist[0] * mystart) + intlist[1]
        else:
            decint = (decint * mystart) + intlist[f + 1]
        f = f + 1 
    while decint > 0:
        endint = decint % myend
        if endint > 9:
            endint = mydict2[endint]
            intresult = endint + intresult
        else:
            intresult = str(endint) + intresult
        decint = decint / myend
else:
    print "There is an error in the syntax of your input.  The program will now end."

if fracresult:
    print intresult + "." + fracresult
elif intresult:
    print intresult
This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.