While loop code keeps running - python

For some reason this code doesn't print anything and doesn't stop running, can anybody tell me what is going wrong here?
l = [1,2]
i = 0
k = l[i]+l[i+1]
while k <= 10:
l.append(k)
i += 1
print l

The value of k (and therefore the loop condition) is set before the loop using the current value of i (0), and never changes during the loop execution. You would have to reassign k based on the new value for i inside the loop for it to change.

Python evaluates the value of k so that k isn't the expression, but the result of that expression:
k = l[i]+l[i+1] # In your case it's l[0] + l[1] = 3
You probably want to evaluate k every loop:
l = [1,2]
i = 0
for i in range(0, 10 + 1):
l.append(l[i] + l[i + 1])
print l
And just for fun, a more Pythonic Fibonacci sequence generator (literally):
def Fibonacci():
a, b = 0, 1
while True:
yield a
a += b
a, b = b, a
for n in Fibonacci():
raw_input(n)

Just move the line with k in it:
l = [1,2]
i = 0
k = l[i]+l[i+1]
while k <= 10:
l.append(k)
i += 1
k = l[i]+l[i+1]
print l

You're not doing any changes to the k variable. Once you calculate the value of K, the code gets stock in the while loop because the value of k never changes, you simply keep appending the value of k to the list.

not sure about python,
but looks like you update the value of K ever also, not sure what is the scope of the while loop in python syntax.

Related

Heap's Algorithm - Non Recursive Method in Python to generate permutations

I am a newbie to programming. I am working on Heap's Algorithm, specifically non-recursive method. There is not so much explanation available on internet, to how the algorithm works. I found this piece of work from Bernardo Sulzbach but he doesn't explain how his algorithm works. I am stuck on it from days, tried everything couldn't figure it out. I have added comments after each line to make myself understand -- what's happening here? but I still couldn't make it work. Am I doing something wrong? Please help.
# Heap's Algorithm (Non Recursive)
# function to swap values in python
def swap(elements, i, j):
elements[i], elements[j] = elements[j], elements[i]
# function to generate permutation
def generate_permutations(elements, n):
# Passing two parameters of elements and n to function "generate_permutations".
c = [0] * n
# c is a new list and its value set to an array literal with value 0, n times.
# Example - [a] * 3 ==> ['a', 'a', 'a', 'a']
yield elements
# "yield" statement is used to define generators, while "return" statement causes a function to exit.
# "yield" replacing the return of a function to provide a result to its caller without destroying
# local variables. Unlike a function, where on each call it starts with new sets of variables, a generator
# will resume the execution where it left off.
i = 0
# i is a new variable and its value is set to 0. It can also be used to count the number of loop runs.
while i < n:
# while loop ==> while i is less than n, do following:
if c[i] < i:
# if statement ==> while i is less than n and if any element from 'c' list is less than i,
# then do following:
if i % 2 == 0:
# if statement ==> while i is less than n, and if any element in 'c' list is less than i, and
# i is an even number, then do following:
swap(elements, 0, i)
# calling swap function and passing following arguments: elements, '0' and 'i'
else:
# else, if all three conditions above are not true then do following:
swap(elements, c[i], i)
# calling swap funtions and passing following arguments: elements, an item from 'c' list and 'i'
yield elements
# ??? yield elements
c[i] += 1
# after that, increment c[i] by 1.
i = 0
# set the value of i to 0
else:
# else, if c[i] < i is not true the do the following.
c[i] = 0
# set the value of c[i] to 0
i += 1
# and increment i by 1
def permutations(elements):
return generate_permutations(elements, len(elements))
# Driver Code
# c = ?
# n = ?
# i = ?
print(permutations(['abc']))
Just cleaning up your code (too many comments):
# Heap's Algorithm (Non Recursive)
# https://en.wikipedia.org/wiki/Heap%27s_algorithm
def swap(seq, i, j):
seq[i], seq[j] = seq[j], seq[i]
def generate_permutations(seq, seqLen, resLen):
c = [0] * seqLen
yield seq[:resLen]
i = 0
while i < seqLen:
if c[i] < i:
if i % 2 == 0:
swap(seq, 0, i)
else:
swap(seq, c[i], i)
yield seq[:resLen]
c[i] += 1
i = 0
else:
c[i] = 0
i += 1
def permutations(seq, resLen=None):
if not resLen: resLen = len(seq)
return generate_permutations(seq, len(seq), resLen)
for p in permutations([1,2,3]): print(p)
for p in permutations([1,2,3],2): print(p)

While loop not giving desired outcome

