## a bases converter

antiloquax
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
Contact: Website

### a bases converter

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 math

def 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 denary

def 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 result

def 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 main
main()
``````
At some point I want to make a GUI version.
Here's a sample run:
bases.png (34.23 KiB) Viewed 1003 times

antiloquax
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
Contact: Website

### Re: a bases converter

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``````

BlackJack
Posts: 288
Joined: Sat Aug 04, 2012 8:28 am
Contact: Website

### Re: a bases converter

@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``````

antiloquax
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
Contact: Website

### Re: a bases converter

Thanks BlackJack, I'll take another look and do some re-writing!

joan
Posts: 12738
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

### Re: a bases converter

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.

antiloquax
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
Contact: Website

### Re: a bases converter

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.

antiloquax
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
Contact: Website

### Re: a bases converter

@BlackJack. I was not aware of divmod() or "**". Those two things certainly helped me to improve my code.