why my code stop in secound while loop? - python

#hello , i wounder why my code keep stoping at the secound while loop and doesn't do anything
print"*******************************"
a = 0
deg_list =[]
deg_list_a=[]
deg_list_b=[]
deg_list_c=[]
degree=input("Enter the students Degree:")
while a<=degree:
deg_list.append(degree);
degree=input("Enter the students Degree:")
print "Degree List :",deg_list
print len(deg_list)
while len(deg_list)>=0:
if deg_list[a]>=16:
deg_list_a.append(deg_list[a])
x=+1
elif 15>deg_list[a]>=10:
deg_list_b.append(deg_list[a])
x=+1
else :
deg_list_b.append(deg_list[a])
x=+1
print deg_list_a
print deg_list_b
print deg_list_c

Your code enters an endless loop.
Both of your while loops have problems with the condition which allows them to terminate. Since your code never changes the value of a, the first loop becomes while 0<=degree, and so the first loop terminates when the user inputs a negative value. But the variable a can be removed from your program.
The while loop continues as long as len(deg_list) >= 0. However, no code within the loop decreases the length of deg_list, so the while loop continues forever.
The code below could help you get this working:
deg_list =[]
deg_list_a=[]
deg_list_b=[]
deg_list_c=[]
degree=input("Enter the students Degree:")
while degree > 0:
deg_list.append(degree);
degree=input("Enter the students Degree:")
print len(deg_list)
while len(deg_list) > 0: # Strictly greater than 0, not equal to 0.
if deg_list[0] >= 16:
# Use pop to access first element
deg_list_a.append(deg_list.pop(0))
elif deg_list[0] >= 10: # One comparison per statement, only.
deg_list_b.append(deg_list.pop(0))
else:
deg_list_c.append(deg_list.pop(0)) # c, not b.
print deg_list_a
print deg_list_b
print deg_list_c

You're never modifying deg_list, so your loop becomes infinite. Even removing all elements wouldn't help since you're comparing against 0 -- the loop condition will never be false.

Well.
It looks to me that a is set to 0 in the beginning and then never changed, so doing something with deg_list[a], that is the first element in the list, isn't going to do very much. In addition, your looping condition is len(deg_list) >= 0, and len(deg_list) will never change.
But there are more fundamental issues with your code. Imagine you were changing the length of deg_list: in this case you would be changing the very list you're looping over, which is usually (if you are not very very certain what you're doing) a recipe for disaster. What I think you should envisage doing is a loop along the lines of:
for degree in deg_list:
if [degree fulfils some condition]:
[do something with degree]
elif [degree fulfils some other condition]:
[do something else]
...
else:
[whatever]
Last, from your comparison it seems that the "degrees" are all small integers. You may want to test for that -- it's user input and you have to expect anything being thrown at your input -- before doing things like if degree >= 16.

It looks like you are trying to loop through all the members of deg_list, but you are waiting for deg_list to be empty, and each time through the loop you are incrementing "x," which is never even read.
If you really are trying to traverse through deg_list, try this for your second loop:
for degree in deg_list:
if degree >= 16:
deg_list_a.append(degree)
elif degree >= 10:
deg_list_b.append(degree)
else :
deg_list_c.append(degree)

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.

Moving Average Function

I am learning Python and one of the exercises from the course I am taking is to create a function that calculates the moving average of all elements in a vector, given a window of elements. The only exceptional cases is near the edges where there are not enough neighbours then the edge value must be repeated.
I wrote the following function, which is not working:
%reset -f
def moving_window_average(x, n_neighbors):
mavg=[]
i=0
while i<=len(x):
sumv=[x[i]]
j = n_neighbors
while j>0:
if (i-j)<0:
sumv.append(x[i])
sumv.append(x[i+j])
j-=1
elif (i+j)>len(x):
sumv.append(x[i])
sumv.append(x[i-j])
j-=1
else:
sumv.append(x[i-j])
sumv.append(x[i+j])
j-=1
mavg_i=sum(sumv)/len(sumv)
mavg.append(mavg_i)
i+=1
return mavg
x = [0,10,5,3,1,5]
print(moving_window_average(x, 1))
But when I run line by line it works (like below) it works fine for me
mavg=[]
i=0
#while i<=len(x):
i<=len(x)
sumv=[x[i]]
j=1
#while j>0
j>0
#
(i-j)<0
sumv.append(x[i])
sumv.append(x[i+j])
j-=1
#
(i+j)>len(x)
sumv.append(x[i])
sumv.append(x[i-j])
j-=1
# else
sumv.append(x[i-j])
sumv.append(x[i+j])
j-=1
mavg_i=sum(sumv)/len(sumv)
mavg.append(mavg_i)
i+=1
Can someone please help me? I reckon the solution must be rather simple, but I cannot understand what is wrong in my function.
Thank you.
In your code, when you are using while loop, you are making a small mistake.
Since you are typically in a while loop and you are checking a list length as a reference to limit loop count, one needs to be very careful.
In python element count starts with zero, so you should stop before one value or count less than the length of any list len(list).
Just remove = sign from outer while loop and your code will work.
def moving_window_average(x, n_neighbors):
mavg=[]
i=0
while i < len(x):
sumv=[x[i]]
...
...
Note : Use for loop here, it's safer than while loop.
First of all you shouldn't have while i<=len(x): since the index len(x) is outside the range of valid values in x.
You have some logic error when the neighbor falls out of the array. That is instead of sumv.append(x[i]) when (i-j)<0 you should append x[0]. The same with the second condition where you should take the last element x[-1] (the condition here should be (i+j) >= len(x)).
Also, since you are doing a course you should strive to write more pythonic code, try to replace the while with a for first, and see if you can get rid of that too, afterwards.
Your complexity right now is O(N*K) where N is the length of the array and K is the number of neighbors, it can be reduced to just O(N) ;)
you're going out of bounds.
sumv.append(x[i+j])
IndexError: list index out of range
You are checking if i+j > len(x)
But it should be i+j >= len(x) as the indexing starts from 0 and not from 1.
Also, I see you are learning python. While your program might work, mess around with it in order to make it shorter: Use for loops to iterate over lists, for example

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...

