snippetpythonMinor
Convert any number (up to 10^3000) to text
Viewed 0 times
3000numberconverttextany
Problem
I kinda got the idea after playing Adventure Capitalist, since that goes up to 10300. I found a website that explained how to go up to 10^3000, so I mainly did this as a challenge to see if I could do it.
Also, I'm fairly new to writing the documentation bits, so feedback on what I did well/not so well would be appreciated. I'm not expecting people to read the entire thing since it ended up quite long, just general feedback would be good.
Basically, it works by initially building a list of every number suffix (like thousand and million) up to nongennovemnonagintillion. Then, when you run the code, it'll probably do similar stuff to conversion codes, with the exception of going a lot higher.
It'll split the number into separate parts matching the exponential values (like 1550 is
Then with converting that to text, I made a separate function to print any number as text between 0-999. Getting it all working initially was really easy, and most of the code is just fixes for various cases when things didn't work quite right (and I'm still occasionally finding bits that don't work).
Some examples:
The script including the documentation is over the character limit so I put it here.
Edit: Before reading the reply from
Also, I'm fairly new to writing the documentation bits, so feedback on what I did well/not so well would be appreciated. I'm not expecting people to read the entire thing since it ended up quite long, just general feedback would be good.
Basically, it works by initially building a list of every number suffix (like thousand and million) up to nongennovemnonagintillion. Then, when you run the code, it'll probably do similar stuff to conversion codes, with the exception of going a lot higher.
It'll split the number into separate parts matching the exponential values (like 1550 is
110^3 + 510^2 + 50*10^0, or {3:1, 2:5, 0:50}), then add the remainder on after the iterations finish. I initially had it calculate the remainder too, like 2 hundredths and 62 millions, but I realised nobody speaks like that so took it out aha.Then with converting that to text, I made a separate function to print any number as text between 0-999. Getting it all working initially was really easy, and most of the code is just fixes for various cases when things didn't work quite right (and I'm still occasionally finding bits that don't work).
Some examples:
>>> LargeNumber('154024500.5').to_text(use_fractions=True)
'154 million, 24 thousand, 5 hundred and 1/2'
>>> LargeNumber('154024500.5').to_text(use_fractions=True, digits=False)
'one hundred and fifty-four million, twenty-four thousand and five hundred point five'
>>> LargeNumber(Decimal('1'+'0'*2000)+Decimal('523.275')).to_text(digits=False)
'one hundred sescenquinsexagintillion, five hundred and twenty-three'
>>> LargeNumber(123456789).to_text(max_iterations=0, num_decimals=2)
'123.46 million'The script including the documentation is over the character limit so I put it here.
Edit: Before reading the reply from
Solution
Use syntax highlighting
Many nice modern IDEs have a feature called Syntax highlighting that will give nice colours to your code making it more readable and help you avoid shadowing built-in:
should be:
to avoid deleting the native
Be helpful
:) What a nice day to learn about this class:
:(
Instead if you change your code to be:
The result is better:
:)
Must
When you write
Noisy commenting
For example:
Almost 1/3 of the lines are comments, and you are telling the what, it is like:
Many of your comments can be removed and the code will improve as they are just noise ad will get obsolete. (Docstrings are great because they give general information, keep them all)
Many nice modern IDEs have a feature called Syntax highlighting that will give nice colours to your code making it more readable and help you avoid shadowing built-in:
def remove_exponent(self, input):should be:
def remove_exponent(self, input_):to avoid deleting the native
input function.Be helpful
:) What a nice day to learn about this class:
>>> help(LargeNumber.__repr__)
Help on method __repr__ in module __main__:
__repr__(self) unbound __main__.LargeNumber method:(
Instead if you change your code to be:
def __repr__(self):
"""
Remove the exponent if a large int/float value is input
Squared length seems to stop precision errors but increase if error happens
"""
if 'E+' in str(self.input):
original_precision = getcontext().prec
getcontext().prec = len(str(self.input))**2
formatted_input = self.remove_exponent(self.input)
getcontext().prec = original_precision
else:
formatted_input = self.input
return "LargeNumber('{}')".format(formatted_input)The result is better:
>>> help(LargeNumber.__repr__)
Help on method __repr__ in module __main__:
__repr__(self) unbound __main__.LargeNumber method
Remove the exponent if a large int/float value is input
Squared length seems to stop precision errors but increase if error happens:)
Must
CalculateFraction be a class?class CalculateFraction(object):
@staticmethod
def find(input, precision=100):
#Convert to float
if not isinstance(input, float):
input = float(input)
#Make sure it is between 0 and 1
original_input = int(input)+1
if not (0 < input < 1):
input = input%1
#Loop through all calculations until a match is found
for j in xrange(2, precision+1):
j = float(j)
for i in xrange(1, int(j)):
if i/j == input:
return i*original_input, int(j)
@staticmethod
def suffix(x, y):
#Convert to str and get important characters
y = str(y)
x = str(x)
last_num = y[-1]
try:
second_num = y[-2]
except IndexError:
second_num = 0
#Define rules
if y == '1':
suffix = ''
elif last_num == '3':
suffix = 'rd'
elif second_num == '1':
suffix = 'th'
elif last_num == '2':
if second_num:
suffix = 'nd'
else:
suffix = ''
elif last_num == '4' and not second_num:
suffix = ''
elif last_num == '1':
suffix = 'st'
else:
suffix = 'th'
#Make plural if x is above 1
if x not in ('1', '0') and suffix:
suffix += 's'
return suffixWhen you write
staticmethod you mean 'this should be free floating but I put it in a class just because it belongs there logically. But your class contains only 2 staticmethod functions, I would let those float around.Noisy commenting
For example:
#Iterate through exponential hundreds (cen+)
for prefix_hundreds in num_exp_hundreds:
#Iterate through exponential tens (decillion+)
for prefix_tens in num_exp_tens:
#Iterate through exponential amounts (un, duo, tre, etc)
for prefix in num_exp_prefix:
num_dict[exp_current] = prefix_hundreds+prefix+prefix_tens
exp_current += 3Almost 1/3 of the lines are comments, and you are telling the what, it is like:
# a is assigned to 10
a = 10Many of your comments can be removed and the code will improve as they are just noise ad will get obsolete. (Docstrings are great because they give general information, keep them all)
Code Snippets
def remove_exponent(self, input):def remove_exponent(self, input_):>>> help(LargeNumber.__repr__)
Help on method __repr__ in module __main__:
__repr__(self) unbound __main__.LargeNumber methoddef __repr__(self):
"""
Remove the exponent if a large int/float value is input
Squared length seems to stop precision errors but increase if error happens
"""
if 'E+' in str(self.input):
original_precision = getcontext().prec
getcontext().prec = len(str(self.input))**2
formatted_input = self.remove_exponent(self.input)
getcontext().prec = original_precision
else:
formatted_input = self.input
return "LargeNumber('{}')".format(formatted_input)>>> help(LargeNumber.__repr__)
Help on method __repr__ in module __main__:
__repr__(self) unbound __main__.LargeNumber method
Remove the exponent if a large int/float value is input
Squared length seems to stop precision errors but increase if error happensContext
StackExchange Code Review Q#91509, answer score: 4
Revisions (0)
No revisions yet.