The following code throws me the error:
Traceback (most recent call last):
File \"\", line 25, in
sol = anna.main()
File \"\", line 17, in
It may not be your exact case, but if you want to take the square root of a large number AND you want to have control of the precision of the result, going either to math.sqrt()
or x ** 0.5
would not be much useful because your result will end up being a float number, and for large enough inputs, this will hit the limitations of float numbers.
One possibility for the specific case of sqrt
is to look into an integer-only implementation of the square root algorithm, e.g. flyingcircus.util.isqrt() (Disclaimer: I am the main author of flyingcircus).
Alternatively, for a more general solution, one may look into gmpy (or any other arbitrary precision library with Python bindings).
You can replace numpy by the built in function math.sqrt like this:
import math
class anaconda():
def __init__(self):
self.mice = range(10000)
def eat(self, food):
calc = math.sqrt(food ** 5)
return calc
def main(self):
sol = list(map(self.eat, self.mice))
return sol
if __name__ == '__main__':
anna = anaconda()
sol = anna.main()
print(len(sol))
I think that the problem of your code is that you are probably reaching a limit (not sure yet why it raises that confusing error) because 10000**5 is a reeeally big number. You can check this out by reducing your range(10000) to range(1000). You will notice that your code runs perfectly fine then:
import numpy as np
class anaconda():
def __init__(self):
self.mice = range(1000)
def eat(self, food):
calc = np.sqrt((food ** 5))
return calc
def main(self):
sol = list(map(self.eat, self.mice))
print sol
return sol
if __name__ == '__main__':
anna = anaconda()
sol = anna.main()
print(len(sol))
This runs perfectly fine, just by reducing range(10000) to range(1000)
I'll try to add a precise answer to those that have already been given. numpy.sqrt
has some limitations that math.sqrt
doesn't have.
import math
import numpy # version 1.13.3
print(math.sqrt(2 ** 64 - 1))
print(numpy.sqrt(2 ** 64 - 1))
print(math.sqrt(2 ** 64))
print(numpy.sqrt(2 ** 64))
returns (with Python 3.5) :
4294967296.0
4294967296.0
4294967296.0
Traceback (most recent call last):
File "main.py", line 8, in <module>
print(numpy.sqrt(2 ** 64))
AttributeError: 'int' object has no attribute 'sqrt'
In fact, 2 ** 64
is equal to 18,446,744,073,709,551,616
and, according to the standard of C data types (version C99), the long long unsigned integer
type contains at least the range between 0
and 18,446,744,073,709,551,615
included.
The AttributeError
occurs because numpy
, seeing a type that it doesn't know how to handle (after conversion to C data type), defaults to calling the sqrt
method on the object (but that doesn't exist). If we use floats instead of integers then everything will work using numpy
:
import numpy # version 1.13.3
print(numpy.sqrt(float(2 ** 64)))
returns:
4294967296.0
So instead of replacing numpy.sqrt
by math.sqrt
, you can alternatively replace calc = np.sqrt(food ** 5)
by calc = np.sqrt(float(food ** 5))
in your code.
I hope this error will make more sense to you now.
Actually, you need neither numpy
nor math
because sqrt(x) is x**0.5. So:
sqrt(x**5) = x ** (5/2) = x ** 2.5
It means you could replace your code with:
class anaconda():
def __init__(self):
self.mice = range(10000)
def eat(self, food):
calc = food ** 2.5
return calc
def main(self):
sol = list(map(self.eat, self.mice))
return sol
if __name__ == '__main__':
anna = anaconda()
sol = anna.main()
print(len(sol))
If you want to use NumPy, you can enjoy the fact that you can work with arrays as if they were scalars:
import numpy as np
class anaconda():
def __init__(self):
self.mice = np.arange(10000)
def eat(self, food):
return food ** 2.5
def main(self):
return self.eat(self.mice)
if __name__ == '__main__':
anna = anaconda()
sol = anna.main()
print(len(sol))
Removing all the unneeded object-oriented-with-weird-names, your code becomes:
import numpy as np
print(np.arange(10000) ** 2.5)
As others have noticed, this boils down to the fact that np.sqrt(7131 ** 5)
works but np.sqrt(7132 ** 5)
returns an error:
import numpy as np
print(np.sqrt(7131 ** 5))
print(np.sqrt(7132 ** 5))
# 4294138928.9
Traceback (most recent call last):
File "main.py", line 4, in <module>
print(np.sqrt(7132 ** 5))
AttributeError: 'int' object has no attribute 'sqrt'
Since np.sqrt docs don't mention any bounds on the argument, I'd consider this a numpy bug.