Python Loop Controls Exercise - python

I just started studying python on hyperskill for the past few weeks.
Here's the scenario:
Write a program that reads from the console integers (one in a line) until their sum is equal to 0. Immediately after that, it should display the sum of the squares of all the entered numbers.
It is guaranteed that at some point the sum of the entered numbers will be equal to 0. After that, reading is not necessary to continue.
In case the first integer equals to 0, also stop reading values from the input. Print out 0 instead of the sum of the squares.
For example, we are reading the numbers 1, -3, 5, -6, -10, 13. At this point, we have noticed that the sum of these numbers is 0 and output the sum of their squares, not paying attention to the fact that there are still unread values.
num = int()
listtrigbreak = []
listsquares = []
sumtrig = 0
sumsqua = 0
while sumtrig != 0: # until sum of trig is not 0,
num = int(input()) #accept numbers
if num == "0": # while first input is 0,
print(0) # print 0
break # and break the loop
listtrigbreak.append(num) # append num to listtrig
sumtrig += sum(listtrigbreak) # add sum of list to sumtrig
for x in listtrigbreak: # for each number in listtrigbreak
squared = x ** 2 # convert each to squares, save variable
listsquares.append(squared) # add squared to listsquq
sumsqua = sum(listsquares) # sum of squares in listsqua
else:
print(sumsqua)
I can't even get past the first while loop. Whenever I run it, it skips the entire while loop and heads over to this:
else:
print(sumsqua)
I've really had a hard time with boolean logic from the start. I need explanations.

As other comments already pointed out, the while loop is a bit tricky since you initially declare the variable to 0. You could use a boolean switch that controls the while loop, like so:
input_integers = []
stop = False
while not stop: # So while we should keep asking user input...
num = int(input())
input_integers.append(num)
if sum(input_integers) == 0 and len(input_integers) > 0:
print('done')
stop = True
Now add the other functionalities in it, and you're done.

Related

