## a bases converter

7 posts
I have re-written my python program to convert numbers from one base to another.
I was very pleased to learn the "enumerate()" function - thanks Blackjack for this!

I have now used this in my "to-denary" function and I think it is a lot better that my previous version.
I know this program could really do with some checking of input /error handling, but I am quite pleased with how it works so far ...
Code: Select all
`# bases.py - converts a base to another base.import mathdef to_denary(n, b, D):    """Converts to denary."""    denary = 0    for i in enumerate(reversed(n)):        temp = D.index(i[1])        denary += temp * math.pow(b, i[0])    return denarydef to_base(n, b, D):    """Converts n to base b."""    result = ""    while n != 0:        temp = int(n % b)        n //= b        result = D[temp] + result    return resultdef main():    DIGITS = "0123456789ABCDEF"    print("**** Base conversion ***")    base_a = input("Base of input:" )    while base_a != "":        base_a = int(base_a)        base_b = int(input("Base for output: "))        num = input("Number: ")        ans = to_base((to_denary(num, base_a, DIGITS)), base_b, DIGITS)        print("The base", base_a, "number", num, "in base", base_b, "is", ans)        base_a = input("Base of input:" )        # call mainmain()                  `

At some point I want to make a GUI version.
Here's a sample run:
bases.png (34.23 KiB) Viewed 786 times
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
I've realised that my enumerate would be nicer like this;
Code: Select all
`def to_denary(n, b, D):    """Converts to denary."""    denary = 0    for (i, digit)  in enumerate(reversed(n)):        temp = D.index(digit)        denary += temp * math.pow(b, i)    return denary`

Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
@antiloquax: The name `to_denary()` is misleading. The function converts a string into an integer. A number itself does not have a base at all, it is only representations of a number as a string that have a base. There is nothing ten-based about an `int`. If at all one could say it is base two as most likely that is what the internal representation in memory is based on. Although it does not have to be — it is an implementation detail.

`math.pow()` operates on `float`\s, so the arguments are converted to `float` and the result is also a `float`. That is unnecessary here and with really big inputs `denary` might get to big for a `float` and the result becomes inexact.

There is a `pow()` function in the builtin namespace which operates on arbitrarily large integers. But I would simply use the power operator ``**`` unless the third argument of the builtin `pow()` is needed.

As that power value might become quite large for inputs with many digits an alternative algorithm which just needs one multiplication and one addition per loop iteration could be used:
Code: Select all
`def to_int(digits, base, allowed_digits):    result = 0    for digit in digits:        result = (result * base) + allowed_digits.index(digit)    return result`

The function lacks some error checking. And the more simple way would be to use the builtin `int()` function which takes an optional base as second argument. Bases up to 36 are possible.

`to_base()` could make use of the `divmod()` function.

Building strings by repeatedly concatenating parts is potentially inefficient because strings are immutable. A more idiomatic approach would be collecting the substrings in a list and joining them at the end.

The function also has a problem with converting the input value 0. Currently it returns an empty string instead of '0'.
Code: Select all
`def to_base(number, base, allowed_digits):    result = list()    while number:        number, index = divmod(number, base)        result.append(allowed_digits[index])    return ''.join(reversed(result)) if result else allowed_digits[0]`
Code: Select all
`while not self.asleep():    sheep += 1`
Posts: 288
Joined: Sat Aug 04, 2012 8:28 am
Thanks BlackJack, I'll take another look and do some re-writing!
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
antiloquax wrote:I have re-written my python program to convert numbers from one base to another...

Well done!

I'm a bit old now but not so old that I don't remember the enjoyment I got from writing my own code to convert between bases.

Posts: 7460
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK
Thanks Joan. I mainly started working on this as a result of trying to explain bases to my GCSE computing group and describing to them how to do the conversions.
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
@BlackJack. I was not aware of divmod() or "**". Those two things certainly helped me to improve my code.
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am