New to python here, so not sure if I'm posting in the right place but I was wondering why the following loop does not give an answer. I am trying to add all of the numbers previous to i, (1 + 2 + 3 + ... + i), but the loop I came up with does not complete.
j = 0
i = 17
while i > 0:
j = j + i
i - 1
print(j)
I expect j = 153, but the loop doesn't put out anything.
The issue is with i--you're not properly reducing it by 1, so this is an infinite loop. Try this:
j = 0
i = 17
while i > 0:
j = j + i
i -= 1
print(j)
Notice that your line in the while statement,
i-1, does not assign (= operator) a value to i. i stays 17 forever and ever, and so you see no output because the program gets stuck in your while loop. Try to fix your i assignment, like so:
j = 0
i = 17
while i > 0:
j = j + i
i = i - 1 # <= i = i - 1
print(j)
One way to debug your loop in the future is to put a print statement in the middle, like in the code below. The extra print statements slow your program down a bit, but you'll be able to easily see that your loop is going way more than you want!
j = 0
i = 17
while i > 0:
j = j + i
i = i - 1
print(j)
print(i) # so that we can see that i is going down :P
print(j)
Good luck :)
As noted above, you're not re-assigning to your i within the loop. But I'd also note that it's generally a bad idea to modify an iterator within the iteration loop. You can achieve the expected results in a more pythonic way using a range expression, and wrap it in a function also :)
def foo(max_num):
j = 0
for i in range(max_num+1):
j += i
return j
But even better, without the loop:
def foo(max_num):
return sum(range(max_num+1))
There are a couple of ways to do what you want to do. The way I recommend you do it is as shown below.
total = 0
i = 18
for j in range(i):
total += j
print(total)
The range(i) takes a maximum number i, and allows you to iterate through every number starting from 0 to i-1 (e.g. i = 5 will add numbers 0,1,2,3,4), therefore always make i one more than you need it to be if you want to be if you want to include the max number.
As already stated i - 1 wasn't assigned back to i
Following is a pythonic way of implementing the loop with a list comprehension
Code:
j = 0
i = 17
j = sum([j + x for x in range(i, 0, -1)])
print(j)
>>> 153
As a Function:
def sum_of_steps(start: int, stop: int, step: int) -> int:
return sum([x for x in range(start, stop, step)])
j = sum_of_steps(17, 0, -1)
print(j)
>>> 153
The function, sum_of_steps uses type hints or function annotations.
Python Basics: List Comprehensions

Python : iterating over a list

With my code I would except that after looping one time he will jump to the next number in the list, but he doesn't. Anyone knows what is wrong with my code?
for j in range(len(k)):
s = [int(i) for i in str(k[j])]
This two lines of code are part of a bigger question I am solving.
def kaprekarseries(n):
"""
>>> kaprekar_series(677)
[677, 99, 0]
>>> kaprekar_series(9876)
[9876, 3087, 8352, 6174]
>>> kaprekar_series(55500)
[55500, 54945, 50985, 92961, 86922, 75933, 63954, 61974, 82962]
"""
k = list()
k.append(n)
count = 0
while count < 10:
for j in range(len(k)):
s = [int(i) for i in str(k[j])]
m = sorted(s, key=int, reverse=True)
m2 = int(''.join(str(i) for i in m))
l = sorted(s, key=int)
l2 = int(''.join(str(i) for i in l))
g = m2 - l2
k.append(g)
if [item for item in k if k.count(item) <= 1]:
count += 1
else:
return k
Your list k has just one element being appended prior to starting the loop. Therefore it is list of length of one, therefore it runs just once.
Rethink your algorythm.

Removing Negative Elements in a List - Python

So, I`m trying to write a function that removes the negative elements of a list without using .remove or .del. Just straight up for loops and while loops. I don`t understand why my code doesn`t work. Any assistance would be much appreciated.
def rmNegatives(L):
subscript = 0
for num in L:
if num < 0:
L = L[:subscript] + L[subscript:]
subscript += 1
return L
Why not use list comprehension:
new_list = [i for i in old_list if i>=0]
Examples
>>> old_list = [1,4,-2,94,-12,-1,234]
>>> new_list = [i for i in old_list if i>=0]
>>> print new_list
[1,4,94,234]
As for your version, you are changing the elements of the list while iterating through it. You should absolutely avoid it until you are absolutely sure what you are doing.
As you state that this is some sort of exercise with a while loop, the following will also work:
def rmNegatives(L):
i = 0
while i < len(L):
if L[i]<0:
del L[i]
else:
i+=1
return L
You could also use filter, if you so please.
L = filter(lambda x: x > 0, L)
A note to your code:
L = L[:subscript] + L[subscript:]
does not change your list. For example
>>> l = [1,2,3,4]
>>> l[:2] + l[2:]
[1, 2, 3, 4]
Other mistakes:
def rmNegatives(L):
subscript = 0
for num in L: # here you run over a list which you mutate
if num < 0:
L = L[:subscript] + L[subscript:] # here you do not change the list (see comment above)
subscript += 1 # you have to do this only in the case, when you did not remove an element from the list
return L
A running code would be:
def rmNegatives(L):
subscript = 0
for num in list(L):
if num < 0:
L = L[:subscript] + L[subscript+1:]
else:
subscript += 1
return L
See the solutions of #Aesthete and #sshashank124 for better implementations of your problem...

Problem with a Python function

Well I have a little problem. I want to get the sum of all numbers below to 1000000, and who has 4 divisors...
I try, but i have a problem because the GetTheSum(n) function always returns the number "6"...
This is my Code :
http://pastebin.com/bhiDb5fe
The problem seems to be that you return as soon as you find the first number (which is 6).
You have this:
def GetTheSum(n):
k = 0
for d in range(1,n):
if NumberOfDivisors(d) == 4:
k += d
return k
But you have probably meant this:
def GetTheSum(n):
k = 0
for d in range(1,n):
if NumberOfDivisors(d) == 4:
k += d
return k

Categories