The following code will gather data from an API and the try/except clause will help to handle several errors (from authentication, index, anything).
There's only one error (an authentication error) that I'm using the while True to repeat the API call to make sure I get the data and it will after a try or two. However if by any means I get another error, it'll be infinitely looping and I can't break it so it goes to the next iteration. I tried to create a counter and if the counter reaches to a number then (pass or continue or break) but it's not working.
## Create a array to loop to:
data_array_query = pd.date_range(start_date,end_date,freq='6H')
#This is my idea but is not working
#Create a counter
counter = 0
#Loop through the just created array
for idx in range(len(data_array_query)-1):
## If counter reaches move on to next for loop element
while True:
if counter>=5:
break
else:
try:
start_date = data_array_query[idx]
end_date = data_array_query[idx+1]
print('from',start_date,'to',end_date)
df = api.query(domain, site_slug, resolution, data_series_collection, start_date=str(start_date), end_date=str(end_date), env='prod', from_archive=True, phase='production').sort_index()
print(df.info())
break
except Exception as e:
print(e)
counter +=1
print(counter)
So the output of running this code for a couple of days show that when it runs 5 times (that's the counter max I set up) it does break but it breaks the whole loop and I only want it to move to the next date.
Any help will be appreciated,
You need to use a break statement to get out of a while True loop. pass and continue work for for loops that have a fixed number of iterations. While loops can go on forever (hence the different names)
Related
I have this code below that runs on a page, finds the element input-optionXXX where XXX is a 3 digit number that changes between 300 and 400, and clicks on it. I would like to store the numeric value that it finds on the page so that i can use that straight away in my other lines of code. Right now, in the section print(i), it shows the correct value. I just need some way of storing that value.
for i in range(300, 400):
try:
driver.find_element_by_id(f'input-option{i}').click()
print(i)
except NoSuchElementException:
continue
If I understand the intention of your code correctly, assigning the value to a new variable that is not i, and then breaking out of the for loop should do the trick. As long as you do not need to continue looking for "input-optionXXX", this should work, as break will only be reached if the try: succeeded which it would only do if it manages to find "input-optionXXX"
for i in range(300, 400):
try:
driver.find_element_by_id(f'input-option{i}').click()
number = i
break
except NoSuchElementException:
continue
The Python script that I am using is not exactly as below, but I just want to show the logic. Let me explain what I am trying to do: I have a database, and I want to fetch one population (a number A) a time from the database until all numbers are fetched. Each time fetching a number, it does some calculations (A to B) and store the result in C. After all fetched, the database will be updated with C. The while condition just works like a 'switch'.
The thing is that I don't want to fetch a negative number, so when it does fetch one, I want to immediately jump out the current loop and get a next number, until it is not a negative number. I am a beginner of Python. The following script is what I could write, but clearly it doesn't work. I think something like continue, break or try+except should be used here, but I have no idea.
for _ in range(db_size):
condition = True
while condition:
# Get a number from the database
A = db.get_new_number()
# Regenerate a new number if A is negative
if A < 0:
A = db.get_new_number()
B = myfunc1(A)
if B is None:
continue
C=myfunc2(B)
db.update(C)
Use a while loop that repeats until the condition is met.
for _ in range(db_size):
condition = True
while condition:
# Get a number from the database
while True:
A = db.get_new_number()
if A is None:
raise Exception("Ran out of numbers!")
# Regenerate a new number if A is negative
if A >= 0:
break
B = myfunc1(A)
if B is None:
continue
C=myfunc2(B)
db.update(C)
My code assumes that db.get_new_number() returns None when it runs out. Another possibility would be for it to raise an exception itself, then you don't need that check here.
Hi everyone first time poster long term reader.
my problem is I want an else statment to loop inside a for loop.
I want the else statment to loop until the if statment above it is met?
can anyone tell me where I am going wrong I have tried so many diffrent ways including while loops inside if statments cant get my head round this ?
edit changed the code to a while loop not on prunes suggestion but cant escape the while loop
for url in results:
webdriver.get(url)
try:
liked = webdriver.find_elements_by_xpath("//span[#class=\"glyphsSpriteHeart__filled__24__red_5 u-__7\" and #aria-label=\"Unlike\"]")
maxcount = 0
while not liked:
sleep(1)
webdriver.find_element_by_xpath('//span/button/span').click()
numberoflikesgiven += 1
maxcount += 1
print'number of likes given : ',numberoflikesgiven
sleep(2)
webdriver.find_element_by_link_text('Next').click()
if maxcount >= 10:
print('max count reached .... moving on.')
continue
else:
print ('picture has already been liked...')
continue
Yes, you very clearly wrote an infinite loop:
while not liked:
... # no assignments to "liked"
You do not change the value of liked anywhere in the loop. You do not break the loop. Thus, you have an infinite loop. You need to re-evaluate liked on each iteration. A typical way to to this is to duplicate the evaluation at the bottom of the loop
sleep(2)
webdriver.find_element_by_link_text('Next').click()
liked = webdriver.find_elements_by_xpath(
"//span[#class=\"glyphsSpriteHeart__filled__24__red_5 u-__7\" \
and #aria-label=\"Unlike\"]")
Also note that your continue does nothing, as it's at the bottom of the loop. Just let your code reach the bottom naturally, and the whilewill continue on its own. If you intended to go to the next iteration offor url in results, then you need tobreakthewhile` loop instead.
I'm trying to increase the count of an integer given that an if statement returns true. However, when this program is ran it always prints 0.I want n to increase to 1 the first time the program is ran. To 2 the second time and so on.
I know functions, classes and modules you can use the global command, to go outside it, but this doesn't work with an if statement.
n = 0
print(n)
if True:
n += 1
Based on the comments of the previous answer, do you want something like this:
n = 0
while True:
if True: #Replace True with any other condition you like.
print(n)
n+=1
EDIT:
Based on the comments by OP on this answer, what he wants is for the data to persist or in more precise words the variable n to persist (Or keep it's new modified value) between multiple runs times.
So the code for that goes as(Assuming Python3.x):
try:
file = open('count.txt','r')
n = int(file.read())
file.close()
except IOError:
file = open('count.txt','w')
file.write('1')
file.close()
n = 1
print(n)
n += 1
with open('count.txt','w') as file:
file.write(str(n))
print("Now the variable n persists and is incremented every time.")
#Do what you want to do further, the value of n will increase every time you run the program
NOTE:
There are many methods of object serialization and the above example is one of the simplest, you can use dedicated object serialization modules like pickle and many others.
If you want it to work with if statement only. I think you need to put in a function and make to call itself which we would call it recursion.
def increment():
n=0
if True:
n+=1
print(n)
increment()
increment()
Note: in this solution, it would run infinitely.
Also you can use while loop or for loop as well.
When you rerun a program, all data stored in memory is reset. You need to save the variable somewhere outside of the program, on disk.
for an example see How to increment variable every time script is run in Python?
ps. Nowadays you can simply do += with a bool:
a = 1
b = True
a += b # a will be 2
I created below for loop to run a function to get price data from pandas for a list of tickers. Basically, the loop will re-run the function if getting RemoteDataError and ignore that error after 3 times attempts.
Even though below for loop is working fine for this purpose, I do think there have a better solution since I can not define the times of attempts from below loop, like putting a while loop for times of attempt outside the for loop. I tried to define a variable named attempts = 0, every time it re-run, one attempts will be added. The logic is attempts += 1. If attempts reached 3, use continue to ignore the error. However, it didn't work. Probably I set something wrongly.
for ticker in tickers:
print(ticker)
try:
get_price_for_ticker()
except RemoteDataError:
print('No information for {}'.format(ticker))
try:
get_price_for_ticker()
print('Got data')
except RemoteDataError:
print('1st with no data')
try:
get_price_for_ticker()
print('Got data')
except RemoteDataError:
print('2nd with no data')
try:
get_price_for_ticker()
print('Got data')
except RemoteDataError:
print('3rd with no data (should have no data in the database)')
continue
Is there a better method for this purpose?
Is there a better method for this purpose?
Yes, there is. Use a while loop and a counter.
count = 0
while count < 3:
try:
get_price_for_ticker()
break # reach on success
except RemoteDataError:
print('Retrying {}'.format(count + 1))
count += 1 # increment number of failed attempts
if count == 3:
... # if count equals 3, the read was not successful
This code should go inside your outer for loop. Alternatively, you could define a function with the while + error handling code that accepts a ticker parameter, and you can call that function at each iteration of the for loop. It's a matter of style, and upto you.