'''An extensible framework for simulated bottle buying, putting away, taking down, and drinking. ''' import sys def vernacularFilter(f): '''Let's say "no more" instead of "zero" ''' def _f(*args, **kw): word = f(*args, **kw) if word == 'zero': return 'no more' return word return _f class LanguageTranslationError(Exception): pass class NumToLanguageTranslator: '''Translate integers to spoken words, for various locales. ''' DEFAULT_LOCALE = 'en-US' def __init__(self, locale=DEFAULT_LOCALE): self.translate = getattr(self, 'translate_%s' % locale.lower().replace('-','_')) if not self.translate: raise LanguageTranslationError, \ "Missing locale translation tables for numeric values" # en-US section. More to follow EN_US_SINGLETON = { 0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten', 11: 'eleven', 12: 'twelve', 20: 'twenty', 30: 'thirty', 40: 'fourty', 50: 'fifty', 60: 'sixty', 70: 'seventy', 80: 'eighty', 90: 'ninety', } EN_US_TEENS = (13,20) EN_US_TEEN_SPECIAL_PFX = { 3: 'thir', 4: 'four', 5: 'fif', 8: 'eigh', } EN_US_RANGE = (0, 100) EN_US_TEEN_SFX = 'teen' @vernacularFilter def translate_en_us(self, num): '''Translations for en-US; currently only 0-99 are supported. That should be enough bottles for anyone. ''' if num not in range(*self.EN_US_RANGE): raise LanguageTranslationError, \ "Cannot tranlsate: number out of range" if num in self.EN_US_SINGLETON: return self.EN_US_SINGLETON[num] remainder = num % 10 if num in range(*self.EN_US_TEENS): return '%s%s' % ( self.EN_US_TEEN_SPECIAL_PFX.get(remainder, self.EN_US_SINGLETON[remainder]), self.EN_US_TEEN_SFX) return '%s-%s' % (self.EN_US_SINGLETON[num / 10 * 10],