Raising an exception while using numba - python

Following up from here, I keep getting overflows. So I'm trying to raise an exception so that I know exactly what's going wrong where.
I've got something like this:
#jit
def train_function(X, y, H):
np.seterr(over="raise", under="raise", invalid="raise")
# do some stuff, start a double loop, and then do:
try:
z[i,j] = math.exp(-beta[j,i])
except OverflowError:
print "Calculation failed! z[i,j] = math.exp(-beta[j,i]), j: " + str(j) + ", i: " +str(i) + ", b: " + str(beta[j,i]) + ", omb: " + str(oneminusbeta[j,i])
raise
class MyClass(object):
# init and other methods
def train(self, X, y, H):
train_function(X, y, H)
But I get this error:
Traceback (most recent call last):
File "C:\work_asaaki\code\gbc_classifier_train_7.py", line 55, in <module>
gentlebooster.train(X_train, y_train, boosting_rounds)
File "C:\work_asaaki\code\gentleboost_c_class_jit_v7_nolimit.py", line 297, in train
self.g_per_round, self.g = train_function(X, y, H)
File "C:\Anaconda\lib\site-packages\numba\dispatcher.py", line 152, in _compile_for_args
return self.jit(sig)
File "C:\Anaconda\lib\site-packages\numba\dispatcher.py", line 143, in jit
return self.compile(sig, **kws)
File "C:\Anaconda\lib\site-packages\numba\dispatcher.py", line 131, in compile
flags=flags, locals=locs)
File "C:\Anaconda\lib\site-packages\numba\compiler.py", line 103, in compile_extra
bc = bytecode.ByteCode(func=func)
File "C:\Anaconda\lib\site-packages\numba\bytecode.py", line 305, in __init__
table = utils.SortedMap(ByteCodeIter(code))
File "C:\Anaconda\lib\site-packages\numba\utils.py", line 70, in __init__
for i, (k, v) in enumerate(sorted(seq)):
File "C:\Anaconda\lib\site-packages\numba\bytecode.py", line 219, in next
raise NotImplementedError(ts % tv)
NotImplementedError: offset=742 opcode=0x79 opname=SETUP_EXCEPT
Can't I raise exception while I'm using numba? I'm using Anaconda 2.0.1 with Numba 0.13.x and Numpy 1.8.x on a 64-bit machine.

http://numba.pydata.org/numba-doc/dev/reference/pysupported.html
2.6.1.1. Constructs
Numba strives to support as much of the Python language as possible, but some language features are not available inside Numba-compiled functions. The following Python language features are not currently supported:
Class definition
Exception handling (try .. except, try .. finally)
Context management (the with statement)
The raise statement is supported in several forms:
raise (to re-raise the current exception)
raise SomeException
raise SomeException(<arguments>)
so that leaves us here:
z[i,j] = math.exp(-beta[j,i])
anything negative under about exp(-1000); really-really small will evaluate to zero without overflow
math.exp(-1000000000) "works" and is probably not your issue (although it will return 0.0, its not "really" zero)
so what would cause this to fail? well we know:
print(math.exp(100))
>>>
2.6881171418161356e+43
is silly big, much more than that... probably overflow
sure enough
print(math.exp(1000))
>>>
OverflowError: math range error
I don't have citation but I think the effective range is like -700 to 700 which evaluate to 0 and infinity(overflow) effectively from the perspective of double floats
to handle that we window the function:
n = beta
if n > 100:
n = 100
z = math.exp(n)
but that won't work either because math.exp(n) only accepts floats and your beta appears to be a list; you'll have to use numpy.exp(n) and numpy.clip() to window
b = numpy.array(-beta[j,i])
n = numpy.clip(b, a_max=100)
z = numpy.exp(n)
or to raise the overflow exception:
b = numpy.array(-beta[j,i])
n = numpy.clip(b, a_max=100)
if b != n:
print (j,i,-beta[j,i])
raise OverflowError
else:
z = numpy.exp(n)

Related

Python turtle function - receiving an error I can't make sense of

When running the below code I am receiving this error. Anyone any ideas, I have followed an example set by a tutor and made it my own but mine doesn't run.
Traceback (most recent call last):
File "main.py", line 74, in <module>
timmy.color(random_color)
File "/nix/store/p21fdyxqb3yqflpim7g8s1mymgpnqiv7-python3-3.8.12/lib/python3.8/turtle.py", line 2217, in color
pcolor = self._colorstr(pcolor)
File "/nix/store/p21fdyxqb3yqflpim7g8s1mymgpnqiv7-python3-3.8.12/lib/python3.8/turtle.py", line 2697, in _colorstr
return self.screen._colorstr(args)
File "/nix/store/p21fdyxqb3yqflpim7g8s1mymgpnqiv7-python3-3.8.12/lib/python3.8/turtle.py", line 1153, in _colorstr
if len(color) == 1:
TypeError: object of type 'function' has no len()
import turtle
import random
timmy = turtle.Turtle()
turtle.colormode(255)
timmy.shape("turtle")
timmy.color("red")
turtle_heading = [0, 90, 180, 270]
def random_color():
r = random.randint(0, 255)
g = random.randint(0, 255)
b = random.randint(0, 255)
random_color(r, g, b)
return random_color
for i in range(200):
timmy.setheading(random.choice(turtle_heading))
timmy.color(random_color)
timmy.forward(30)
You seem to have gotten variables and functions confused. Maybe from VBA or similiar.
In python, a variable is either a function or a value, never both.
At then end of your random_color() you call random_color with the arguments (r,g,b), which will give you an error when executed, as your function doesn't take arguments. Then you return the function itself.
What you probably wanted to do was to return the tuple (r, g, b) which you can do by replacing the last two lines of the function with return (r, g, b) and then calling it with random_color() in your timmy.color().
Your current error there happens because you pass it the function without executing it, so it complains that the function-type object you passed has no length (as that is required by timmy.color)

