Skip to content

Instantly share code, notes, and snippets.

@zvoase
Created October 30, 2008 05:44
Show Gist options
  • Save zvoase/20925 to your computer and use it in GitHub Desktop.
Save zvoase/20925 to your computer and use it in GitHub Desktop.
import copy
class Base(object):
def __init__(self, words, name=''):
self.__words = words
if not name:
name = 'base%d' % (self.length,)
self.name = name
def __repr__(self):
return 'Base(%r, %r)' % (self.words, self.name)
def __get_words(self):
return self.__words
def __get_length(self):
return len(self.words)
def is_valid(self, values):
return set(values).issubset(set(self.words))
words = property(__get_words)
length = property(__get_length)
class Number(object):
def __init__(self, base, values=[]):
assert base.is_valid(values), (
'Invalid number for base %r: %r' % (base, values))
self.__base = base
self.__indices = map(self.base.words.index, values)
def __repr__(self):
return 'Number(%r, %r)' % (self.base.name, self.values)
def __str__(self):
if hasattr(self.base, 'format'):
return self.base.format(self)
return ''.join(map(str, self.values))
def zfill(self, length):
s = str(self)
if len(s) < length:
return ''.join(
self.base.words[0] for i in xrange(length - len(s))) + s
return s
@classmethod
def from_decimal(cls, base, decimal):
new = Number(DECIMAL, str(decimal))
new.base = base
return new
def __get_base(self):
return self.__base
def __set_base(self, base):
old_decimal = copy.copy(self.decimal)
self.__base = base
self.decimal = old_decimal
def __get_decimal(self):
decimal = 0
for index, value in enumerate(reversed(self.__indices)):
decimal += value * (self.base.length ** index)
return decimal
def __set_decimal(self, decimal):
indices = []
number = copy.copy(decimal)
while number:
indices.insert(0, number % self.base.length)
number = number // self.base.length
self.indices = indices
def __get_indices(self):
return self.__indices
def __set_indices(self, indices):
new_indices = []
for index in indices:
assert index < self.base.length, ('Invalid index for base %r: %r'
% (self.base, index))
new_indices.append(index)
self.__indices = new_indices
def __get_values(self):
return map(self.base.words.__getitem__, self.indices)
def __set_values(self, values):
self.__indices = map(self.base.words.index, values)
base = property(__get_base, __set_base)
decimal = property(__get_decimal, __set_decimal)
indices = property(__get_indices, __set_indices)
values = property(__get_values, __set_values)
DECIMAL = Base('0123456789', 'decimal')
BINARY = Base('01', 'binary')
BINARY.format = (
lambda n: '0b' + ''.join(map(str, n.values)))
HEXADECIMAL = Base('0123456789ABCDEF', 'hexadecimal')
HEXADECIMAL.format = (
lambda n: '0x' + ''.join(map(str, n.values)))
OCTAL = Base('01234567', 'octal')
OCTAL.format = (
lambda n: '0o' + ''.join(map(str, n.values)))
ALPHA_LOWER = Base('abcdefghijklmnopqrstuvwxyz', 'alpha_lower')
ALPHA_UPPER = Base('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'alpha_upper')
ALPHA = Base('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 'alpha')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment