ignored counting the same integers - python

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.

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.

Can you tell me how to use a for loop in my code?

def get_odds(first=0, stop=10, step=1):
number = first
while number % 2 == 1:
yield number
number += step
for i in range(1,10):
third_value = get_odds[4]
number = third_value
print(third_value)
I want to return the odd numbers from range(10), so that's why I coded like this. But now, I want to know 'How to use for loop to find and print the third value returned'.
Use list-comprehension
odd_list = [x for x in range(0,11) if x%2 != 0]
or use recursion,
or use a state machine (just kidding,but it can be done)
best suggestion?
google it.
If your aim is to use a generator function to find the odd numbers in the range from 0 to 10 and you need to use a 'for' statement in it, and you need to be able to state the third odd value, then I think this is what you are after. But none of the answers given by me or the Stack Overflow respondents will do you any good until you understand why they work. (Comprehension is its own thing, and is not the same thing as a generator function.) This is a great opportunity to learn. Study them all until you know why they work, how to write your own, -and- why your code did not work. Good luck with this Hojin. And have fun!
def get_odds(first=0, stop=10, step=1):
number = first
for x in range(first, stop, step):
number += step
if number %2:
yield number
numbers = []
print("The odd numbers in the range from 0 to 10 are:")
for num in get_odds():
print(num)
numbers.append(num)
print("-"*25)
print("The third odd number is "+str(numbers[2])+".\n") #(Computers count from 0)
list comprehension is your best bet
>>> [ i for i in range(10) if i%2 !=0][4]
9
This expression returns the 3rd element in a list between the numbers 0 and 10 that are not divisible by 2.
My Answer : [ i for i in range(1,10) if i%2 !=0][4]

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.

Python Loop Controls Exercise

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.

Python: I have nested for loops that aren't working and I don't know why

So I'm trying to figure out how to print numbers that have more even digits than odd digits. This is my code:
inVal=(input("Please enter a positive integer: "))
evencounter=0
oddcounter=0
for i in range(1,int(inVal)):
for j in range (1,len(str(i))):
if(int(str(i)[j])%2==0):
evencounter+=1
else:
oddcounter+=1
if(evencounter>oddcounter):
print(i)
What's wrong?
As zeet correctly pointed out, you need to reset the counters on each number (they don't even need to be global), but you have another issue. You need to start the second loop from 0, not 1. String indexes start from 0.
inVal=(input("Please enter a positive integer: "))
for i in range(1,int(inVal)):
evencounter=0
oddcounter=0
for j in range (0,len(str(i))):
if(int(str(i)[j])%2==0):
evencounter+=1
else:
oddcounter+=1
if(evencounter>oddcounter):
print(i)
I think that the problem is, you haven't reset your counter variables. Another problem is that your second loop starts from 1 instead of 0. (thanks Leonardo Gazdek for pointing out!)
Strings indexes start from 0:
>>> 'abc'[1]
'b'
Here's how you should do it:
inVal=(input("Please enter a positive integer: "))
evencounter=0
oddcounter=0
for i in range(1,int(inVal)):
# add those pieces of code:
evencounter=0
oddcounter=0
for j in range (0,len(str(i))): # start from 0
if(int(str(i)[j])%2==0):
evencounter+=1
else:
oddcounter+=1
if(evencounter>oddcounter):
print(i)
range(start, stop[, step]) gives values from start till values less than stop.
In your inner loop, change
for j in range (1,len(str(i))):
to
for j in range (0,len(str(i))):
since the indexing starts from 0.
And you need to reset the value of the counter after each iteration of the outer loop so that it can start over for the next number.
Also, if you want to include inVal as well, change the outer loop to
for i in range(1,int(inVal)+1):
You might also want to check this out for exception handling in case the user's input is not a number.
evencounter=0
oddcounter=0
try:
for i in range(1,int(inVal)+1):
for j in range (0,len(str(i))):
if(int(str(i)[j])%2==0):
evencounter+=1
else:
oddcounter+=1
if(evencounter>oddcounter):
print(i)
oddcounter = evencounter = 0
except ValueError:
print('Conversion error!')

Categories

Resources