I felt it would be helpful to folks interested in Python and studying algorithms, to review some commonly studied algorithms in Computer Science by providing a small description and a Python implementation of each algorithm.
This week, we’ll cover an introductory algorithm for converting from one numeral base to another. Here is the python code:
"""Simple implementation of a base expansion algorithm""" import math def base_expand(base, val): """This simple function performs a base-expansion from decimal using moduli and a translation table. The translation table is a clear limitation here, in that it implies the maximum base is 36.""" if (base < 2) or (base > 36): raise BaseOutOfBoundsError(base) trans_table = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' res = '' while val != 0: res += trans_table[(int(val % base))] val = math.floor(val / base) return res[::-1] class BaseOutOfBoundsError(Exception): """Base must be between 2 and 36""" def __init__(self, val): self.val = val def __str__(self): print "\nInvalid base: %s. Base must be (x | x > 1; x < 37)" % \ self.val |
Here is a unit-test for base_expand.py:
"""Unit tests for base_expansion.py""" import unittest from base_expansion import base_expand, BaseOutOfBoundsError # Unit tests for base_expansion.py class TestVals(unittest.TestCase): """Test suite""" def test_known_values(self): """Testing against known values""" vals = [{'val': 8, 'base': 2, 'expect': '1000'}, {'val': 915652, 'base': 16, 'expect': 'DF8C4'}, {'val': 256, 'base': 10, 'expect': '256'}, {'val': 88189, 'base': 8, 'expect': '254175'}] for val in vals: self.assertEqual(val['expect'], \ base_expand(val['base'], val['val'])) def test_invalid_base(self): """ Testing invalid bases """ bases = [1, 37, 50, 100] for base in bases: self.assertRaises(BaseOutOfBoundsError, base_expand, \ base, 1) if '__main__' == __name__: unittest.main() |
Related posts:
from math import *
def baseExpansion(n,c,b):
….j = 0
….base10 = sum([pow(c,len(n)-k-1)*n[k] for k in range(0,len(n))])
….while floor(base10/pow(b,j)) != 0: j = j+1
…..return [floor(base10/pow(b,j-p)) % b for p in range(1,j+1)]
This algorithm although it might be a bit longer, runs without bounds on integer bases. The input is a list and so is the output as to accommodate for larger bases.