Trying to add numbers in python loop wrong result - python

I am new to python. I am trying to write a program that counts a range of values but for multiples of 3 and 4 adds 3 and 4 to them resepectively and when the number is multiple of both adds that number to it. So for instance 1,2,3,4,5,6,7,8,9,10,11,12
should read in the end program as: 1,2,6,8,5,9,7,12,10,11,24
But my code is getting stuck somewhere.
for i in range (1,20):
if i%3==0 and i%4==0:
i=i+12
if i%3==0:
i=i+3
if i%4==0:
i=i+4
print i

This line has a typo
if i%3==0 and 1%4==0: # your second condition is 1 % 4 == 0, which is always false
I think you meant
if i%3==0 and i%4==0:

It is better (accurate and cleaner) if you use a different variable.
for i in range (1,20):
n = i
if i%3==0 and i%4==0:
n=i+12
if i%3==0:
n=i+3
if i%4==0:
n=i+4
print n
Now you will notice this fixed it for the 9 case, but not the 12 case! We now need to add the use of elif. Also, if a number is a multiple of 3 and 4, then it is also a multiple of their lowest common multiple, in this case 12. So you could re-write your first step to just check for multiples of 12. This gives us:
for i in range (1,20):
n = i
if i%12==0
n=i+12 # or possibly i + i
elif i%3==0:
n=i+3
elif i%4==0:
n=i+4
print n
The reason this works is because without the elif the i was getting added to multiple times. For example, with 9, you get to 9%3 ==0, True. Now i is set to 12. Next statement? 12%4 ==0 True. So another 4 is added.
Alternatively, if you would like to do some crazy python stuff:
for i in range(1, 20):
print i + next((n for n in (12, 4, 3) if i % n == 0), 0)
(Shout out to Jon Clements for this 2-liner answer)

You're allowing multiples cases (if conditions) for each iteration.
I think you probably wanted to do exclusive cases.
Maybe something like:
for i in range(1, 20):
print i, "=>",
if i % 3 == 0 and i % 4 == 0:
i += i
elif i % 3 == 0:
i += 3
elif i % 4 == 0:
i += 4
print i

Related

Why, using "and" in a for loop and "or" in a while loop gives the same result?

I am trying to practice writing these loops, and I had an exercise which asked me to print numbers from 0 to 20 that aren't divisible by 3 or 5.
For the while loop, I wrote this code:
#solution with while
i = 0
while i < 21:
i += 1
if i % 3 == 0 or i % 5 == 0:
continue
print(i)
Whereas, for the for...in loop, I struggled because I found out that I needed to use and instead of or here.
The code is as follows:
#solution with for
for k in range(21):
if k % 3 != 0 and k % 5 != 0:
print(k)
Why did I have to change the logical operator?
In my head, the first rows of the two codes do the same thing, iterate a number from 0 to 20. So the condition, after these, should be equal for both the iterations used.
Can anyone explain to me what am I missing here?
This isn't a loop type problem, the issue is in using different equality operators in your conditions - != instead of ==.
After changing or to and, the result stays the same because you've accidentally used De Morgan's second law (negation of disjunction):
Now, let's look at the code.
In the while loop:
the program doesn't print i:
if it's divisible by 3 (but not necessarily by 5)
or
if it's divisible by 5 (but not necessarily by 3).
In other words:
the program prints i:
if it's not divisible by 3
and
if it's not divisible by 5.
Noe, let's check, what says the condition in the for...in loop:
the program prints k:
if it's not divisible by 3
and
if it's not divisible by 5.
Looks like the same condition, doesn't it?
As you noticed, in the In other words: paragraph, we've naturally used the negation of disjunction.
To sum up, both programs for i / k lower than 21 print:
0
1
2
4
7
8
11
13
14
16
17
19
If you still aren't sure, try to replace the conditions between loops:
i = 0
while i < 21:
i += 1
if i % 3 != 0 and i % 5 != 0:
print(i)
for k in range(21):
if k % 3 == 0 or k % 5 == 0:
continue
print(k)
In while loop.
if i % 3 == 0 or i % 5 == 0: # this means when i is evenly divided by 3 or 5 then don't do anything.
continue
print(i) # means only print i when i is not evenly divided by 3 and 5
And in the for loop
if k % 3 != 0 and k % 5 != 0: # here this means print i when k is not evenly divided by 3 and 5. Which same as while loop
print(k)
You just reverse order and nothing. You can use the same method in both way and you will get the same result.
While loop
i = 0
while i < 21:
i += 1
if i % 3 != 0 and i % 5 != 0:
print(i)
For Loop
for a in range(21):
if a % 3 != 0 and a % 5 != 0:
print(a)
Because you have also changed the conditions for the results in the while loop you have used ==, but in for loop you have used != if you modify the code you will get the same output by or operator in both
for k in range(21):
if k % 3 == 0 or k % 5 == 0:
continue
print(k)
The two loop types are totally equivalent. You had to use and instead of or, and != instead of ==, because you reversed the logic.
In the first case, you are saying "if the number is divisible then skip it, else print it" while in the second one_ "if the number is not divisible then print (else do nothing)"_.