Python: calling inner() from outer()

I have looked around on SO and surprisingly not found an answer to this question. I assume this is because normally inner/nested functions are used for something in particular (eg. maintaining an environment variable, factories) as opposed to something trivial like I'm trying to use them for. In any case, I can't seem to find any information on how to properly call an inner function from an outer function without having to declare inner() above outer() in the file. The problem is from this problem on HackerRank (https://www.hackerrank.com/challenges/circular-array-rotation/problem).
def circularArrayRotation(a, k, queries):
def rotateArrayRightCircular(arr: list, iterations: int) -> list:
"""
Perform a 'right circular rotation' on an array for number of iterations.
Note: function actually moves last 'iterations' elements of array to front of array.
>>>rotateArrayRightCircular([0,1,2], 1)
[2,0,1]
>>>rotateArrayRightCircular([0,1,2,3,4,5], 3)
[3,4,5,0,1,2]
>>>rotateArrayRightCircular([0,1,2,3,4,5], 6)
[0,1,2,3,4,5]
"""
return arr[-1 * iterations:] + arr[0:-1 * iterations]
k = k % len(a)
a = rotateArrayRightCircular(a, k)
res = []
for n in queries:
res.append(a[n])
return res
The code above does what I want it to, but it's somehow inelegant to me that I have to put the inner function call after the inner function definition. Various errors with different attempts:
# trying 'self.inner()'
Traceback (most recent call last):
File "solution.py", line 52, in <module>
result = circularArrayRotation(a, k, queries)
File "solution.py", line 13, in circularArrayRotation
a = self.rotateArrayRightCircular(a, k)
NameError: name 'self' is not defined
# Removing 'self' and leaving the definition of inner() after the call to inner()
Traceback (most recent call last):
File "solution.py", line 52, in <module>
result = circularArrayRotation(a, k, queries)
File "solution.py", line 13, in circularArrayRotation
a = rotateArrayRightCircular(a, k)
UnboundLocalError: local variable 'rotateArrayRightCircular' referenced before assignment
Any idea how I could include def inner() after the call to inner() without throwing an error?
As a function is executed from top to bottom, and a function is put into existence as the function is processed, what you want is just not possible.
You could put the function before the outer one, making it outer itself, possibly adding some parameters (not necessary here). (BTW, it looks so generic that other parts of the code might want to use it as well, so why not outer?)
But otherwise, you are stuck. It is essetially the same situation as in
def f():
print(a) # a doesn't exist yet, so this is an error
a = 4
Well, you could do it this way:
def circularArrayRotation(a, k, queries):
def inner_code():
k = k % len(a)
a = rotateArrayRightCircular(a, k)
# BTW, instead of the following, you could just do
# return [a[n] for n in queries]
res = []
for n in queries:
res.append(a[n])
return res
def rotateArrayRightCircular(arr: list, iterations: int) -> list:
"""
Perform a 'right circular rotation' on an array for number of iterations.
Note: function actually moves last 'iterations' elements of array to front of array.
>>>rotateArrayRightCircular([0,1,2], 1)
[2,0,1]
>>>rotateArrayRightCircular([0,1,2,3,4,5], 3)
[3,4,5,0,1,2]
>>>rotateArrayRightCircular([0,1,2,3,4,5], 6)
[0,1,2,3,4,5]
"""
return arr[-1 * iterations:] + arr[0:-1 * iterations]
return inner_code()
but I don't see that you gain anything from it.
This is not possible in Python, but is possible in other languages like Javascript and PHP. It is called function hoisting.

Handle the error when the limits do not exist in sympy

I have been having a problem with SymPy at the time of making a limit which would have to answer "does not exist" is returning the infinite value. The code section would be this:
x = Symbol ('x')
a = Limit ((5-x) / (x-2), x, 2, "+"). doit ()
print (a)
oo
b = Limit ((5-x) / (x-2), x, 2, "-"). doit ()
print (b)
-oo
c = Limit ((5-x) / (x-2), x, 2) .doit ()
print (c)
oo
Here is the problem as investigated and check should leave a message as the limit does not exist or return any value equal to 0.
By default, Limit ((5-x) / (x-2), x, 2) means one-sided limit from the right, so c will always be the same as a in your example.
In the current development version on GitHub, one can pass "+-" as the direction, which will compute both limits and raise ValueError if they are not the same:
>>> limit((5-x) / (x-2), x, 2, "+-")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/ubuntu/sympy/sympy/series/limits.py", line 66, in limit
% (llim, rlim))
ValueError: The limit does not exist since left hand limit = -oo and right hand limit = oo
But you probably just want a conditional like
if a != b:
print("One-sided limits are different")
elif a.is_infinite:
print("Infinite limit")
# and so on

