Python documentation says that FloatingPointError is raised when a float calculation fails. But what is exactly meant here by "a float calculation"?
I tried adding, multiplying and dividing with floats but never managed to raise this specific error. Instead, i got a TypeError:
10/'a'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for /: 'int' and 'str'
Can someone help me understand when a FloatingPointError is raised in python?
It is part of the fpectl module. The FloatingPointError shouldn't be raised if you don't explicitly turn it on (fpectl.turnon_sigfpe()).
However mind the note:
The fpectl module is not built by default, and its usage is discouraged and may be dangerous except in the hands of experts. See also the section fpectl-limitations on limitations for more details.
Update: The fpectl module has been removed as of Python 3.7.
Even with FloatingPointErrors turned on, 10/'a' will never raise one. It will always raise a TypeError. A FloatingPointError will only be raised for operations that reach the point of actually performing floating-point math, like 1.0/0.0. 10/'a' doesn't get that far.
You can also trigger a FloatingPointError within numpy, by setting the appropriate numpy.seterr (or numpy.errstate context manager) flag. For an example taken from the documentation:
>>> np.sqrt(-1)
nan
>>> with np.errstate(invalid='raise'):
... np.sqrt(-1)
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
FloatingPointError: invalid value encountered in sqrt
Interestingly, it also raises FloatingPointError when all operands are integers:
>>> old_settings = np.seterr(all='warn', over='raise')
>>> np.int16(32000) * np.int16(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
FloatingPointError: overflow encountered in short_scalars
The documentation notes the conditions under which the FloatingPointError will be raised:
The floating-point exceptions are defined in the IEEE 754 standard [1]:
Division by zero: infinite result obtained from finite numbers.
Overflow: result too large to be expressed.
Underflow: result so close to zero that some precision was lost.
Invalid operation: result is not an expressible number, typically indicates that a NaN was produced.
Related
I don't exactly know how I whiffed this, but at some point I input
repr = 64
into the python console in spyder. When I now try to run repr(b64) this happens:
repr(b64)
Traceback (most recent call last):
File "<ipython-input-23-8c64b01419a6>", line 1, in <module>
repr(b64)
TypeError: 'int' object is not callable
can I fix this without restarting spyder?
Delete your variable:
del repr
This will clear the binding you created, unhiding the builtin. (It will not remove the builtin repr.) This gets you back to a slightly cleaner state than repr = builtins.repr would, though it usually won't matter.
Use builtins.repr:
>>> repr = 42
>>> repr(42)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
>>> from builtins import repr
>>> repr(42)
'42'
(or use del as suggested by user2357112).
When round is imported from the future, it does not behave the same as the Python3 round function. Specifically, it does not support negative digit rounding.
In Python3:
>>> round(4781, -2)
4800
In Python2:
>>> from builtins import round
>>> round(4781, -2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/future/builtins/newround.py", line 33, in newround
raise NotImplementedError('negative ndigits not supported yet')
NotImplementedError: negative ndigits not supported yet
Possible solutions include error handling for negative rounding, writing my own round function, etc. How should this be handled? (Implicitly, I'm asking for best practices, most Pythonic, accepted by community, etc.)
I was going to suggest your custom function idea so you can ensure it always does what you want, but this appears to be a special (weird) case where if I don't use future.builtin.round() I get
Python 3.6:
>>> round(4781, -2)
4800
and Python 2.7:
>>> round(4781, -2)
4800.0
It appears to just be the future.builtins that is somehow broken; in this case, you should avoid using the future.builtins.round() function. Note that py3 round() returns an integer while py2 round() returns a float, but that seems to be the only difference between the two stock implementations (for simple rounding operations such as the examples given).
I do not want to do:
try:
pid = int(a_variable)
except StandardError as e:
pass
So, the question is what is the method of figuring out all of the possible exceptions can result in int(a_variable). Obviously, TypeError and ValueError can happen, but how do I work out what else can result?
You can pick the method that suits you from traceback module and combine it with a logger object (see logging module):
import traceback
import sys
import logging
try:
pid = int(sys.argv[1])
except Exception as e:
logging.error(traceback.print_exc())
Execution examples:
You can catch anIndexError exception with python begueradj.py
begueradj#begueradj:~/Desktop$ python begueradj.py
Traceback (most recent call last):
File "tester.py", line 6, in <module>
pid = int(sys.argv[1])
IndexError: list index out of range
You can catch a ValueError exception with python begueradj.py +:
begueradj#begueradj:~/Desktop$ python begueradj.py +
Traceback (most recent call last):
File "tester.py", line 6, in <module>
pid = int(sys.argv[1])
ValueError: invalid literal for int() with base 10: '+'
I only see two possible exceptions that can be generated by your code:
pid = int(sys.argv[1])
ValueError if the string in sys.argv[1] is no valid integer representation (like "one" or "1.5")
IndexError if the sys.argv list does not contain at least two elements, because the script was executed without command-line arguments.
There's no chance (assuming you don't override the builtins) that your code can raise a TypeError, because sys.argv is always a list of strings. Period.
You could eventually also even get a NameError if you forgot the import sys in your code above this line as well, but that's no runtime error but a programming error.
What could happen is that while your command is running the interpreter raises an unrelated exception like KeyboardInterrupt because the user pressed Ctrl+C in that exact millisecond - but you usually don't want to catch those locally.
As you're saying in your comment that the code line in your question was just an example, if we generalize this to int(x) (with x being a literal or a variable, but nothing that is able to throw exceptions itself, like method calls or operations), you can additionally get those exceptions:
TypeError if the argument is neither a numeric type (int, long, float, complex, bool), nor a string-like type (str, bytes, bytearray) nor any other object having a __int__ method or (since 3.4) a __index__ method.
NameError if you use a variable name as input which has not been defined yet in this context. However this is very unlikely unless you use eval or exec and let the user input a variable name (discouraged!). As this is a pure programming error and no runtime error and your IDE will highlight the use of undeclared variable names, it's usually not useful to check for this error.
I'm following along with the Python docs for try/except with the following effort:
def profile_check(self):
try:
profile = self.profile_type
return profile
except TypeError:
...
self.profile_type is a field in a Django model which doesn't exist in this case (therefore it returns as None). However, something seems to be missing, because it never moves on to the actions for except, rather it immediately throws the TypeError exception:
>>> a.profile_check()
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: 'NoneType' object is not callable
This is my first effort with try-catch, so I know it's something basic.
First off, your problem is that profile_check is set to None for some reason. That's why it's giving you that error when you call it.
As for your try/catch problem, if a variable doesn't exist, then the Python interpreter will throw a NameError at you. Try substituting TypeError for that.
I can't help you with your profile_check-is-None situation though without anymore context though. Sorry!
The tuples represent fractions. I'm trying to divide the fractions by multiplying by the reciprical
class Test():
def __init__(self):
self._x=(1,2)
def __div__(self,div_fraction):
return (self._x[0]*div_fraction[1],self._x[1]*div_fraction[0])
y=Test()
z=y/(1,3)
print(z)
Gives me:
Traceback (most recent call last):
File "E:/test.py", line 8, in <module>
z=y/(1,3)
TypeError: unsupported operand type(s) for /: 'Test' and 'tuple'
Yet when I change the __div__ to __mul__ and use * instead of / it does what it should.
How do I fix the exception I'm getting?
Python 3.x uses __truediv__ and __floordiv__. __div__ is 2.x-only.
had the same problem the other day.
see if __future__.division is active in your environment. if so, you need to define __truediv__ as well.
http://docs.python.org/2/library/operator.html#mapping-operators-to-functions