ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Thu, 10 Mar 2016 13:25:15 +0100How can I make my code continue despite exception?https://ask.sagemath.org/question/32760/how-can-i-make-my-code-continue-despite-exception/ I wrote a function that loops through a data array, performs some calculations and returns new arrays with the results. Unfortunately, some entries in the array contain zero values and cause a division by zero exception, which stops the code. Is there a way to generally ignore division by zero exceptions without wrapping every single line in a "try: except:" construct? Here is a very simplistic example:
var('a x y')
eq_y1 = y == a/x
eq_y2 = y == a*x
eq_y3 = y == a^x
def fun_loop(in_array):
out_array1 = np.zeros_like(in_array)
out_array2 = np.zeros_like(in_array)
out_array3 = np.zeros_like(in_array)
for i in srange(len(in_array)):
in_list = in_array[i]
for j in srange(len(in_list) - 1):
vdict = {}
vdict[a] = in_array[i][j]
vdict[x] = in_array[i][j+1]
out_array1[i,j] = eq_y1.rhs().subs(vdict)
out_array2[i,j] = eq_y2.rhs().subs(vdict)
out_array3[i,j] = eq_y3.rhs().subs(vdict)
return [out_array1, out_array2, out_array3]
in_array = np.array([[3,2,1],[2,1,3],[-3,-1,-2]])
fun_loop(in_array)
returns:
[array([[1, 2, 0],
[2, 0, 0],
[3, 0, 0]]), array([[6, 2, 0],
[2, 3, 0],
[3, 2, 0]]), array([[9, 2, 0],
[2, 1, 0],
[0, 1, 0]])]
However:
in_array = np.array([[3,2,1],[2,1,3],[-3,-1,-2]])
fun_loop(in_array)
returns "ValueError: power::eval(): division by zero" and no results. I would like the function to still return the results for all the other cells, without wrapping each line of the code in a try-except construct. Is there a way to define a general rule how to deal with exeptions of a certain kind within a function like that? The reason is that I have many different equations in the real function and don't want to make the code three times longer.
Wed, 09 Mar 2016 17:21:10 +0100https://ask.sagemath.org/question/32760/how-can-i-make-my-code-continue-despite-exception/Answer by calc314 for <p>I wrote a function that loops through a data array, performs some calculations and returns new arrays with the results. Unfortunately, some entries in the array contain zero values and cause a division by zero exception, which stops the code. Is there a way to generally ignore division by zero exceptions without wrapping every single line in a "try: except:" construct? Here is a very simplistic example:</p>
<pre><code>var('a x y')
eq_y1 = y == a/x
eq_y2 = y == a*x
eq_y3 = y == a^x
def fun_loop(in_array):
out_array1 = np.zeros_like(in_array)
out_array2 = np.zeros_like(in_array)
out_array3 = np.zeros_like(in_array)
for i in srange(len(in_array)):
in_list = in_array[i]
for j in srange(len(in_list) - 1):
vdict = {}
vdict[a] = in_array[i][j]
vdict[x] = in_array[i][j+1]
out_array1[i,j] = eq_y1.rhs().subs(vdict)
out_array2[i,j] = eq_y2.rhs().subs(vdict)
out_array3[i,j] = eq_y3.rhs().subs(vdict)
return [out_array1, out_array2, out_array3]
in_array = np.array([[3,2,1],[2,1,3],[-3,-1,-2]])
fun_loop(in_array)
</code></pre>
<p>returns:
[array([[1, 2, 0],
[2, 0, 0],
[3, 0, 0]]), array([[6, 2, 0],
[2, 3, 0],
[3, 2, 0]]), array([[9, 2, 0],
[2, 1, 0],
[0, 1, 0]])]</p>
<p>However:</p>
<pre><code>in_array = np.array([[3,2,1],[2,1,3],[-3,-1,-2]])
fun_loop(in_array)
</code></pre>
<p>returns "ValueError: power::eval(): division by zero" and no results. I would like the function to still return the results for all the other cells, without wrapping each line of the code in a try-except construct. Is there a way to define a general rule how to deal with exeptions of a certain kind within a function like that? The reason is that I have many different equations in the real function and don't want to make the code three times longer.</p>
https://ask.sagemath.org/question/32760/how-can-i-make-my-code-continue-despite-exception/?answer=32762#post-id-32762Using an inline `if then else` statement might do it. Below, I assume the equations involved are rational functions, but it works for that case. You might be able to adapt this idea to your specific situation.
var('a x y')
eq_y1 = y == a/x
eq_y2 = y == a*x
eq_y3 = y == a^x
def fun_loop(in_array):
out_array1 = np.zeros_like(in_array)
out_array2 = np.zeros_like(in_array)
out_array3 = np.zeros_like(in_array)
for i in srange(len(in_array)):
in_list = in_array[i]
for j in srange(len(in_list) - 1):
vdict = {}
vdict[a] = in_array[i][j]
vdict[x] = in_array[i][j+1]
out_array1[i,j] = eq_y1.rhs().subs(vdict) if eq_y1.rhs().denominator().subs(vdict)!=0 else 0
out_array2[i,j] = eq_y2.rhs().subs(vdict)
out_array3[i,j] = eq_y3.rhs().subs(vdict)
return [out_array1, out_array2, out_array3]
in_array = np.array([[3,2,1],[2,1,3],[-3,-1,-2]])
fun_loop(in_array) Wed, 09 Mar 2016 19:20:13 +0100https://ask.sagemath.org/question/32760/how-can-i-make-my-code-continue-despite-exception/?answer=32762#post-id-32762Comment by stan for <p>Using an inline <code>if then else</code> statement might do it. Below, I assume the equations involved are rational functions, but it works for that case. You might be able to adapt this idea to your specific situation.</p>
<pre><code>var('a x y')
eq_y1 = y == a/x
eq_y2 = y == a*x
eq_y3 = y == a^x
def fun_loop(in_array):
out_array1 = np.zeros_like(in_array)
out_array2 = np.zeros_like(in_array)
out_array3 = np.zeros_like(in_array)
for i in srange(len(in_array)):
in_list = in_array[i]
for j in srange(len(in_list) - 1):
vdict = {}
vdict[a] = in_array[i][j]
vdict[x] = in_array[i][j+1]
out_array1[i,j] = eq_y1.rhs().subs(vdict) if eq_y1.rhs().denominator().subs(vdict)!=0 else 0
out_array2[i,j] = eq_y2.rhs().subs(vdict)
out_array3[i,j] = eq_y3.rhs().subs(vdict)
return [out_array1, out_array2, out_array3]
in_array = np.array([[3,2,1],[2,1,3],[-3,-1,-2]])
fun_loop(in_array)
</code></pre>
https://ask.sagemath.org/question/32760/how-can-i-make-my-code-continue-despite-exception/?comment=32764#post-id-32764Thanks, but this is quite similar to wrapping each line in a try-exception statement, only using if-else instead. I was wondering if one could not wrap the whole function in something that would continue evaluation every time a division by zero exception is thrown.Wed, 09 Mar 2016 23:03:58 +0100https://ask.sagemath.org/question/32760/how-can-i-make-my-code-continue-despite-exception/?comment=32764#post-id-32764Answer by nbruin for <p>I wrote a function that loops through a data array, performs some calculations and returns new arrays with the results. Unfortunately, some entries in the array contain zero values and cause a division by zero exception, which stops the code. Is there a way to generally ignore division by zero exceptions without wrapping every single line in a "try: except:" construct? Here is a very simplistic example:</p>
<pre><code>var('a x y')
eq_y1 = y == a/x
eq_y2 = y == a*x
eq_y3 = y == a^x
def fun_loop(in_array):
out_array1 = np.zeros_like(in_array)
out_array2 = np.zeros_like(in_array)
out_array3 = np.zeros_like(in_array)
for i in srange(len(in_array)):
in_list = in_array[i]
for j in srange(len(in_list) - 1):
vdict = {}
vdict[a] = in_array[i][j]
vdict[x] = in_array[i][j+1]
out_array1[i,j] = eq_y1.rhs().subs(vdict)
out_array2[i,j] = eq_y2.rhs().subs(vdict)
out_array3[i,j] = eq_y3.rhs().subs(vdict)
return [out_array1, out_array2, out_array3]
in_array = np.array([[3,2,1],[2,1,3],[-3,-1,-2]])
fun_loop(in_array)
</code></pre>
<p>returns:
[array([[1, 2, 0],
[2, 0, 0],
[3, 0, 0]]), array([[6, 2, 0],
[2, 3, 0],
[3, 2, 0]]), array([[9, 2, 0],
[2, 1, 0],
[0, 1, 0]])]</p>
<p>However:</p>
<pre><code>in_array = np.array([[3,2,1],[2,1,3],[-3,-1,-2]])
fun_loop(in_array)
</code></pre>
<p>returns "ValueError: power::eval(): division by zero" and no results. I would like the function to still return the results for all the other cells, without wrapping each line of the code in a try-except construct. Is there a way to define a general rule how to deal with exeptions of a certain kind within a function like that? The reason is that I have many different equations in the real function and don't want to make the code three times longer.</p>
https://ask.sagemath.org/question/32760/how-can-i-make-my-code-continue-despite-exception/?answer=32765#post-id-32765You can express "general rules" like this as wrapper functions. In your case you might want to write something along the lines of:
def subs_or_none(expr, vdict):
try:
return expr.subs(vdict)
except ValueError:
return None
and then you can write
out_array1[i,j] = subs_or_none(eq_y1.rhs(), vdict)
...
Your code is still a bit longer, because you have to specify how to handle the exception (but you really need to do that anyway). Your cost does not go up with the number of times you need the behaviour, however.
Be careful that this code would catch *all* ValueErrors. You'd need to do some more checking to ensure it's just a division-by-zero. In fact, one could consider it a deficiency that pynac signals a ValueError here and not a ZeroDivisionError.Wed, 09 Mar 2016 23:11:09 +0100https://ask.sagemath.org/question/32760/how-can-i-make-my-code-continue-despite-exception/?answer=32765#post-id-32765Comment by stan for <p>You can express "general rules" like this as wrapper functions. In your case you might want to write something along the lines of:</p>
<pre><code>def subs_or_none(expr, vdict):
try:
return expr.subs(vdict)
except ValueError:
return None
</code></pre>
<p>and then you can write</p>
<pre><code> out_array1[i,j] = subs_or_none(eq_y1.rhs(), vdict)
...
</code></pre>
<p>Your code is still a bit longer, because you have to specify how to handle the exception (but you really need to do that anyway). Your cost does not go up with the number of times you need the behaviour, however.</p>
<p>Be careful that this code would catch <em>all</em> ValueErrors. You'd need to do some more checking to ensure it's just a division-by-zero. In fact, one could consider it a deficiency that pynac signals a ValueError here and not a ZeroDivisionError.</p>
https://ask.sagemath.org/question/32760/how-can-i-make-my-code-continue-despite-exception/?comment=32769#post-id-32769Awesome, thank you! This does the trick with only small alterations to the code. Just a small comment, unless insisting on an integer dtype in the array, it would be better to use NaN instead of None. See here for a discussion of NaN vs. None: http://stackoverflow.com/questions/17534106/what-is-the-difference-between-nan-and-none#17534682Thu, 10 Mar 2016 13:25:15 +0100https://ask.sagemath.org/question/32760/how-can-i-make-my-code-continue-despite-exception/?comment=32769#post-id-32769