How do I implement 2 python range functions at the same time? - python

I have a statement which is working fine.
for i in range(1, 4):
piece = driver.find_element_by_xpath('//*[#id="js_proList"]/ul[1]/li[{}]/div/div[2]/p'.format(i))
piece.click()
time.sleep(2)
driver.back()
After it gets finished with this loop I want to run it again but with /ul[2]. and then /ul[3] and so on...
...//[#id="js_proList"]/ul[2]/...
...//[#id="js_proList"]/ul[3]/...
I can't get the coding for two ranges in the same sentence.
Thanks

You can use a nested for loop.
x = 10 # How many times do you want to loop over /ul[INDEX]
# Outer loop
for j in range(1, x):
# Inner loop
for i in range(1, 4):
piece = driver.find_element_by_xpath('//*[#id="js_proList"]/ul[{}]/li[{}]/div/div[2]/p'.format(j, i))
piece.click()
time.sleep(2)
driver.back()

nested loops of implementation is accurate , you can also try updating xpath dynamically once one iteration is done.

Related

How to restart a for loop

I have a piece of code. Here, I am running a for loop. If the if statement is not met, I want to restart that for loop. How should I do this? sp is a library btw.
for i in range (10000):
#my codes
a= sp.levene(#my variables)
if a[1] < 0.05:
#I want to restart for loop again
else:
#doing something
You probably don't want to use a for loop, since you aren't iterating over a particular sequence of numbers (i is going to jump around based on what happens inside the loop). Using a while you'd do:
i = 0:
while i < 10000:
# my code
a = sp.levene() # my variables
if a[1] < 0.05:
i = 0
continue
i += 1
# doing something
continue restarts the loop at the beginning of the loop body, and having set i = 0 it's now in the same state it was in at the first iteration.
The simplest way to handle this is:
while True:
for i in range(100000):
...
if a[1] < 0.05:
# this will exit out of the for loop, but the while
# loop will keep going
break
else:
....
# if we've successfully finished the "for" loop, then break out of
# the while loop
break
If your logic is a little bit more complicated:
done = False
while not done:
for i in range(100000):
...
if a[1] < 0.05:
# this will exit out of the for loop, but the while
# loop will keep going
break
else:
# set done to True if you've decided you don't need to perform
# the outer loop any more
other stuff
# likewise, set done to True if you're done with the outer while loop
To build on Frank Yellin's answer if you don't want to use break else break.
continueloop=True
while(continueloop):
for i in range (10000):
#my codes
a=sp.levene #my variables
if a[1] < 0.05:
#I want to restart for loop again
continueloop=True
else:
continueloop=False
#doing something
Hope you find a suitable answer!
I think what you are looking to do is have that function inside a loop. If the statement fails then on the else statement call the function again with new parameters. Basically, you want recursion on your loop is what I'm understanding.
def RecursionFunc() #3) when this function is called code runs from here
for i in range (10000):
#my codes
a= sp.levene(#my variables)
if a[1] < 0.05:
RecursionFunc() #2) will make you jump to the top again basically calling itself
break #4) will exit the current loop
else:
RecursionFunc() # 1)This will be the first code that gets executed
And the recursion will keep the function going and you can do plenty of other stuff with this. I know you want to break the loop and run again you can also change the "i" value on the next recursion run. If you give recursionFunc(int i) then you can basically set yours for loop to a new I value on the next run too. Can do a lot of cool things like this.

Getting index in For Loop in python

Hi if i want to know when i reached the last iteration of my
for c in text:
In C it will seem like :
for (int i=0;i<strlen(str);i++)
if (i == strlen(str))
printf("The last index");
The idiomatic way to test whether a loop finished completely (i.e. exhausted its iterable) is to use for with else:
s = 'Hello World!'
for c in s:
# do something with character c, your code might break the loop
pass
else:
# the loop did not break, and iterated over all characters
print('The loop finished!')
My solution would be to create a counter outside the loop and increment it every time the loop iterates so you can have a reference of what the loop index is.
Check out the Python built-in function "enumerate", here is a link: http://book.pythontips.com/en/latest/enumerate.html
You can use the enumerate statement. It is written like this:
for index, val in enumerate(N):
if index + 1 == len(N):
print('The last index')
If you want see in console the state of your loop, you can use tqdm,
from tqdm import tqdm
for i in tqdm(range(N)):
#Some logic here

Is loop "for" prior to "if" statement in Python?

I'm new to a programming language and wanted to start with Python as its the recommendation of most people (as far as i see).
So, im practising on some functions to improve my understanding on loops, and basic statements etc. Though i'm not very good at it yet, i do believe that i'll improve sooner or later.
Here is an example where i'm stuck at:
def L():
List = []
TauS = []
a = 12
for i in range(1,a+1):
if a % i == 0:
List.append(i)
if a % len(List) == 0:
TauS.append(a)
print(List)
print(TauS)
L()
This is the function i want to have and the output is:
[1, 2, 3, 4, 6, 12]
[12]
As i expected.However, the problem is that i want "a" to be a variable instead of a constant.Something like:
def L():
List = []
TauS = []
for a in range(2,20):
for i in range(1,a+1):
if a % i == 0:
List.append(i)
if a % len(List) == 0:
TauS.append(a)
print(List)
print(TauS)
L()
Fails because it seems like for loop is working before the 2nd if statement (if a % len(list)) == 0: TauS.append(a)).I have also tried a "while" loop instead of a "for" loop as:
a = 2
while a <= 20:
for i in range(1,a+1):...(The rest is the same)
It would be a better idea if your help focus on the basic ideas instead of just giving the right function.
Thanks a lot from now!
Regards.
Python uses indention levels to tell whether code is in within a function, loop or condition, the general thing being that if there is a : then all the code indented underneath it is within that statement.
The problem with your code is that the second if statement is on the same indention level as the for loop rather than being on the indention level below the for loop. This means that rather than running in the for loop it runs after it.
So to fix your code all you need to do is select the if statement and press crtl + ] which is pythons keyboard shortcut for indent code section.
edit:
I think what you're asking for is to get all the factors of numbers from 2 to 19 and then print numbers where the number of factors is a factor of that number.
def L():
List = []
TauS = []
for a in range(2,20):
l=[] #this is the list for each individual number
#if i is a factor of a add it to l
for i in range(1,a+1):
if a % i == 0:
l.append(i)
#if length of l is a factor of a add a to TauS
if a % len(l) == 0:
TauS.append(a)
List.append(l)
print(List)
print(TauS)
L()
It fails because of variable scope.
Python uses indention to represent code block. So, here for loop and 2nd if condition has same indention which means they belong to same code block and can access variables defined in the same or the outer code block. "List" & "Taus" in this case.
However, Variable "a" is localize to outer for loop and can be access in the same or inner for loop and cant be access from outside. Similarly variable "i" is specific to inner for loop and cant be access outside of the loops block, not even from outer for loop.
Hope it helps...

