try.. except failing inside for loop - python-3.x

I have a for loop which loops through initial guesses for a scipy.optimize.minimize routine. Some of the initial guesses fail, so I want to wrap the call to scipy.optimize.minimize in a try/except statement, so that when a guess fails, it moves on to the next.
Unfortunately this is not working. Once a guess fails, the next iterations also fail, even if the initial guess is a good one that I know works.
When I try to reproduce this failure in a MWE, I can't, so I am stumped.
Here is the MWE that works
import numpy as np
def f(x):
assert type(x) == float
return np.log(x)
def arbitrary_function():
vals = [ 0.5, "string", 5, 9.3]
v_list=[]
for num in vals:
try:
v = f(num)
if v > 0:
v_list.append(v)
except:
print("failed on {}".format(num))
continue
return v_list
my_list = arbitrary_function()
print(my_list)
Am I missing something with the try.. except usage?
The error that the real code raises on the failed attempts is due to
assert np.isclose(np.sum(x_tilde), 1.0)
AssertionError
for this reason I included the assert type(x) == float in the MWE, it raises the same exception, however, it carries on fine after hitting string, whereas my actual code only does the exceptions following a failure.
The real code has inside the try statement, where I have f(num)
try:
params = scipy.optimize.minimize(stuff)
if params.success:
stuff
except:
continue
Maybe the params.success is throwing it off since that doesn't exist when the scipy.optimize.minimize fails in the middle?
It does not appear to even attempt to do scipy.optimize.minimize on the next iteration once one of the initial guesses has caused scipy to fail.

Related

break statement is not working under a def function of for loop