Python: Error in for loop

See, I started learning Python today and I am stuck in a situation.
I was solving a very simple question and I completed it but there is a problem.
First of all, let me tell the question and the constraints. Here is the question:
Given an integer,n, perform the following conditional actions:
If n is odd, print Weird.
If n is even and in the inclusive range of 2 to 5, print Not Weird
If n is even and in the inclusive range of 6 to 20, print Weird
If n is even and greater than 20, print Not Weird
Here is my code:
n = input("")
if n%2!=0 :
print ("Weird")
elif n%2==0 :
for n in range(3,4,5) :
print ("Not Weird")
elif n%2==0 :
for n in range(6,21) :
print ("Weird")
else :
if (n%2==0 & n>20) :
print ("Not Weird")
I compiled the code, everything is fine but for the input 18 and 20 I must get Weird as output but I am getting Not Weird. Can anyone help me?
Were you asked specifically to use for loops? If not you can try this!
n = int(input(""))
if n%2==1:
print("Weird")
elif n%2==0 and n in range(3, 6):
print("Not Weird")
elif n%2==0 and n in range(6, 21):
print("Weird")
elif n%2==0 and n>20:
print("Not Weird")
You have 2 elif with same condition it shouldn't.
Change it or remove one elif
n = input("")
if n%2!=0 :
print ("Weird")
elif n%2==0 :
if n>20:
print ("Not Weird")
for n in range(3,4,5) : #range shouldn't be like this. But for your understanding i leave it as it is
print ("Not Weird")
for n in range(6,21) :
print ("Weird")
Final else also not needed
Your have a problem with range(3,4,5). list(range(3,4,5)) is [3]..probably not what you expected...range is start, stop, step.
You could do for n in [3,4,5] or range(3,6)
Your main problem is that you keep re-defining n in your for loops, thus at each conditional statement after the first for loop your n is not what was initially given.
In your two cases of n=18 and n=20, the first condition n%2!=0 is False, so then the second condition is tested. n%2==0 is True, so the for n in range(3,4,5): loop is executed. The first (and only) iteration of that loop sets n to 3 and prints 'Not Weird'. Since n is now 3, none of the remaining conditions in you code are True, so they do not execute.
The following would be much simpler given your requirements:
def isweird(n):
if n%2 or n in range(6,21):
return 'Weird'
if n in range(2,6) or n > 20:
return 'Not Weird'
for n in range(23):
print(n, isweird(n))
Output:
0 None
1 Weird
2 Not Weird
3 Weird
4 Not Weird
5 Weird
6 Weird
7 Weird
8 Weird
9 Weird
10 Weird
11 Weird
12 Weird
13 Weird
14 Weird
15 Weird
16 Weird
17 Weird
18 Weird
19 Weird
20 Weird
21 Weird
22 Not Weird
There are a number of problems with the code you've provided.
The most obvious is that you have the same condition repeated in two branches of an if...else chain. The second such condition,
elif n%2==0:
for n in range(6,21) :
will never execute.
Also, the use of for loops in those branches is incorrect. Those should be conditionals. You use a loop when you want to repeat an action, but here you have one variable and you want to ask a question about it. That's an "if":
elif n%2==0 :
if n in range(3,4,5) :
print ("Not Weird")
But that leads to the next bug, which is the use of range. As written, you're specifying the range of numbers starting with 3, running up to 4 (not inclusive), in steps of 5. That would be the range containing 3.
To specify the inclusive range from 2 to 6, you would write
elif n%2==0 :
if n in range(2,7):
print ("Not Weird")
Ranges are inclusive on the bottom end and exclusive on the top end. This seems counterintuitive at first, but it's generally what you want when working with zero-indexes. For example, you would like range (10) to have 10 members, and to start with zero, hence contain all of the base-ten digits.
You can also write this as
elif n%2==0 :
if 2 <= n <= 6:
print ("Not Weird")
which would be my preference.
So, let's walk through your code line by line and see what's happening in the case of an input of 18:
if n%2!=0 :
print ("Weird")
18 modulus 2 is equal to 0, so this print statement will not be reached.
Next:
elif n%2==0 :
for n in range(3,4,5) :
print ("Not Weird")
Hello, this one matches! Therefore, the for statement will be executed. No other statements in your if / elif / else chain will be reached for the value 18, because you found a match here.
However, you're not going to see what you expect, because the for statement does not do what you think it does. You're thinking that it's going to look at n and for a value of n that's found in the the list [3,4,5], the value Not Weird will be printed.
That's not what for does. Instead, n will be changed to one each of the values in the range, in turn, and the code inside the loop will be executed with n set to that value. Now, you're wondering why, if this is the case, you don't see the Not Weird printed three times? The reason is that range is a function and it doesn't return a list of the supplied numbers, it returns a bunch of numbers starting with (in your example) 3, and ending with 4, but taking only every 5th number. By coincidence, this gives a range with only 1 value (the value 3) which is why Not Weirdappears only once.
Here is a corrected and annotated version of your code:
if n%2 != 0:
print ("Weird")
else:
#Don't need elif, there are only two cases odd, or not.
#But, inside this branch we have three possibilities.
if n in [2, 3, 4, 5]:
#I just enumerate here, instead of using range. You forgot about 2, BTW
print ("Not Weird")
elif n in range(6,21)
# Note the use of if (or elif), not for.
print ("Weird")
else:
print ("Not Weird")
n = int(input())
if n % 2 != 0:
print('Weird')
elif n % 2 == 0 and n in range(2, 6):
print('Not Weird')
elif n % 2 == 0 and n in range(5, 21):
print('Weird')
elif n % 2 == 0 and n > 20:
print('Not Weird')
This will work....the key point there is inclusive.
n = int(input().strip())
check = {True: "Not Weird", False: "Weird"}
print(check[
n % 2 == 0 and (
n in range(2, 6) or
n > 20)
])
This will be the shortest solution without using if else.
Here is a direct solution:
n = int(input())
if n%2==0 and n not in range(6,21):
print("Not Weird")
else:
print("Weird")
num = input()
n = int(num)
if n%2 !=0:
print('Weird')
if n%2==0 and n in range(2,6):
print('Not Weird')
if n%2==0 and n in range(6,21):
print('Weird')
if n%2==0 and n>20:
print('Not Weird')
else:
pass
Try this:
n= int(input("")
if n%2==1:
print("Weird")
elif n%2==0 and n in range(3, 6):
print("Not Weird")
elif n%2==0 and n in range(6, 21):
print("Weird")
elif n%2==0 and n>21:
print("Not Weird")
n=3
if(n%2!=0):
print("Weird")
else:
if(n>=2 and n<=5):
print("Not Weird")
elif(n>=6 and n<=20):
print("Weird")
elif(n>20):
print("Not Weird")

Why are these lines of code in python only outputting the same answer?

I'm trying to get this program to return all possible multiples of 3 and 5 below 1001 and then add them all together and print it but for some reason these lines of code only seem to be printing one number and that number is the number 2 which is obviously wrong. Can someone point me in the right direction to why this code is grossly wrong?
n = 0
x = n<1001
while (n < 1001):
s = x%3 + x%5
print s
You've got a few mistakes:
x is a boolean type
Your loop never ends
adding values to mimic lists?
Edit
Didn't see the part where you wanted sum, so you could employ a for-in loop or just a simple one like so:
sum = 0
for i in range(1001):
if(i % 3 == 0 or i % 5):
sum += i
print(sum)
(Python 3)
You need to stop while at some point by incrementing n. Here is some code:
nums = []
n = 0
while (n < 1001):
# in here you check for the multiples
# then append using nums.append()
n += 1
This creates a loop and a list that accounts for every number in 0 to 1000. In the body, check for either condition and append to the list, then print out the values in the list.
num is a list where you are going to store all the values that apply, (those numbers who are divisible by 3 and 5, which you calculate with modulo). You append to that list when a condition is met. Here is some code:
nums = []
n = 0
while (n < 1001):
if(n % 3 == 0 or n % 5 ==0):
nums.append(n)
n += 1
print(n) #or for loop for each value
Explanation: a list of numbers called num stores the numbers that are divisible by 3 or 5. The loop starts at zero and goes to 1000, and for all the values that are divisible by 3 or 5, they will be added to the list. Then it prints the list.
Of course there is a simpler approach with a range:
for i in range(1001):
if(i % 3 == 0 or i % 5 == 0):
print(i)
This will print out all the values one by one. It is 1001 because the upper limit is exclusive.
true=1
false=0
so:
x = n<1001
we have x=1 because 0<1001 is true
s = x%3 + x%5
the remainder of 1/3 is 1 and 1/5 is 1
In your code:
1. x=n<1001 - generates a boolean value; on which we can't perform a mathematical operation.
In while loop:
your variable n,x are not changing; they are constant to same value for all the iterations.
Solution 1:
Below code will help you out.
s=0
for i in range(1,1002):
if( i%3 == 0 or i%5 == 0):
s = s + i
print(s)
Solution: 2
There is one more approach you can use.
var = [i for i in range(1,1002) if i%3==0 or i%5 ==0]
print(sum(var))

Python - home-made binary search function not working

I've been learning python for about a week now, and I tried my hand at creating the binary search function:
def bin_srch(a, b, c, d):
l_c = map(int, c.split(" "))
l_d = map(int, d.split(" "))
for n in l_d:
if n <= l_c[a/2]:
for j in l_c[0:(a/2)+1]:
if j == n:
print l_c.index(j)+1,
elif n not in l_c[0:(a/2)+1]:
print -1,
elif n > l_c[a/2]:
for j in l_c[a/2:a]:
if j == n:
print l_c.index(j)+1,
elif n not in l_c[a/2:a]:
print -1,
However, when I test the function with some input:
bin_srch(5,6,
"10 30 50 60 70",
"60 10 50 10 5")
yields 4 1 3 1 -1 -1 -1 instead of 4 1 3 1 -1. Can anybody explain this?
While I don't really understand what you're code is supposed to be doing, I'm pretty sure I know the problem:
for j in l_c[0:(a/2)+1]:
if j == n:
print l_c.index(j)+1,
elif n not in l_c[0:(a/2)+1]:
print -1,
So, for each value, if it's a match, print the match (and keep looking); otherwise, check it against of the same values you're already looping over (and are going to continue to loop over) and if it's not found, print -1. So, if something isn't a match, you're going to print -1 multiple times.
What you probably want is:
for j in l_c[0:(a/2)+1]:
if j == n:
print l_c.index(j)+1,
break
else:
print -1,
At least this gives the desired output for this example. Why?
Well, the break means that as soon as you find a match, you stop going through the inner loop. The else—notice that it's attached to the for, not the if—runs if you finished the loop without ever break-ing. So, instead of checking for a match 3 times and printing -1 each time, you just check for a match 3 times and print -1 at the end, if you never found one.
(Actually, it looks like you could replace this whole loop with a list.index call, but I'll leave that up to you.)
Of course you have to make the same fix in the elif branch of your top-level if, because you have the same problem there.
Also, as a side note, if you write if n <= l_c[a/2]:, you don't need elif n > l_c[a/2]: Just use else; you already know that it's not true that n <= l_c[a/2] or you wouldn't have gotten here, therefore it must be true that n < l_c[a/2], so you don't need to check it.

Numbers without remainder python

I need to print out numbers between 1 and n(n is entered with keyboard) that do not divide by 2, 3 and 5.
I need to use while or for loops and the remainder is gotten with %.
I'm new here and I just don't understand the usage of %?
I tried something like this:
import math
print("Hey. Enter a number.")
entered_number = int(input())
for i in range(1, entered_number):
if i%2 != 0:
print("The number", i, "is ok.")
else:
pass
if i%3 != 0:
print("The number", i, "is ok.")
else:
pass
if i%5 != 0:
print("The number", i, "is ok.")
help?
You need to test for all 3 conditions in one statement, not in 3:
for i in range(1, entered_number):
if i % 2 != 0 and i % 3 != 0 and i % 5 != 0:
print("The number", i, "is ok.")
The and operators here make sure that all three conditions are met before printing.
You are testing each condition in isolation, which means that if the number is, say, 10, you are still printing The number 10 is ok. because it is not divisible by 3. For numbers that are okay, you were printing The number ... is ok. 3 times, as your code tests that it is not divisible by 3 different numbers separately, printing each time.
If something divides by 7 then:
something % 7 == 0
If something divides by 7 and 9 then:
something % 7 == 0 and something % 9 == 0
Conversely, if something divides by 7 or 9 then:
something % 7 == 0 or something % 9 == 0
Something that does not divide by 7 or 9 is given by the expression:
not (something % 7 == 0 or something % 9 == 0)
You don't require the else: pass bits from your code and one if statement with an if-expression that has three %, == bits in it should suffice.
You should probably check the three conditions at the same time:
if i%2 != 0 and i%3 != 0 and i%5 != 0:
print("The number", i, "is ok.")
Otherwise, you would print the same message several times for a single number.
Anyway, for your second question, the% operation is called modulo and it gives you the remainder of a division. For instance, 5%3 = 2 because 5 = 3*1 + 2. And when you check i%2 != 0, you actually check if i can be divided by 2.
print("Hey. Enter a number.")
entered_number = int(input())
for i in range(1, entered_number):
if i%2 != 0 and i%3 !=0 and i%5!=0:
print("The number", i, "is ok.")
a%b returns the remainder when a is divided by b. Example:
>> 5%3
2
What you are doing wrong here is that you are printing after checking a single condition so it will print even if i is divisible by other numbers. For example if i is 3, it will satisfy the first condition and therefore print that the number is ok but it is actually divisible by 3.
I saw you've solved your problem but my answer may worth reading.
This problem is actually doing filtering over a list of numbers 1..n. You can define a base function to test if number x is dividable by number y, and then use this base function to filter the list to get the result.
Here's my version.
import math
from functools import partial
print("Hey. Enter a number.")
entered_number = int(input())
def not_dividable_by(x, y):
return False if x % y == 0 else True
number_list = range(1, entered_number)
for i in [2, 3, 5]:
test_func = partial(not_dividable_by, y=i)
number_list = filter(test_func, number_list)
for number in number_list:
print("%d is OK" % (number,))

Categories

Resources