So I was doing while loops and I noticed something strange.
count = 0
while count <= 5:
count += 1
print(count)
output:
1
2
3
4
5
6
it's not that I don't understand while loops. It's that how come the count is printed up to six? when it's supposed to print count only if count is less than or equal to 5?
and well 6 is beyond 5. why is this?
I know I could do
count = 0
while count != 5:
count += 1
print(count)
but I just want to understand why does putting <= behave in an odd way?
There is nothing odd about <=; your loop condition allows for numbers up to and including 5. But you increment count and then print it, so you will print 6 last.
That's because count = 5 satisfies your loop condition, then you add one to make it 6 and print. The next time through the loop count <= 5 is no longer true and only then loop ends.
So your code does this:
count = 0, count <= 5 -> True, count += 1 makes count = 1, print 1.
count = 1, count <= 5 -> True, count += 1 makes count = 2, print 2.
count = 2, count <= 5 -> True, count += 1 makes count = 3, print 3.
count = 3, count <= 5 -> True, count += 1 makes count = 4, print 4.
count = 4, count <= 5 -> True, count += 1 makes count = 5, print 5.
count = 5, count <= 5 -> True, count += 1 makes count = 6, print 6.
count = 6, count <= 5 -> False, end the loop.
You could increment the counter after printing:
while count <= 5:
print(count)
count += 1
or you could use < to only allow numbers smaller than 5:
while count < 5:
count += 1
print(count)
Let's walk through the code and see what's happening.
Note: If your code is doing something that you didn't expect it to do, this is a good practice to follow.
count = 0
while count <= 5:
count += 1
print(count)
The count starts at 0
count = 0
while count <= 5: # count = 0. Is 0 <= 5? Yes. Run the code.
count += 1
print(count)
Increment the count so it now equals 1. Print it.
while count <= 5: # count = 1. Is 1 <= 5? Yes. Run the code.
count += 1
print(count)
Increment. Print. Repeat.
Let's move on to the interesting case that's causing the problem.
while count <= 5: # count = 5. Is 5 <= 5? Yes. Run the code.
count += 1
print(count)
In this case the count still satisfies the inequality, so the code runs.
What happens?
The count, which is 5, is incremented and thus prints out 6.
Now that I hope you understand why the problem exists, let's explore alternatives and their advantages, disadvantages, and outputs.
Let's start with your code.
count = 0
while count <= 5:
count += 1
print(count)
Advantages: Does not print out 0
Disadvantages: Prints out 6
What if we removed the = sign?
count = 0
while count < 5:
count += 1
print(count)
Output:
1
2
3
4
5
Advantages: Does what you want
Disadvantages: You have to start at 0 instead of 1
What if we did as you suggested and replaced the < sign with the ! sign?
count = 0
while count != 5:
count += 1
print(count)
Output:
1
2
3
4
5
Advantages: Does what you want
Disadvantages: Fragile. If you ever changed your increment so that it increased by a number like, say, 3, the end point would be skipped over accidentally and the code would continue to run forever. Better to use an inequality
What if we wanted where we start to be the first number that is displayed? Well, to do this we'd have to print out the current number before we change it, so that means we have to flip the order of the events.
count = 1 # Change the first number so it's what we want displayed first.
while count <= 5:
print(count)
count += 1
Output:
1
2
3
4
5
Advantages: Does what you want and starts on the first displayed number instead of below it.
Disadvantages: If you want to stick with while loops, this is the way to go, but there is a better way in this case.
In situations like this, where you increment numbers and then perform operations with them, it's much more logical to just use a for loop, which was designed for instances just like this one.
for count in range(1,5):
print(count)
Output:
1
2
3
4
5
Advantages: Does what you want, easier to read, easier to write, less likely to cause bugs based on placement.
Disadvantages: The upper boundary must be known, unlike in a while loop.
It is simple when count equals five you add 1 and it becomes 6 then it is printed and you exit the loop.
Your problem is not about how <= works.
You are adding 1 to count before printing it, so when count is equal to 5, you then add 1 and therefore print 6.
To make things clear i will show the two scenarios with concrete explanation:
a=0
while (a<4):
a=a+1
print(a)
output would be 1,2,3,4
Variable a=0 should satisfy the condition(a<4) of while loop to continue the execution.
a=a+1 is calculated and saved in memory of the loop which is now 1.
Therefore the number 1 would be outputted not 0 as a result of print(a).
In order to iterate again inside the loop; the number 1(that was saved in the memory of the first loop is checked against the a<4 condition). Which is True; continue execution as previous.
a=a+1 calculated and saved in memory of loop which is now 2.
Then the number 2 is outputted
and is saved in the memory of the second loop and checked afterwards against the a<4). Which is True; continue execution as previous.
a=a+1 calculated and saved in memory of loop which is now 3.
Then the number 3 is outputted
and is saved in the memory of the third loop which is checked afterwards against the a<4). Which is True; continue execution as previous.
a=a+1 calculated and saved in memory of loop which is now 4.
Then the number 4 is outputted, even though the condition a<4 should be satisfied. The reason is that, i have stuck inside the loop after satisfaction of previous condition 3<4 and now after i am inside the loop, the execution of the statements is inevitable which will hold to output 4. The number 4 is now saved in the memory of the fourth loop which is checked against the a<4). Which is False, execution stop here.
This scenario would be amenable and understandable to the case of the opposite scenario
a=0
while (a<4):
print(a)
a=a+1
Output would be 0,1,2,3
Variable a=0 should satisfy the condition(a<4) of while loop to continue the execution.
First the print statement is executed, and the first value coined by a in the memory of the first loop is 0. Therefore 0 is outputted.
Afterwards a=a+1 is calculated and saved in memory of the loop which will change to be 1 and not 0.
In order to iterate again inside the loop; the number 1(that was saved in the memory of the first loop is checked against the a<4 condition). Which is True; continue execution as previous.
The print statement is executed, and the value coined by a in the memory of the second loop is now 1. Therefore 1 is outputted.
Afterwards a=a+1 is calculated and saved in memory of the loop which is now 2.
In order to iterate again inside the loop; the number 2(that was saved in the memory of the second loop is checked against the a<4 condition). Which is True; continue execution as previous.
The print statement is executed, and the value coined by a in the memory of the third loop is now 2. Therefore 2 is outputted.
Afterwards a=a+1 is calculated and saved in memory of the loop which is now 3.
In order to iterate again inside the loop; the number 3(that was saved in the memory of the third loop is checked against the a<4 condition). Which is True; continue execution as previous.
First the print statement is executed, and the value coined by a in the memory of the fourth loop is now 3. Therefore 3 is outputted.
Afterwards a=a+1 is calculated and saved in memory of the loop which is now 4.
In order to iterate again inside the loop; the number 4(that was saved in the memory of the fourth loop is checked against the a<4 condition). Which is False; execution stops.
For completeness:
Many beginners have difficulty with this problem conceptually. They often expect the loop to exit as soon as the condition is met, even in the middle of an iteration.
It does not work that way. The while loop condition is only checked at the beginning of each loop. It is the same as how an if block works - if the condition is met at the beginning, the rest of the block will be run, even if the condition stops being met.
If you want to exit a loop partway through an iteration, break can do that. However, you need to check the condition again in order for it to matter. Also keep in mind that you are writing a condition to leave the loop, rather than a condition to stay; so the logic needs to be reversed.
A lot of the time, it is easier to write code logic that checks a condition only partway through, and use an unconditional loop. That looks like (admittedly this is a silly example):
while True:
count += 1
if count > 5:
break
print(count)
In Python 3.8 and above, it is sometimes possible to simplify that sort of code using the so-called "walrus" operator, which assigns a value but also creates an expression rather than a statement (like how = works in C and C++):
count = 0
while (count := count + 1) <= 5:
print(count)
(Note that we cannot use :+= or +:= to avoid repeating count; those simply don't exist.)
Related
I'm trying to write a function that, when given a list of numbers or string of numbers separated by commas as well as a target number, will find the number of numbers in that list that are equal to the target or can become the target.
Numbers can change by eating numbers that are smaller than or equal to them, after eating a number the larger number will have grown by 1 and the smaller number disappears.
The function checks all the numbers in the provided list so if you have [27,9,11,10,8] and your target is 12 then the function should return 3 because 11 can eat 10 to become 12, 10 can eat 9 and 8 to become 12, and 9 can eat 8 then it can now eat 10 and then 11 to become 12.
My issue is that when provided with something like [3,3,3,2,2,2,1,1,1] with target 4, my function returns the wrong value (value should be 9). For some reason my function does not recognise numbers that are equal as numbers that can be eaten even though in the if statement there is a ">=".
def cannibal(l, target):
try:
l = l.split(",")
l.sort(reverse = True)
l = list(map(int, l))
print (l)
except:
l.sort(reverse = True)
print (l)
finally:
eatingl = l[:]
count = 0
flag = True
for i in range(0,len(l)-1):
if l[i] > target:
print (l[i],"got skipped at",i)
continue
if l[i] == target:
print (l[i],"at",i,"got added")
count += 1
continue
if l[i] < target:
while flag:
if eatingl[i] < target and len(eatingl) == 1:
flag = False
break
if eatingl[i] == target:
(eatingl[i],"at",i,"got added")
count +=1
flag = False
break
for j in range(0,len(eatingl)):
if eatingl[i] == eatingl[j]:
continue
print (eatingl[i],eatingl[j])
if eatingl[i] >= eatingl[j]:
print (eatingl[i],"is eating",eatingl[j])
eatingl.remove(eatingl[j])
eatingl[i] += 1
break
if eatingl[i] > target:
flag = False
break
print (count)
return count
my function does not recognise numbers that are equal as numbers that can be eaten even though in the if statement there is a ">=".
There is only one >= in your code, and not far above it is this:
if eatingl[i] == eatingl[j]:
continue
This line stops a number from eating an equal number. Did you want this line to stop a number from eating itself? If so, you need the condition above to be if i == j: instead.
There are, however, a few other problems with your code:
Once you've found one number that can reach the target, you need to reset the list for the next number. You already have a line eatingl = l[:] which will do this, but it's outside the for i in ... loop. Move it inside.
Secondly, under the line if eatingl[i] == target: you have the following line.
(eatingl[i],"at",i,"got added")
This puts together a tuple with four items in it and then throws it away because nothing is done with it. I'm guessing you are missing a print here.
Thirdly, your variable flag is set to True before the for i in ... loop starts. As soon as this variable gets set to False, the while loop never gets entered again, so your program will never find any more than one cannibal number. Instead, move the line flag = True to immediately above the while loop.
Next, when a number gets eaten you remove it from the list eatingl. This doesn't cause a problem when j > i, but it does when j < i, because removing the number at index j will move the number at index i to index i - 1, after which you then increment the number at index i, which might be a different number.
Adding to or removing items from a list that you are iterating through often causes problems. Instead of removing the numbers it is simpler to replace them with a placeholder value such as 0, -1 or None. You would need to be sure that you don't attempt to eat a number that has already been eaten, and you can do this by checking that eatingl[j] isn't the placeholder just before checking whether eatingl[i] >= eatingl[j].
If your program gets to the end of the j loop without breaking out of it, then there aren't enough other numbers that eatingl[i] could eat to reach the target. In this situation you would want to break out of the while loop. The easiest way to do this is to add an else clause to the for loop:
else:
print("Could do no more for", eatingl[i])
flag = False
break
The else line in the above should line up with the for j in ... line. A for loop can have an else block, and the code in the else block runs if the code in the for loop did not break.
Finally, your i loop should be for i in range(0,len(l)): rather than for i in range(0,len(l)-1):. If you have a unique smallest number, as in your example 27,9,11,10,8 then this isn't a problem: a unique smallest number cannot eat any other numbers so skipping it doesn't do any harm. But in your example 3,3,3,2,2,2,1,1,1, where the smallest number is 1 and there are three of them, each of the 1s can eat the other two 1s and then a 2 to become a 4.
I made these changes to your code and it gave me the output I expected it to.
I'm in the middle of my homework. And i can't find out how to do this solution.
I have tried to used the break under for-statement but nothing return.
The problem is "Complete the following program so that the loop stops when it has found the smallest positive integer greater than 1000 that is divisible by both 33 and 273."
This is my code that i have tried to do it
n = 1001 #This one is required
while True: #This one too
for i in range(n,___): # I don't know what should i put in the blank
if i%33 == 0 and i%273 == 0: # I really confused about this line
break # Should i break it now?, or in the other lines?
print(f"The value of n is {n}") #This one is also required
I don't know that i should put break in which lines (or i don't have to used it?) or i should created a function that called a minimum number of the list?
I'm sorry about my language and how silly i am at my programming skill
I would accept every comment. Thank you
You already have a while True: loop, you don't need the inner for loop to search for your number, just keep incrementing n in the while loop instead of adding a new counter, when the number you're looking for is found, the infinite while True: loop will stop (using break), and so your print statement will be executed:
n = 1001 # start at 1001
while True: # start infinite loop
if n % 33 == 0 and n % 273 == 0: # if `n` found
break # exit the loop
n += 1 # else, increment `n` and repeat
print(f"The value of n is {n}") # done, print the result
Output:
The value of n is 3003
Thanks for saying it's homework! Makes it better to explain things in more detail than just giving an answer.
There are few things to explain:
1) n%33 is the remainder of dividing n by 33. So 66%33 is 0 and 67%33 is 1.
2) For loops are generally when you need to loop over a defined range (not always, but usually). E.g. "add up the first 100 integers". A while loop makes more sense here. It will definitely terminate, because at some point you'll get to 33 * 237.
3) if i%33 == 0 and i%237 == 0: means we want to do something when the number can be divided evenly (no remainder) by both 37 and 237.
n=1001
while True:
if n%33==0 and n%237==0:
print(n)
break
n+=1
A for loop will not help you here, because you don't know when to end the loop. You usually use for loops when the range of things you want to loop over is already known.
Instead, do the following:
before starting your while: True loop: set i to 0,
then increase i with 1 every time to the loop
also, don't forget to stop the loop when i>1000!
Well you could still use a for loop, as long as the upper limit is at least as high as the maximum possible result. The result would be in i, not in n, and the for loop will suffice, not an additional while loop. The for loop will break when the remainder when dividing by both 33 and 237 is zero (i.e. they are both factors).
n = 1001 #This one is required
for i in range(n, 33 * 237 + 1): # I don't know what should i put in the blank
if i % 33 == 0 and i % 237 == 0: # I really confused about this line
break #
print(f"The value of i is {i}") #This one is also required
You could also use a while loop and use the same logic for the condition. In this case we test that at least one is not a factor and continue the loop until both 33 and 237 are evenly divisible into i.
n = 1001 #This one is required
i = n
while i % 33 or i % 237:
i += 1
print(f"The value of i is {i}")
I am trying to create a program that prints out a list of numbers starting at 0 and leading up to a number the user inputs (represented by the variable "number"). I am required to use "while" loops to solve this problem (I already have a functional "for" loop version of the assignment). The program should mark anything in that list divisible by 3 with the word "Fizz," divisible by 5 with the word "Buzz," and anything divisible by both with "FizzBuzz" while also including unlabeled numbers outside of those specifications.
Every time I run this program, it ignores the conditions and just prints the word "FizzBuzz" however many times is represented by the number inputted. (I typically use 15 because it has at least one example of each condition, so that means I get 15 "FizzBuzz"s in a row).
To find out why it was doing that, I used print(i) instead of the rest of the program under the first conditional and it gave me 15 counts of the number 0, so there is reason to believe the program is completely ignoring the range I gave it and just outputting copies of i based on the user number input.
Any help would be appreciated!
number = int(input("Enter a Number"))
i = 0
while(i < number + 1):
if number % 3 == 0 and number % 5 == 0:
print("Fizzbuzz")
elif number % 5 == 0:
print("Buzz")
elif number % 3 == 0:
print("Fizz")
else:
print(number)
i += 1
print ("Done!")
You meant to check the divisibility of i, which increments every loop, not of number which doesn't change.
You also meant to print(i) in the else clause.
If you have another method that can help me I will appreciate your help, I tried my best to write a code that calculates the number of zeroes in a given number.
Here's the code I tried:
def zrc(n):
count=0
while n%10==0 and n!=0:
n=n%10
count=count+1
return count
print(zrc(2500))
it just gives 1 as output of the code, while it must print 2, but for numbers like 36, it gives 0 as output, what is the problem? I know there must be a problem with that while...
If n%10 is zero, n is zero in the next step, so the condition is always fulfilled after the first loop. You probably want to use // instead of %:
def zrc(n):
count = 0
while n%10 == 0 and n != 0:
n //= 10
count += 1
return count
while n%10==0 and n!=0:
n=n%10
See the above lines. If the condition in the while loop is true, n=n%10 line will be executed.
This line will make your n=0 no matter what. For example,
2500%10 = 0
25000%10 = 0
250000%10 = 0
So, there is no chance that your loop condition will be True during the second iteration, so no chance of increment count variable more than once.
So, no matter what is your n is, you always get the output 1.
In your code, Change this:
n=n%10
To this:
n=n/10
An alternative way, might help you.
from collections import Counter
def zrc(n):
valDict=Counter(str(n))
return valDict['0']
print(zrc(2500))
I'm just starting to learn while loops.
I'm trying to iterate same number 10 times using a while loop.
I figured out how I can utilize while loop in order to stop at a certain point as it increases
But I can't figure out how to stop at a certain point without having to add 1 and setting a limit.
Here is my code
i = 1
total = 0
while i < 11:
print i
i += 1
total = i + total
print total
This prints
1,2,3,4,5,6,7,8,9,10,65
in a separate line
How could I modify this result?
1,1,1,1,1,1,1,1,1,1,10?
Just print a literal 1 and add 1 to the total:
while i < 11:
print 1
i += 1
total += 1
You need to keep track of how many times your loop is run, and using i for that is fine, but that does mean you need to increment it on each run through.
If, during each loop, you only want to add one to the total, just do that and don't use the loop counter for that.
i = 1
total = 0
res = []
while i < 11:
res.append(1)
i += 1
print ', '.join(res) +', '+ str(sum(res))
or with for:
vals = [1 for _ in range(10)]
print ', '.join(vals) +', '+ str(sum(vals))
The whole point of a while loop is to keep looping while a certain condition is true. It seems that you want to perform an action n times then display the number of times the action was performed. As Martijn mentioned, you can do this by printing the literal. In a more general sense, you may want to think of keeping your counter separate from your variable, e.g.:
count = 1
number = 3
while count <11:
print number*count
print "While loop ran {0} times".format(count)