returning indices using a while loop

I'm trying to take an input of a list of numbers and return the list of indices in the original list that contain negative values. I also want to use a while loop. Here is my code so far.
def scrollList2(myList):
negativeIndices = []
i = 0
while i < len(myList):
if myList[i] < 0:
i = i + 1
negativeIndices.append(i)
return negativeIndices
How to I stop the loop and how do i get the indices to return? Right now when I run it, it runs forever (infinite loop) how do I tell it to stop once it hits the last indices of myList?
When you hit your first non-negative number, the if is never entered again and i never gets incremented again. Put the part where you increment i outside the if block.
while i < len(myList):
if myList[i] < 0:
i = i + 1
negativeIndices.append(i)
Assume, the conditional myList[i] < 0 is not true. In that case, i won’t be incremented and nothing else happens either. So you will end up in the next iteration, with the same value of i and the same conditional. Forever, in an endless loop.
You will want to increment i regardless of whether you matched something or not. So you will have to put the increment outside of the if conditional. Furthermore, you want to increment i after appending the index to the list, so you actually append the index you tested, and not the one afterwards:
while i < len(myList):
if myList[i] < 0:
negativeIndices.append(i)
i = i + 1
Also, you would usually use a for loop here. It will automatically take care of giving you all the values of i which you need to index every element in myList. It works like this:
negativeIndices = []
for i in range(len(myList)):
if myList[i] < 0:
negativeIndices.append(i)
range(len(myList)) will give you a sequence of values for every number from zero to the length of the list (not including the length itself). So if your list holds 4 values, you will get the values 0, 1, 2 and 3 for i. So you won’t need to take care of incrementing it on your own.
Another possibility would be enumerate as Foo Bar User mentioned. That function will take a sequence, or list in your case, and will give you both an index and the value at the same time:
negativeIndices = []
for i, value in enumerate(myList):
if value < 0:
negativeIndices.append(i)
As you can see, this completely removes the need to even access the list by its index.
OP wants to use a while loop, so this answer is not exactly on point - but I feel I should point out that many pythonistas will expect something like:
neg_indices = [k for k,v in enumerate(myList) if v < 0]
This is implicit in the other answers, however it might be useful for lurkers and for OP to consider down the road... While certainly does the job as the other answers show, but its 'free' in a list comprehension; plus, there's no chance of an infinite loop here....

Function running way too slow

I am practicing Python with Project Euler, question 1, but the function I wrote to solve it is taking way too long.
I figure it's because the way I coded it not the actual method itself.
When I run this function with 10 or 15 iterations it spits out an answer instantly, but as soon as I jump it up to even 20, it doesn't show me anything for even minutes.
This is obviously a big problem if I need to go to 1000 iterations.
def pe1(n):
counter = 1
total = 0
while counter < n:
if counter%3==0:
total=total+counter
if counter%5==0:
if counter%3==0:
continue
total=total+counter
if counter % 25 == 0:
print (total)
counter=counter+1
return (total)
Because as soon as counter hits 15, your loop goes into an infinite continue - it's always going to hit the second if statement's case.
You need to move your counter = counter + 1 line before the continue, or better yet, use something like for counter in range(1,n).
Consider the case if counter equals 15 and look at what happens where counter%5==0 and counter%3==0, which will first occur at that time.
Consider also what will not happen for that value of counter, specifically, the line counter=counter+1 won't be executed.
To avoid traps like this one, consider using
if ...
elif ...
elif ...
else ...
You can use table-driven. Like this.
counter_map = {3:fun1, 5:func2, 25:fun3} # key is remainder.Of course,fun can be replaced with lambda.

Categories