While loop gets ignored

Hej Everyone,
The idea of the script is to grab image links from a catalogue page of my company's website and change them to image links with a higher resolution and filter for image format, where the variable to filter for is found in the link itself, in this case the capital P. Afterwards a csv is generated with the links.
The transformation, filtering and writing to csv works fine, but my problem is that I don't want all the 80 products, I only want 8 to be in the list nl.
The links list contains elements like this one https://rndr.mywebsite.com/media/catalog/product/seo-cache/x386/19/95/19-95-101P/How-Hard-You-Hit-Butcher-Billy-Premium-Poster.jpg
NOTE: variables ratio and creatives (inputnumber-1) are defined by commandline input. Just assume that the input was ratio = P and creatives = 9-1.
NOTE2: For quicker testing, the links list has a limit of 15 elements by now.
nl= []
string1= "https://rndr.mywebsite.com/media/catalog/product/cache/x800/"
string2= ".jpg"
while len(nl) <= creatives:
for index in range(len(links)):
if "P" in "".join(links[index].split("/", 12)[10]) and "P" in ratio:
print("YEAH", len(nl))
nl.extend([string1 + "/".join(links[index].split("/", 11)[8:11]) + string2])
else:
print ("Ups", len(nl))
print (nl)
The actual output is
('YEAH', 0)
('YEAH', 1)
('YEAH', 2)
('YEAH', 3)
('Ups', 4)
('YEAH', 4)
('YEAH', 5)
('Ups', 6)
('YEAH', 6)
('YEAH', 7)
('YEAH', 8)
('YEAH', 9)
('YEAH', 10)
('YEAH', 11)
('YEAH', 12)
[https://rndr.mywebsite.com/media/catalog/product/cache/x800/19/95/19-95-101P.jpg, transformed-link2,...,transformed-link12]
As you can see the filtering and transforming works fine, but it should stop after having 9 links in the list nl.
As mentioned by Coldspeed, in the inner loop you're adding a whole batch of items to nl, thus overshooting the limit. To fix it, you could get rid of the while loop and do this instead:
for index in range(len(links)):
if "P" in "".join(links[index].split("/", 12)[10]) and "P" in ratio:
print("YEAH", len(nl))
nl.append(string1 + "/".join(links[index].split("/", 11)[8:11]) + string2)
if len(nl) > creatives:
break
else:
print ("Ups", len(nl))
Adding a couple of print statements like this can help you figure out exactly what is going on:
while len(nl) <= creatives:
print('outer loop')
for index in range(len(links)):
print('inner loop')
...
You've got a nested loop here. What happens is, inside the inner loop, the condition for the outer loop is not checked, until the inner loop has finished iterating. What you'd need to do is put an explicit break inside the inner loop.
Look at this answer for a solution. :)
You're doing a for loop inside the while loop. The while loop will only check its condition upon finishing the first for loop, by which point you've already looped over every element in links.
E.g.
i = 0
while i < 10:
for z in range(20):
i = z
print(i)
will print all the way to 19, because the precondition for the while loop will only be checked when the inner for loop finishes.

Transform a while loop with counter into a more pythonic code

Is there a way to trasform this python code into a more pythonic one?
i = 0
while condition:
doSomething()
i+=1
I use count for this type.
from itertools import count
c = count(0)
while condition:
doSomething()
next(c) # returns 0, +1 in further loops
But if you know how much loops you want, Try for loop.
for i in range(n):
doSomething()
If the condition is about the value of i like "i < 10", you can use "for" statement:
for i in range (10):
do_something ()
This will execute the function 10 times.
To second itzmeontv's answer, I personally do this:
for i in itertools.count():
if not condition:
break
do_something()
Note: Infinite loops are usually to be avoided if possible but, you know what's worse? Manual counters. Especially if they are at the bottom of the loop. That's why I put the condition check at the very top, right under the for loop statement.
However, if you know how many iterations you need, you can just use:
for i in range(100):
do_something()
And replace 100 by the desired amount of iterations.

Categories