Straight to the point, here's the original code:
integer = input(...)
size = len(integer)
# Created three dicts for matching numbers as keys to corresponding words
dic_ones = {...}
dic_tens = {...}
dic_tys = {...}
# Created one main function digits_length within which I called functions(ones,tens,hundreds,thousands,millions,billions)
# based on the input length
def ones(num):
print(dic_ones[num], end="")
def tens(num):
if num//10 == 1:
print(dic_tens[num], end="")
elif num % 10 == 0:
print(dic_tys[num], end="")
else:
print(dic_tys[num-(num % 10)], end="")
ones(num % 10)
def hundreds(num):
if num % 100 == 0:
ones(num//100)
print(" Hundred")
else:
ones(num//100)
print(" Hundred", end="")
digits_length(len(str(num % 100)), num % 100)
def billions(num):
ones(num//1000000000)
print(" Billion", end="")
if num % 1000000000 != 0:
digits_length(len(str(num % 1000000000)), num % 1000000000)
def millions(num):
digits_length(len(str(num//1000000)), num//1000000)
print(" Million", end="")
if num % 1000000 != 0:
digits_length(len(str(num % 1000000)), num % 1000000)
def thousands(num):
digits_length(len(str(num//1000)), num//1000)
print(" Thousand", end="")
if num % 1000 != 0:
digits_length(len(str(num % 1000)), num % 1000)
def digits_length(length, number):
if length == 1:
ones(number)
elif length == 2:
tens(number)
elif length == 3:
hundreds(number)
elif 7 > length > 3:
thousands(number)
elif 10 > length > 7:
millions(number)
else: # else applies to length 10 or billions
billions(number)
# ones and tens are the smallest magnitudes so they do not include recursive call to digits_length
digits_length(size, int(integer))
(I replaced some irrelevant parts with ...).
Here's my new, refactored code:
class FormatNumber():
@staticmethod
def create_maps(start=0, stop=10, skip=None, names=()):
if skip:
return {k: v for k, v in zip(range(start, stop, skip), names)}
return {k: v for k, v in zip(range(start, stop), names)}
# Created three dicts for matching numbers as keys to corresponding words
dict_ones = create_maps(1, 10, names=["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"])
dict_tens = create_maps(10, 20,
names=[" Ten ", " Eleven ", " Twelve ", " Thirteen ", " Fourteen ", " Fifteen ", " Sixteen ",
" Seventeen ", " Eighteen ", " Nineteen "])
dict_tys = create_maps(20, 100, 10,
names=[" Twenty ", " Thirty ", " Forty ", " Fifty ", " Sixty ", " Seventy ", " Eighty ",
" Ninety "])
def __init__(self, number):
self.num = number
def ones(self, num):
print(self.dict_ones[num], end="")
def tens(self, num):
if num // 10 == 1:
print(self.dict_tens[num], end="")
elif num % 10 == 0:
print(self.dict_tys[num], end="")
else:
print(self.dict_tys[num - (num % 10)], end="")
self.ones(num % 10)
def hundreds(self, num):
# print(type(num))
if num % 100 == 0:
self.ones(num // 100)
print(" Hundred")
else:
self.ones(num // 100)
print(" Hundred", end="")
self._format_number(num % 100)
def billions(self, num):
self.ones(num // 1000000000)
print(" Billion", end="")
if num % 1000000000 != 0:
self._format_number(num % 1000000000)
def millions(self, num):
self._format_number(num // 1000000)
print(" Million", end="")
if num % 1000000 != 0:
self._format_number(num % 1000000)
def thousands(self, num):
self._format_number(num // 1000)
print(" Thousand", end="")
if num % 1000 != 0:
self._format_number(num % 1000)
def _format_number(self, number):
length = len(str(number))
if length == 1:
self.ones(number)
elif length == 2:
self.tens(number)
elif length == 3:
self.hundreds(number)
elif 7 > length > 3:
self.thousands(number)
elif 10 > length > 7:
self.millions(number)
else: # else applies to length 10 or billions
self.billions(number)
def format_number(self):
self._format_number(self.num)
if __name__ == '__main__':
integer = int(input("Enter non-negative integer number which should not begin with zero"))
english_repr = FormatNumber(integer)
english_repr.format_number()
Is refactoring in this case a good idea? Or should the separate ones(), tens(), hundreds(), …etc. stay as functions? Also I would greatly appreciate anyone pointing out any other structural weaknesses in my code and potential fixes (I considered posting this on code review but I decided that for the structure part I would ask here).
Note: The refactored code is actually my answer to a question on codereview.stackexchange, but it created some controversy as to whether or not my refactoring is suitable for this case. Thus, I asked here in hopes of knowing if refactoring is a good idea in this case.
if __name__ == '__main__') but this is unrelated to the use of a class.