Iam using break statement but it doesn't bring out of loop ,
I tried to find prime factors of given number but due to malfunctioning of break i cant do it
def fact(x):
for i in range(2,x+1):
if x%i==0:
xx.append(i)
x=x//i
if x==1:
break
else:
print('fact')
fact(x)
a=12
xx=[]
fact(a)
print(xx)
The main issue is that you are "double counting" factors.
having identified a factor, add it and call recursively with the number that results after removing the factor.
At the moment, you do that, but then also look for the next factor in the current function call.
There are of course little ways to improve this some more like skipping over values of i that we know cannot be factors of n and making the function return the array of results itself rather than updating a global, but this will get you going:
With the lightest modification to your existing code what you want to do is:
def fact(x):
for i in range(2,x+1):
if x%i == 0:
xx.append(i)
fact(x//i)
return
xx=[]
fact(12)
print(xx)
This will show you:
[2, 2, 3]

Index out of range in leetcode ide in code for finding the length of the longest substring without repeating characters

This below giving expected output in pycharm and the other side it's getting index out of range in line return length_of_substring[-1] in leetcode.
why it is getting such error?
class Solution:
def lengthOfLongestSubstring(self, string):
unique_list = []
length_of_substring = []
for i in string:
if i not in unique_list:
unique_list.append(i)
else:
length_of_substring.append(len(unique_list))
unique_list.clear()
unique_list.append(i)
length_of_substring.sort()
return length_of_substring[-1]
if __name__ == '__main__':
s = input()
obj = Solution()
result = Solution.lengthOfLongestSubstring(obj, s)
print(result)
First of all: when posting here you should clearly specify (i) the goal of your code and (ii) a self contained minimum example.
In your case it is very difficult to answer your question, because you do not make clear what your code is actually trying to achieve.
Regarding your error message:
Your code does not account for the fact that a string could also consist of only unique elements (e.g. "abcd"). In that case the else clause of your code is never reached and length_of_substring will remain empty. If you then call length_of_substring[-1] it raises an error message.

When i change True to False in the first code my output stays same.Why is that?

My code:
liste = ["345","sadas","324a","14","zxc"]
for i in liste:
try:
int(i) == True #(make it false for example)
print(i)
except:
pass
for i in liste:
try:
i = int(i)
print(i)
except:
pass
output:
345
14
Here as you can see there are two different codes and the question is only write the numbers not letters.(By using try-except). But my question is when i change True to False in the first code my output stays same.Why is that?
This:
int(i) == True #(make it false for example)
first try to make an int of i, and if the operation succeeds, compares it with True, then discard the result of the test. IOW, the whole comparison ends up being a no-op ((functionally speaking - the code is still executed), and could as well be replaced with just
`int(i)`
Of course since the result of the comparison is discarded, you could test against just any value that's comparable with an int (another int, a float, a bool etc), this would make absolutely no difference.
As a side note: this:
try:
something()
except:
pass
is pure evil - it catches absolutely everything (including a SystemExit) and ignore it. I understand this is just a quick test code snippet, but do yourself a favour and never do this in real code - always specify the exact exception(s) you expect and can handle at this point in the code, and if you want to ignore them, at least log them somewhere so you know what really happens in your code.
when i change True to False in the first code my output stays same
Because you're not doing anything with that result, as compared to
if int(i) == True:
print(i)
Or simply
if int(i):
print(i)
But, more appropriate would be
if i.isdigit():
print(i)

Yield stop the action by penetrating a while loop

I read such a minimal demonstration about coroutine A Curious Course on Coroutines and Concurrency
def countdown(n):
print("Counting down from", n)
while n > 0:
yield n
n -= 1
#why it stop?
x = countdown(10)
#no output was produced
I print no result, when first call it.
In [10]: x
Out[10]: <generator object countdown at 0x1036e4228>
but should
In [14]: next(x)
Out[14]: Counting down from 10
In [15]: next(x)
Out[15]: 1
In [16]: next(x)
Why print("Counting down from", n)not executed directly when i invoke the function countdown().
I think the Counting down from 10 should be executed whatever yield, it is a sequential process.
What stop print("Counting down from", n) running, I am aware that
do something yield
yield will stop the action ahead of it,
but in the countdown example, how could yield stop print("Counting down from", n) by penetrating the while loop
If I understand your question correctly, you expect to see the Counting down from 10 text printed out immediately when you call countdown(10). But that reflects a misunderstanding of how generator functions work.
A yield expression isn't something that just interrupts the control flow of a normal function. Rather, any function that contains a yield anywhere in it becomes a generator function, which works differently than a normal function.
When you call a generator function, none of its code runs immediately. Instead, Python just creates a generator object that encapsulates the state of the function call (which at first will just record that you're at the very top of the function which hasn't started running yet). The generator object is what gets returned to the caller.
It is only after you call next on the generator object that function's code starts to run. It will run until it comes to a yield expression, and the value being yielded is what the next will return. The state of the running function is saved as part of the generator object, and it remains paused until you call next on it again.
The important thing to note is that the generator object doesn't ever run ahead of a yield until the outside code is done with the yielded value and asks for another one. We use generator functions specifically because they are lazy!
Here's a simple script that might help you understand how it works better than your example generator that tries to do something more useful:
import time
def generator_function():
print("generator start")
yield 1
print("generator middle")
yield 2
print("generator end")
print("creating the generator")
generator_object = generator_function()
print("taking a break")
time.sleep(1)
print("getting first value")
val1 = next(generator_object)
print("got", val1)
print("taking a break")
time.sleep(1)
print("getting second value")
val2 = next(generator_object)
print("got", val2)
print("taking a break")
time.sleep(1)
print("try getting a third value (it won't work)")
try:
val3 = next(generator_object) # note, the assignment never occurs, since next() raises
print("got", val3) # this line won't ever be reached
except Exception as e:
print("got an exception instead of a value:", type(e))
The print statements from the generator will always appear between the "getting" and "got" messages from the outer code.

Best way to handle exceptions in functon args?

I was recently coding a few Python 3.x programs and I wonder what is the best way of handling simple exceptions in python function args. In this example I'm going with checking if inserted value can be converted to int. I've come up with two ways of doing this:
def test_err_try(x, y, z):
try:
int(x)
int(y)
int(z)
except ValueError or TypeError: #try handler
return 'Bad args.'
##code##
or
def test_err_if(x, y, z):
if type(x) != int or type(y) != int or type(z) != int: #if handler
raise ValueError('Bad args.')
else:
##code##
I know that there is a difference in what the handlers are returning - in the first case it's just string 'Bad args.' and in the second it is ValueError exception.
What is the best (or rather simplest and shortest) way? First, second or neither and there is a better one?
The answer depends on your use case. If you are building a function which will be exposed to an end user, then the try except block offers more functionality because it will allow any variable which can be converted to an int. In this case I would suggest raising an error rather than having the function return a string:
try:
x = int(x)
y = int(y)
z = int(z)
except ValueError:
raise TypeError("Input arguments should be convertible to int")
If the function is meant for internal use within your program, then it is best to use the assert statement because its evaluation can be disabled once you are finished debugging your program.
assert type(x) is int
assert type(y) is int
assert type(z) is int

Resources