TypeError raised while trying to use range

While i'm running the following code it shows a TypeError:
a = int(input("Enter the iteration value:"))
b=[]
for c in range[0,a]:
d=int(input("Enter:"))
b.append(d)
f=0
for e in b:
f = f + e
print f
It shows the following error
Enter the iteration value:5
Traceback (most recent call last):
File "/var/app/eclipse/plugins/org.python.pydev_3.5.0.201405201709/pysrc/pydevd.py", line 1845, in <module>
debugger.run(setup['file'], None, None)
File "/var/app/eclipse/plugins/org.python.pydev_3.5.0.201405201709/pysrc/pydevd.py", line 1373, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "/opt/odoo/v7.0_cust_mod/Python/print.py", line 68, in <module>
for c in range[0,a]:
TypeError: 'builtin_function_or_method' object has no attribute '__getitem__'
You are using the wrong syntax for the range() function:
for c in range[0,a]:
Note the square brackets, you should use parentheses instead:
for c in range(0, a):
The square brackets are used for subscriptions, which means Python will try and use a __getitem__ method on the range function object. There is no such method, which is why you get your traceback.

Assert an integer is within range

I am writing some unittests in python that are testing if I receive an integer. However sometimes this integer can be off by 1 or 2 and I don't really care. Essentially I want to be able to assert that the received integer is within a certain range, something like:
self.assertBetween(998, 1000, my_integer)
Is there an accepted way of doing this? Or will I have to do something like this:
self.assertTrue(998 <= my_integer)
self.assertTrue(my_integer <= 1000)
EDIT
The answers so far suggest:
self.assertTrue(998 <= my_integer <= 1000)
Is there any benefit of this over my example with 2 asserts?
You can use a "chained comparison":
self.assertTrue(998 <= my_integer <= 1000)
Python has a built in function you may use for this: assertAlmostEqual.
self.assertAlmostEqual(myinteger, 999, delta=1)
# is equivalent to
self.assertTrue(998 <= myinteger <= 1000)
# ... but gives better error messages.
The optional parameter delta specifies the allowed distance from the value you're testing.
I don't think it's a good idea to use assertTrue with comparison inside -
that way you lose any information in FAIL message:
AssertionError: False is not true
Which is not helpful at all and you're basicaly back to "raw" assert and you are losing a lot of unittest's methods benefits.
I would recommend either:
Creating your own custom assert
in which you can print more meaningful message. For example:
import unittest
class BetweenAssertMixin(object):
def assertBetween(self, x, lo, hi):
if not (lo <= x <= hi):
raise AssertionError('%r not between %r and %r' % (x, lo, hi))
class Test1(unittest.TestCase, BetweenAssertMixin):
def test_between(self):
self.assertBetween(999, 998, 1000)
def test_too_low(self):
self.assertBetween(997, 998, 1000)
def test_too_high(self):
self.assertBetween(1001, 998, 1000)
if __name__ == '__main__':
unittest.main()
then you'll have following output (shortened):
======================================================================
FAIL: test_too_high (__main__.Test1)
----------------------------------------------------------------------
Traceback (most recent call last):
File "example.py", line 19, in test_too_high
self.assertBetween(1001, 998, 1000)
File "example.py", line 8, in assertBetween
raise AssertionError('%r is not between %r and %r' % (x, lo, hi))
AssertionError: 1001 is not between 998 and 1000
======================================================================
FAIL: test_too_low (__main__.Test1)
----------------------------------------------------------------------
Traceback (most recent call last):
File "example.py", line 16, in test_too_low
self.assertBetween(997, 998, 1000)
File "example.py", line 8, in assertBetween
raise AssertionError('%r is not between %r and %r' % (x, lo, hi))
AssertionError: 997 is not between 998 and 1000
----------------------------------------------------------------------
Or use assertLessEqual and assertGreaterEqual
if you don't want custom assert (which does add another traceback record and several lines of code):
...
def test_no_custom_assert(self):
my_integer = 100
self.assertGreaterEqual(my_integer, 998)
self.assertLessEqual(my_integer, 1000)
...
which is a bit longer (it may be shorter in total than adding custom assert if it's used only once) than assertTrue(998 <= my_integer <= 1000) but you'll still get nice fail messages (also without additional traceback record):
======================================================================
FAIL: test_no_custom_assert (__main__.Test1)
----------------------------------------------------------------------
Traceback (most recent call last):
File "example.py", line 23, in test_no_custom_assert
self.assertGreaterEqual(my_integer, 998)
AssertionError: 100 not greater than or equal to 998
self.assertTrue(998 <= my_integer <= 1000)

Categories