Python: Error in for loop - python

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")

Related

Could someone explain why my code is not working properly?

i am doing a challenge but for some reason every time i run it says 3 outta of 7 test cases are incorrect and don't know why? everything seems in order. Here is the challenge if Task
Given an integer, , perform the following conditional actions:
If is odd, print Weird
If is even and in the inclusive 2 range of 5 to , print Not Weird
If is even and in the inclusive range of 6 to 20, print Weird
If is even and greater than 20, print Not Weird
My code below:
n = int(input().strip())
if n % 2 != 0:
print("Weird")
else:
if n % 2 == 1 and n in range(2,5):
print("Not Weird")
elif n % 2 == 1 and n in range(6,20):
print("Weird")
elif n > 20:
print("Not Weird")
Try this
n = int(input().strip())
if n % 2 != 0:
print("Weird")
else:
if n in range(2,6):
print("Not Weird")
elif n in range(6,21):
print("Weird")
elif n > 20:
print("Not Weird"
To include 5 and 20 in range you need to specify it as number + 1. Range does not include the last number. Also, there is no need to check for even condition every time in the else part as the control jumps to else when if fails!.
n = int(input().strip())
if n % 2 != 0:
print("Weird")
else:
if n in range(2,6):
print("Not Weird")
elif n in range(6,21):
print("Weird")
elif n > 20:
print("Not Weird")

Python script to find nth prime number

I'm new to Python and I thought I'd try to learn the ropes a bit by writing a function to find the nth prime number, however I can't get my code to work properly. No doubt this is due to me missing something fundamental, but I'd appreciate your help in finding where it went wrong!
c=2
n=input("Which prime would you like? ")
n=int(n)
a=[]
l=len(a)
while l<=n:
if c==2:
a.append(c)
elif (c % 2 ==0): #c is even
break
elif (c % 2 !=0): #c is odd
if c<7:
a.append(c)
elif c >=7:
for i in range(3,int((c+1)/2)):
if (c % i ==0):
break
else:
a.append(c)
else:
c+=1
a[n]
Thanks!
Andrew
This can be a start. This checks whether the number N is divisible by all numbers from 2 to int(sqrt(N)) + 1, where the int function truncates the square root of N. The all() function in python returns True if all members of a list satisfy some condition (here not zero). You should set an upper bound as this is not very efficient for really large n. I'll leave that to you.
def nthprime(n):
import math
start = 2
count = 0
while True:
if all([start % i for i in range(2, int(math.sqrt(start)) + 1)]) != 0:
count += 1
if count == n:
return start
start += 1
In [91]: nthprime(50)
Out[91]: 229
In [92]: nthprime(100)
Out[92]: 541
Tested with this.
Try like this?
print 2
for i in range(3,1000):
b = False
for j in range(2,i):
if i % j == 0:
b=True
if b == False:
print i

Trying to add numbers in python loop wrong result

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

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,))

Python Beginner's Loop (Finding Primes)

