How to store a number as a variable - python

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

Related

try/except while true in a for loop

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)

How to jump out the current while loop and run the next loop whenever meeting a certain condition?

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.

Using Python, how can I try - except a few different inputs in a single function, where if one fails, the remainder still get processed?

I am quite a novice at Python still, so I apologize if this is a novice question. I have this piece of code in my program:
entryBox1 = "not a number"
entryBox2 = 27
def setValues():
content = entryBox1.get()
if content != "":
try:
int(content)
currentValuePumpOn.set(content)
except ValueError:
return
content = entryBox2.get()
if content != "":
try:
int(content)
currentValuePumpOff.set(content)
except ValueError:
return
entryBox1.delete(0, 99)
entryBox2.delete(0, 99)
For simplicity, I have added the variables entryBox1 and entryBox2 in a format that I might expect the user to put in.
Basically, I want to receive input in 2 or more tkinter entry boxes, and when a button is pushed, it looks at the inputs in all the entry boxes and only assigns those inputs to their associated values if they are integers. If one or more is not an integer, it just skips over that input and carries on. Once all the inputs have been looked at, valid or not, it blanks the entrybox (with entryBox1.delete(0,99))
At the moment, if I were to use the variables above, the string "not a number" would prevent any further variables from being tested for validity.
Based on my prior reading, I think I could get the result I want by putting the try/except args in a for loop, but I'm not certain how to go about that. Any advice would be appreciated.
Just use a for loop and don't return in the except block.
EDIT: As #TaraMatsyc points, add the currentValuePumpOn/Off to the loop also.
def setValues():
for eBox, currentValuePump in ((entryBox1, currentValuePumpOn),
(entryBox2, currentValuePumpOff)):
content = eBox .get()
if content != "":
try:
int(content)
currentValuePump.set(content)
except ValueError:
pass
eBox.delete(0, 99)

Nested Loop 'If'' Statement Won't Print Value of Tuple

Current assignment is building a basic text adventure. I'm having trouble with the following code. The current assignment uses only functions, and that is the way the rules of the assignment state it must be done.
def make_selections(response):
repeat = True
while repeat == True:
selection = raw_input('-> ')
for i, v in enumerate(response):
i +=1 # adds 1 to the index to make list indices correlate to a regular 1,2,3 style list
if selection == i:
print v[1]
else:
print "There's an error man, what are you doing?!?!?"
firstResponse = 'You chose option one.'
secondResponse = 'You chose option two.'
thirdResponse = 'You chose option three.'
responses = [(0, firstResponse), (1, secondResponse),( 0, thirdResponse)]
make_selections(responses)
My intention in that code is to make it so if the user selects a 1, it will return firstResponse, if the user selects 2 it will return secondResponse, etc.
I am basically just bug testing the code to make sure it produces the appropriate response, hence the "Error man..." string, but for some reason it just loops through the error message without printing the appropriate response string. Why is this?
I know that this code is enumerating the list of tuples and I can call them properly, as I can change the code to the following and get the expected output:
for i, v in enumerate(response):
i += 1 # adds 1 to the index to make list indices correlate to a regular 1,2,3 style list
print i, v
Also, two quick asides before anyone asks:
I know there is currently no way to get out of this while loop. I'm just making sure each part of my code works before I move on to the next part. Which brings me to the point of the tuples.
When I get the code working, a 0 will produce the response message and loop again, asking the user to make a different selection, whereas a 1 will produce the appropriate response, break out of the loop, and move on to the next 'room' in the story... this way I can have as many 'rooms' for as long of a story as I want, the player does not have to 'die' each time they make an incorrect selection, and each 'room' can have any arbitrary amount of options and possible responses to choose from and I don't need to keep writing separate loops for each room.
There are a few problems here.
First, there's no good reason to iterate through all the numbers just to see if one of them matches selection; you already know that will be true if 1 <= selection <= len(response), and you can then just do response[selection-1] to get the v. (If you know anything about dicts, you might be able to see an even more convenient way to write this whole thing… but if not, don't worry about it.)
But if you really want to do this exhaustive search, you shouldn't print out There is an error man after any mismatch, because then you're always going to print it at least twice. Instead, you want to only print it if all of them failed to match. You can do this by keeping track of a "matched" flag, or by using a break and an else: clause on your for loop, whichever seems simpler, but you have to do something. See break and continue Statements, and else Clauses on Loops in the tutorial for more details.
But the biggest problem is that raw_input returns a string, and there's no way a string is ever going to be equal to a number. For example, try '1' == 1 in your interactive interpreter, and it'll say False. So, what you need to do is convert the user's input into a number so you can compare it. You can do that like this:
try:
selection = int(selection)
except ValueError:
print "That's not a number!"
continue
Seems like this is a job for dictionaries in python. Not sure if your assignment allows this, but here's my code:
def make_selections(response):
selection = raw_input('-> ')
print response.get(selection, err_msg)
resp_dict = {
'1':'You chose option one.',
'2':'You chose option two.',
'3':'You chose option three.'
}
err_msg = 'Sorry, you must pick one of these choices: %s'%sorted(resp_dict.keys())
make_selections(resp_dict)
The problem is that you are comparing a string to an integer. Selection is raw input, so it comes in as a str. Convert it to an int and it will evaluate as you expect.
You can check the type of a variable by using type(var). For example, print type(selection) after you take the input will return type 'str'.
def make_selections(response):
repeat = True
while repeat == True:
selection = raw_input('-> ')
for i, v in enumerate(response):
i +=1 # adds 1 to the index to make list indices correlate to a regular 1,2,3 style list
if int(selection) == i:
print v[1]
else:
print "There's an error man, what are you doing?!?!?"

