number2words

import re


class number_to_words(object):

    def __init__(self, number):

        self.words_dict = {
            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', 13: 'thirteen',
            14: 'fourteen', 15: 'fifteen', 16: 'sixteen', 17: 'seventeen',
            18: 'eighteen', 19: 'nineteen', 20: 'twenty', 30: 'thirty', 40: 'forty',
            50: 'fifty', 60: 'sixty', 70: 'seventy', 80: 'eighty', 90: 'ninty'
        }

        self.power_list = ['thousand', 'lakh', 'crore']

        self.number = number

    def convert(self):
        judge_minus, number = self.convert_minus(self.number)
        result = self.check_point_number(number)
        if judge_minus:
            return "minus " + result
        return result

    @staticmethod
    def _validate_number(number):

        # Only works till 999999999
        if number > 999999999 or number < 0:
            raise AssertionError('Out Of range')

    @staticmethod
    def convert_minus(number):
        if "-" in number:
            convert_number = number[1:]
            return True, convert_number
        return False, number

    # 只有小數傳過來時進行轉換,其餘格式的直接返回數字
    def check_point_number(self, number):
        if "." in number:
            number_words_list = []
            number_list = number.split(".")
            integer_number = number_list[0]
            self._validate_number(int(integer_number))
            decimals_number = re.search(r'(\d*[1-9])0*$', number_list[-1])
            integer_en = self._convert_to_words(integer_number)
            number_words_list.append(integer_en)
            if decimals_number is not None:
                number_words_list.append("point")
                for decimals in decimals_number.group(1):
                    decimals_en = self._convert_to_words(decimals)
                    number_words_list.append(decimals_en)
            return " ".join(number_words_list)
        return number

    def _convert_to_words(self, number):

        msbs, hundreds, tens = self._group_numbers(number)

        words_list = self._group_to_numbers(msbs, hundreds, tens)

        return ' '.join(words_list)

    @staticmethod
    def _group_numbers(number):
        str_number = str(number)

        hundreds, tens = str_number[-3:-2], str_number[-2:]

        msbs_temp = list(str_number[:-3])

        msbs = []

        str_temp = ''

        for num in msbs_temp[::-1]:

            str_temp = '%s%s' % (num, str_temp)

            if len(str_temp) == 2:

                msbs.insert(0, str_temp)

                str_temp = ''

        if str_temp:

            msbs.insert(0, str_temp)

        return msbs, hundreds, tens

    def _group_to_numbers(self, msbs, hundreds, tens):

        word_list = []

        if tens:

            tens = int(tens)

            tens_in_words = self._formulate_double_digit_words(tens)

            if tens_in_words:
                word_list.insert(0, tens_in_words)

        if hundreds:

            hundreds = int(hundreds)

            if not hundreds:
                pass
            else:

                hundreds_in_words = '%s hundred' % self.words_dict[hundreds]

                word_list.insert(0, hundreds_in_words)

        if msbs:

            msbs.reverse()

            for idx, item in enumerate(msbs):

                in_words = self._formulate_double_digit_words(int(item))

                if in_words:

                    in_words_with_power = '%s %s' % (in_words, self.power_list[idx])

                    word_list.insert(0, in_words_with_power)

        return word_list

    def _formulate_double_digit_words(self, double_digits):

        if (int(double_digits)) in self.words_dict:

            # Global dict has the key for this number
            tens_in_words = self.words_dict[int(double_digits)]
            return tens_in_words

        else:

            str_double_digits = str(double_digits)

            tens, units = int(str_double_digits[0]) * 10, int(str_double_digits[1])

            tens_units_in_words = '%s %s' % (self.words_dict[tens], self.words_dict[units])

            return tens_units_in_words


複製代碼
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息