I'm truly a beginner at python so I apologise for the lack of knowledge, but the reason I'm asking is that reading the Python manual and tutorial (http://docs.python.org/2.7/tutorial) I'm not unable to totally grasp how loops work. I've written some simple programs so I think I get the basics but for whatever reason this program that is meant to list all primes less than or equal to n is not working:
n = int(raw_input("What number should I go up to? "))
p = 2
while p <= n:
for i in range(2, p):
if p%i == 0:
p=p+1
print "%s" % p,
p=p+1
print "Done"
The output when I enter 100 for example is:
2 3 5 7 11 13 17 19 23 27 29 31 35 37 41 43 47 53 59 61 67 71 73 79 83 87 89 95 97 101 Done
Which looks almost right but for some reason contains 27, 35, 95, which are composite of course. I've been trying to pick apart the way my loop works but I just don't see where it skips checking for divisibility suddenly. I figured that if someone had a look they could explain to me what about the syntax is causing this. Thanks a bunch!
I would actually restructure the program to look like this:
for p in range(2, n+1):
for i in range(2, p):
if p % i == 0:
break
else:
print p,
print 'Done'
This is perhaps a more idiomatic solution (using a for loop instead of a while loop), and works perfectly.
The outer for loop iterates through all the numbers from 2 to n.
The inner one iterates to all numbers from 2 to p. If it reaches a number that divides evenly into p, then it breaks out of the inner loop.
The else block executes every time the for loop isn't broken out of (printing the prime numbers).
Then the program prints 'Done' after it finishes.
As a side note, you only need to iterate through 2 to the square root of p, since each factor has a pair. If you don't get a match there won't be any other factors after the square root, and the number will be prime.
Your code has two loops, one inside another. It should help you figure out the code if you replace the inner loop with a function. Then make sure the function is correct and can stand on its own (separate from the outer loop).
Here is my rewrite of your original code. This rewrite works perfectly.
def is_prime(n):
i = 2
while i < n:
if n%i == 0:
return False
i += 1
return True
n = int(raw_input("What number should I go up to? "))
p = 2
while p <= n:
if is_prime(p):
print p,
p=p+1
print "Done"
Note that is_prime() doesn't touch the loop index of the outer loop. It is a stand-alone pure function. Incrementing p inside the inner loop was the problem, and this decomposed version doesn't have the problem.
Now we can easily rewrite using for loops and I think the code gets improved:
def is_prime(n):
for i in range(2, n):
if n%i == 0:
return False
return True
n = int(raw_input("What number should I go up to? "))
for p in range(2, n+1):
if is_prime(p):
print p,
print "Done"
Note that in Python, range() never includes the upper bound that you pass in. So the inner loop, which checks for < n, we can simply call range(2, n) but for the outer loop, where we want <= n, we need to add one to n so that n will be included: range(2, n+1)
Python has some built-in stuff that is fun. You don't need to learn all these tricks right away, but here is another way you can write is_prime():
def is_prime(n):
return not any(n%i == 0 for i in range(2, n))
This works just like the for loop version of is_prime(). It sets i to values from range(2, n) and checks each one, and if a test ever fails it stops checking and returns. If it checks n against every number in the range and not any of them divide n evenly, then the number is prime.
Again, you don't need to learn all these tricks right away, but I think they are kind of fun when you do learn them.
This should work and is bit more optimized
import math
for i in range(2, 99):
is_prime = True
for j in range(2, int(math.sqrt(i)+1)):
if i % j == 0:
is_prime = False
if is_prime:
print(i)
Please compare your snippet with the one pasted below and you will notice where you were wrong.
n = int(raw_input("What number should I go up to? "))
p = 2
while p <= n:
is_prime=True
for i in range(2, p):
if p%i == 0:
is_prime=False
break;
if is_prime==True:
print "%d is a Prime Number\n" % p
p=p+1
you do not re-start the i loop after you find a non-prime
p = i = 2
while p <= n:
i = 2
while i < p:
if p%i == 0:
p += 1
i = 1
i += 1
print p,
p += 1
print "Done"
A while loop executes the body, and then checks if the condition at the top is True, if it is true, it does the body again. A for loop executes the body once for each item in the iterator.
def is_prime(n):
if n>=2:
for i in range(2, n):
if n%i == 0:
return False
return True
else:
return False
To find PRIME NUMBER
Let's do a couple more improvements.
You know 2 is the only even prime number, so you add 2 in your list and start from 3 incrementing your number to be checked by 2.
Once you are past the half-way point (see above sqrt and * examples), you don't need to test for a prime number.
If you use a list to keep track of the prime numbers, all you need to do is to divide by those prime numbers.
I wrote my code and each of the above items would improve my code execution time by about 500%.
prime_list=[2]
def is_prime(a_num):
for i in prime_list:
div, rem = divmod(a_num, i)
if rem == 0:
return False
elif div < i:
break;
prime_list.append(a_num)
return True
This in my opinion is a more optimised way. This finds all the prime numbers up to 1,000,000 in less than 8 seconds on my setup.
It is also one of my very first attempts at python, so I stand to be corrected
class prime:
def finder (self):
import math
n = long(raw_input("What number should I go up to? "))
for i in range(2, n):
is_prime = True
if i % 2 == 0:
is_prime = False
for j in range(3, long(math.sqrt(i) + 1), 2):
if i % j == 0:
is_prime = False
break
if is_prime:
print(i)
prime().finder()
print('Enter a Number: ')
number=abs(int(input()))
my_List=[0,1]
def is_prime(n):
if n in my_List:
return True
elif n>=2:
for i in range(2, n):
if n%i == 0:
return False
return True
else:
return False
if is_prime(number):
print("%d is Prime!"%number)
else:
print(number,'is not prime')
for i in range(2, p):
if p%i == 0:
p=p+1
print "%s" % p,
p=p+1
I am going to tell your error only,in line 3 you are incrimenting p but actually what you are missing is your i if your i in previous case is let say 13 then it will check your loop after 13 but it is leaving 2,3,5,7,11 so its an error .that is what happening in case of 27 your i before 27 is 13 and now it will check from 14.and I don't think u need an solution.
def findprime(num):
count = 0
for i in range(1,num+1):
list1 = []
for ch in range(1,i+1):
if i%1==0 and i%ch==0:
list1.append(ch)
if len(list1)==2:
count += 1
print(i,end=", ")
print()
return count
num2 = int(input("enter a number: "))
result=findprime(num2)
print("prime numbers between 1 and",num2,"are",result)
Here's a more extensive example with optimization in mind for Python 3.
import sys
inner_loop_iterations: int = 0
def is_prime(n):
a: int = 2
global inner_loop_iterations
if n == 1:
return("Not prime")
elif n == 2:
return("Prime")
while a * a <= n + 1:
inner_loop_iterations += 1
# This if statement reduces the number of inner loop iterations by roughy 50%
# just weeding out the even numbers.
if a % 2 == 0:
a += 1
else:
a += 2
if n % 2 == 0 or n % a == 0:
return ("Not prime")
else:
return ("Prime")
while True:
sys.stdout.write("Enter number to see if it's prime ('q' to quit): ")
n = input()
if not n:
continue
if n == 'q':
break
try:
n = int(n)
except ValueError:
print("Please enter a valid number")
if n < 1:
print("Please enter a valid number")
continue
sys.stdout.write("{}\n".format(is_prime(n)))
sys.stderr.write("Inner loops: {}\n\n".format(inner_loop_iterations))
inner_loop_iterations=0
This program has two main optimizations, first it only iterates from 2 to the square root of n and it only iterates through odd numbers. Using these optimizations I was able to find out that the number 1000000007 is prime in only 15811 loop iterations.
My fast implementation returning the first 25 primes:
#!/usr/bin/env python3
from math import sqrt
def _is_prime(_num: int = None):
if _num < 2:
return False
if _num > 3 and not (_num % 2 and _num % 3):
return False
return not any(_num % _ == 0 for _ in range(3, int(sqrt(_num) + 1), 2))
_cnt = 0
for _ in range(1, 1000):
if _is_prime(_):
_cnt += 1
print(f"Prime N°: {_:,} | Count: {_cnt:,}")
Better use
for i in range(2, p//2 + 1):

Categories

Resources