Print prime numbers within an interval [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 11 months ago.
Improve this question
This code is running for the 1-10 interval but for interval 20-30 it is writing 21 and 27 and I am unable to understand what's wrong in the code. I don't want to know other code; I want to know what's wrong in my code.
start = int(input("Enter the first number of the interval")) #starting of interval
end = int(input("Enter the last number of the interval")). #end of interval
for i in range(start, end+1):
for x in range (2,end):
if (i == 0 or i==1):
break
elif (i % x != 0):
print(i)
break
else:
break
for x in range (2,end):
if (i == 0 or i==1):
break
elif (i % x != 0):
print(i)
break
else:
break
This part of code should
print a number if it's prime, otherwise break
but it doesn't.
Do you notice something strange in your code? I do, and it's the fact that in every case the inner for loop breaks after the first iteration, rethink this aspect of your code, and it will work fine.
First, I am not sure whether you want the period after the inputting for the end. Also, your code checks if i is not divisible by x, then print. So for example, your code checks if 21 is divisible by 2. It is not, so your code prints it out and breaks.
Introduction
Your code is effectively testing if a number is odd and if it is, it prints it out.
If start is 1 and end is any number greater than 1, your code is printing every odd number greater than 2 in the interval [1, end].
It is printing all odd numbers, but not all odd numbers are prime!
Dissecting your code
Let's consider the [1, 20] interval. Your code outputs every odd number greater than 2 in the interval [1, 20].
3, 5, 7, 9, 11, 13, 15, 17, 19.
2 is prime and is missing from this list. We can fix that by writing the following within the outer loop but above the inner loop:
if i == 2:
print(i)
Now the output is `
2, 3, 5, 7, 9, 11, 13, 15, 17, 19.
This is better but 9, 15 are not prime numbers.
The if statement with condition (i == 0 or i == 1) inside of your inner loop is not causing any problems. Let's simplify the inner loop by moving this just outside of the inner loop (just above) so that your code becomes
for i in range(start, end+1):
if (i == 0 or i == 1):
# 0 and 1 are not prime
continue
if (i == 2):
# 2 is prime
print(i)
for x in range (2,end):
if (i % x != 0):
print(i)
break
else:
break
All that remains as the potential culprit for your problems is the inner loop so let's focus on that.
Whenever i is even, in the first iteration of the inner loop, we
have x = 2. We know that if i is even that i % 2 is 0 and so i % x != 0 is False and so we move onto the else, in which case we
break out of the inner for loop. This is all fine because no even
integer greater than 2 is prime!
Whenever i is odd, in the first iteration of the inner loop, we
have x = 2. We know that if i is odd that i % 2 is NOT 0 and so
i % x != 0 is True and then we print i and then break out of
the for loop.
We never once have x = 3 or x = 4 and so on!
The above describes precisely what you code is doing, which is ignoring even integers and simply printing out every odd integer.
Solution that outputs what you want
It would help me if I knew what definition of a prime number you have and/or what algorithm you are trying to implement. But since I don't have this information, I can only suggest a solution.
In order to solve your problem, you need to clearly have in mind what a prime number is. There are many equivalent definitions of a prime number (see the Wikipedia prime number page for examples of definitions). I chose a definition that suggests a natural algorithm for finding prime numbers. Whatever definition of prime number you were given, it is possible to prove mathematically that it is equivalent to this (for some this is the first definition of a prime number that they see!):
An integer i is prime if and only if i > 1 AND for all k in {2, 3,
..., i - 1}, i % k != 0.
In words this says that an integer i is prime iff i is strictly greater than 1 and for all integers k from 2 up until i - 1, k does not divide i evenly.
Here it is
start = int(input("Enter Start: "))
end = int(input("Enter End: "))
print(f"\nPrime numbers between [{start}, {end}]:")
for i in range(start, end + 1):
if (i == 0 or i == 1):
# i is not prime
continue
if (i == 2):
# i is prime
print(i)
continue
for x in range(2, i):
if (i % x) == 0:
break
if (i % x) != 0:
print(i)
Example session:
Enter Start: 20
Enter End: 30
Prime numbers between [20, 30]:
23
29
The (i == 0 or i == 1) check should be placed outside the inner for loop. Otherwise, for all i greater than or equal to 2, for every iteration in the inner loop, you will be checking to see if it is less than 2 or not. You are doing this check too much.
We know that when i == 2 that i is prime.
For i > 2, we appeal to the definition of a prime number above.
The inner loop and the last statement applies the second part of the prime definition.

Cannibal numbers with target incorrect return

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.

Change in variable values upon recursion, Python 3

Hey so im pretty new to programming in general and I was having a crack at a question I found for the collatz function,
The code I wrote after some trial and error is as follows:
def collatz(number):
if number % 2 == 0:
number = number//2
print(number)
return number
elif number%2 != 0:
number = 3*number + 1
print(number)
return number
n = int(input("plz enter the number:"))
while n != 1:
n = collatz(n)
Output:
plz enter the number:3
10
5
16
8
4
2
1
This code works but im not sure how the variable values are being alloted, cuz after running this program I can see that in the shell "number = 3" but "n = 1", why is this the case? Shouldnt "number" also equal to 1? Because I am returning the value of number within the function?
Also just to clear my concepts, at the initial moment when I input n = 3, at that moment n = number = 3, then does this returned value of "number" automatically become the new value of n, when i call it in the while loop?
Just wanted to check cuz im a little weak when it comes to doing stuff that needs to pass parameters.
edit:
Why is this case diff then what was just answered?
def testfile(number):
number = number -1
print(number)
return number
n = int(input("enter:"))
while n != 2:
n = testfile(n)
Output:
enter:5
4
3
2
When the input is given as n = 5, then why does number = 3 instead of 5 as was just explained below?
Here's how your program works.
You ask for a number and store it in variable n.
You open a loop which continues until n is 1
Every time the loop repeats, you're calling your function and passing a COPY of n. If you add one to the copy inside the function, your original n will not change.
The COPY is called number. You perform your little tricks with number, output it to the screen, and here's the confusing part: you return a copy of number right back to your loop. And where does it go? It goes right back to n. This overwrites whatever was in n previously.

Why does my loop continue as an infinite loop?

I have a bit of code and I'm having trouble understanding why the loop is an infinite loop even though I have an else condition which should end the loop.
def add1(*args):
total = 0
add = True
for num in args:
while add == True:
if num!=6:
total = total + num
else:
add = False
return total
add1(1,2,3,6,1)
My question is, I have an else statement that changes the add to 'False' hence the loop should stop but for some reason it doesn't.
However, if I make a slight alteration to the code as such, it stops:
def add1(*args):
total = 0
add = True
for num in args:
while add == True:
if num!=6:
total = total + num
break
else:
add = False
return total
add1(1,2,3,6,1)
basically, adding a break.
I don't understand how expert python coders actually interpret 'break' in their minds. I've read articles on break, but still can't seem to understand it quite as well.
I don't understand why the 'break' is needed and why the 'else' can't suffice.
When you enter the for loop, num gets the value 1 (the first value in args). Then you enter the while loop (since add is True). Now, because num does not equal 6, you enter the if block, so the else block does NOT executes. Then, you just return to the while loop, and the value of num doesn't change. Then, because num does not equal 6 (remember it didn't change, it is still 1), once again you enter the if block, and so on until you terminate the program.
When you add the break, you exit the closest loop, which in this case is the while loop, so the for loop continues, until num gets the value 6, and add becomes False. When that happens, the while loop never executes again.
def add1(*args):
total = 0
add = True
for num in args:
if add == True:
if num!=6:
total = total + num
else:
add = False
break #breaking the for loop for better performance only.
return total
add1(1,2,3,6,1)
this adds till 6 is not encountered. you are using while loop unnecessarily. you have to break the infinite loop by some condition and that condition is when num!=6. even your else part can break the infinite while loop, but according to me the while loop itself is unnecessary.
I believe the purpose of your code is to sum up elements in *args up to first occurrence of number 6. If that is the case, the while loop is redundant here. Changing the first code snippet:
def add1(*args):
total = 0
for num in args:
if num != 6:
total = total + num
else:
break
return total
add1(1, 2, 3, 6, 1)
What actually happens in your original code is that the num variable doesn't change in any way when iterating in while loop, so it never enters the else part, effectively getting stuck on the first input argument that is not 6, see below:
def add1(*args): # [1, 2, 3, 6, 1]
total = 0
add = True
for num in args: # first element is 1. num = 1
while add == True:
if num != 6: # num = 1 always
total = total + num
# adding break here gets out of the while loop on first iteration, changing num = 2
# and later to 3, 6...
else: # else is never reached
add = False
return total
add1(1, 2, 3, 6, 1)
You should change the below codes:
from
if num != 6:
to
if total != 6:

ignored counting the same integers

I am very new at Python.
I need to input integers, and sort integers into positive and negative lists.
When the input is 0, it can be ignored.
The result should look like this:
input integers:
23 -2 5 89 -43 0 5 0
positive: 4, negative: 2, sum: 77
input integers:
there is no input
positive: 0, negative: 0, sum: 77
This is my code, but it has some problems.
L = [int(x) for x in input("input integers: \n").split()]
positive=[]; negative=[]
for number in L:
if L==[]:
print("There is no input")
if L!=[]:
if number > 0:
positive.append(number)
elif number < 0 :
negative.append(number)
else:
break
print("positive: %d , negative : %d, total : %d" %(len(positive), len(negative), sum(L)))
first of all, my code doesn't count the same numbers twice;
in this case, there are two '5', but it counts as one.
second, when there is no input number,
print("There is no input")
is not shown.
How should I solve these problems?
first of all, my code doesn't count the same numbers twice; in this case, there are two '5', but it counts as one.
Not precisely. What's happening is that, as soon as your loop encounters a zero, it breaks out of the loop and stops looking at any further numbers. In the case of your first input, this means it ends up skipping over the second 5.
The solution is simple: remove the else: break. It's unnecessary. If a number is neither > 0 nor < 0, you don't need to do anything, so you don't need an else: for that case.
second, when there is no input number, print("There is no input") is not shown.
The check for an empty list is inside the for loop. If the list is empty, there are no numbers to iterate over, so the loop never runs.
Move that check outside the loop.
As an aside, there's a much simpler way of doing the job of your for loop:
positive = [x for x in L if x > 0]
negative = [x for x in L if x < 0]
This implementation uses list comprehensions. You will probably learn about these later.

Categories

Resources