Loop thru a list and stop when the first string is found

I have a list and I want to extract to another list the data that exist between top_row and bottom_row.
I know the top_row and also that the bottom_row corresponds to data[0] = last integer data (next row is made of strings, but there are also rows with integers which I'm not interested).
I've tried several things, but w/o success:
for row,data in enumerate(fileData):
if row > row_elements: #top_row
try:
n = int(data[0])
aux = True
except:
n = 0
while aux: #until it finds the bottom_row
elements.append(data)
The problem is that it never iterates the second row, if I replace while with if I get all rows which the first column is an integer.
fileData is like:
*Element, type=B31H
1, 1, 2
2, 2, 3
.
.
.
359, 374, 375
360, 375, 376
*Elset, elset=PART-1-1_LEDGER-1-LIN-1-2-RAD-2__PICKEDSET2, generate
I'm only interested in rows with first column values equal to 1 to 360.
Many thanks!
The code you've posted is confusing. For example, "aux" is a poorly-named variable. And the loop really wants to start with a specific element of the input, but it loops over everything until it finds the iteration it wants, turning what might be a constant-time operation into a linear one. Let's try rewriting it:
for record in fileData[row_elements:]: # skip first row_elements (might need +1?)
try:
int(record[0])
except ValueError:
break # found bottow_row, stop iterating
elements.append(record)
If no exception is thrown in the try part, then you basically end up with an endless loop, given that aux will always be True.
I’m not perfectly sure what you are doing in your code, given the way the data looks isn’t clear and some things are not used (like n?), but in general, you can stop a running loop (both for and while loops) with the break statement:
for row, data in enumerate(fileData):
if conditionToAbortTheLoop:
break
So in your case, I would guess something like this would work:
for row, data in enumerate(fileData):
if row > row_elements: # below `top_row`
try:
int(data[0])
except ValueError:
break # not an int value, `bottom_row` found
# if we get here, we’re between the top- and bottom row.
elements.append(data)
Will this work?
for row, data in enumerate(fileData):
if row > row_elements: #top_row
try:
n = int(data[0])
elements.append(data)
except ValueError:
continue
Or what about:
elements = [int(data[0]) for data in fileData if data[0].isdigit()]
By the way, if you care to follow the convention of most python code, you can rename fileData to file_data.
Use a generator:
def isInteger(testInput):
try:
int(testInput)
return True
except ValueError: return False
def integersOnly(fileData):
element = fileData.next()
while isInteger(element):
yield element
element = fileData.next()

Categories