Python Beginner Question “Prime Number Count” - python

def prime_count(a, b):
for i in range(a,b):
if i % 2 != 0:
return sum(i)
else:
return 0 "
I am a beginner programmer, I have been practicing on some challenges on Edabit, small problems but that require some thinking (for me).
I am trying to count how many prime numbers are on a and b, they are already integers and there is no user input.
I am not very good at loops yet and thought this was going to be a good challenge to practice, what am I doing wrong? I keep getting int object is not iterable
If reference need, here is the link for the challenge.
Link : https://edabit.com/challenge/6QYwhZstMuHYtZRbT

it is an interesting problem that you are solving. You will have to run two-loops here. One to iterate from a to b and the inner loop to check if each element in a -->b is prime or not (the inner loop should run from 2 to j in [a,b).
def primecheck(a,b):
printlist=[]
if a > 1:
for i in range(a,b+1):
for j in range(2,i):
if i % j == 0:
break
else:
printlist.append(i)
if len(printlist) == 0:
return 0
else:
return len(printlist), printlist
Try this out.

As people say in the comment section, calling sum() is what's causing an error.
But, even if you somehow got that part right, you wouldn't quite get what you want. Maybe you were just trying a simple for loop to check if numbers are odd...?
Anyway, I normally like using Sieve of Eratosthenes to generate prime numbers because it's simple.
def sieve_of_eratosthenes(start, end):
if start > end:
raise AssertionError
# end = end + 1 # If end is inclusive, then uncomment this line.
if end < 2:
return 0
sieve = [i for i in range(2, end)] # Initialize an array of number from 2 to end.
size = len(sieve)
p = 2 # Initial prime.
count = 0
# This block implements Sieve of Eratosthenes.
while count < size:
for i in range(count, size):
num = sieve[i]
if num != p and num % p == 0:
sieve[i] = 0
if count == size-1:
break
count += 1
while sieve[count] == 0:
count += 1
if count == size-1:
break
p = sieve[count] # Update the next prime.
# This block calculates the numbers of primes between start and end.
num_of_primes = 0
for p in sieve:
if p == 0 or p < start:
continue
num_of_primes += 1
print(sieve)
return num_of_primes
sieve_of_eratosthenes(1, 100) # This should return 25.

Related

how to find how many factorial numbers are within a file

i have a problem when i try to find if a number is factorial
this is what I've done so far:
i = 1
count = 0
while n>1:
if n % i == 0:
n /= i
else:
break
i+=1
if n<=1:
count += 1
return count
but it returns 1 and I don't know how to fix
As written, the value of count in your example code indicates whether or not the number n is a factorial number, for a single n.
If it is, then at some point n <= 1, so count will be incremented, and the value of count returned by the function will be 1. If it is not, then at some point before n <= 1, n % i == 0 will be False, the loop will break, and the returned value of count will be 0.
Note, though, that there is an edge case not covered by your example code as is. Namely, 1 is a factorial number (1! = 1). But if n is 1, the condition on the while loop is never True, so the function immediately returns 0. So, you need to change the condition in the while loop.
E.g.
def isfactorialnumber(n):
i = 1
count = 0
while n >= 1:
if n % i == 0:
n /= i
else:
break
i += 1
if n <= 1:
count += 1
return count
I have 2 further comments about this code.
First, in the context of this new function, the variable name count is misleading. What is it counting? Nothing, really. It can only take 2 values, 1 or 0. It would be better then, to use a boolean variable, and call it result or similar. Even better, get rid of the variable and refactor your code as:
def isfactorialnumber(n):
i = 1
while n >= 1:
if n % i == 0:
n /= i
else:
break
i += 1
if n <= 1:
return True
return False
Which is equivalent but a little better.
Second, a more readable, natural way to solve the problem would be to work from bottom-up. That is, solve the problem by generating the factorial numbers, m that are less than or equal to n, then checking if the last m is equal to n. This leads to more concise and understandable code IMO.
E.g.
def isfactorialnumber(n):
m = 1
i = 1
while m < n:
m *= i
i += 1
return m == n
Finally, assuming each number in your file, is on its own line:
with open('factorials.txt') as infile:
print(len([1 for line in infile if isfactorialnumber(int(line))]))
Will print the number of factorial numbers in the file factorials.txt
count = 0
for n in listOfNumbers:
i = 1
while n>=1:
if n % i == 0:
n /= i
else:
break
i+=1
if n<=1:
count += 1
return count

Speeding up prime number finding algorithm for large numbers

My code for Project Euler problem 7 seems correct because it works for small numbers, but it takes forever for large numbers. Where did I go wrong
prime_numbers = []
for number in (range(2,2000000000)):
if number > 1:
for i in range(2, number):
if number % i == 0:
break
else:
prime_numbers.append(number)
print(prime_numbers[10001])
Look at comments and other answers for inspiration on using a faster algorithm. This answer suggests some small speed optimizations to your algorithm, which may be enough to get the result in time.
Stop as soon as you have your result:
prime_numbers = []
number = 1
while True:
number += 1
for i in range(2, number):
if number % i == 0:
break
else:
prime_numbers.append(number)
if len(prime_numbers) > 10001:
break
print(prime_numbers[10001])
No need to look at even numbers or divisors:
prime_numbers = [2]
number = 1
while True:
number += 2
for i in range(2, number, 2):
if number % i == 0:
break
else:
prime_numbers.append(number)
if len(prime_numbers) > 10001:
break
print(prime_numbers[10001])
The upper limit of i can be lower: the square root of number:
import math
prime_numbers = [2]
number = 1
while True:
number += 2
for i in range(2, math.isqrt(number) + 1, 2):
if number % i == 0:
break
else:
prime_numbers.append(number)
if len(prime_numbers) > 10001:
break
print(prime_numbers[10001])
Only look at prime divisors:
import math
prime_numbers = [2]
number = 1
while True:
number += 2
divisor_limit = math.isqrt(number)
no_divisor = True
for d in prime_numbers:
if d > divisor_limit:
break
if number % d == 0:
no_divisor = False
break
if no_divisor:
prime_numbers.append(number)
if len(prime_numbers) > 10001:
break
print(prime_numbers[10001])
Your code is valid, but not very fast - and therefore for large numbers, your program is just going to take far too long. You could try to make some changes, skip even numbers, don't range from 2 to the number but rather 2 to the square root and so on, but you could also look at a different, faster approach called the Sieve of Eratosthenes, you can read about it here.

Python Code to Find x Prime Numbers w/ For Loop?

I am trying to put together a simple program which could work out n prime numbers. I would like to do this by using a nested for loop, where one would go through the numbers, and another would divide that number by all of the numbers up to it to see if it would be divisible by anything.
The problem I am having is that in the main for loop, I need to start it at 2, seeing as 1 would mess up the system and I don't want it to be considered a prime. For the loop to have a starting number however, it also needs an ending number which is difficult in this instance as it is hard to generate the largest prime that will be needed prior to the loop working.
Here's the program that I am using right now. Where I have marked X is where I need to somehow put an ending number for the For Loop. I guess it would be much simpler if I let the For Loop be completely open, and simply take out anything that '1' would produce in the loop itself, but this feels like cheating and I want to do it right.
check = 0
limit = int(input("Enter the amount of Prime Numbers"))
for i in range(2,X):
check = 0
if i > 1:
for j in range(2,i):
if (i % j) == 0:
check = 1
if check == 0:
print (i)
Thanks for your help!
You can step through an unlimited amount of numbers using a generator object.
Insert the following somewhere near the top of your code:
def infinite_number_generator(initial_value=2):
""" Generates an infinite amount of numbers """
i = initial_value
while True:
yield i
i += 1
What this does is it creates a function for constructing generator objects that "pause" whenever they reach the yield statement to "yield" whatever value is specified by the yield command, and then continue to execute from the next line beneath the yield statement.
Python's own range function is itself an example of a generator, and is roughly equivalent to (ignoring the step argument and other peculiarities)
def range(start, end):
i = start
while i < end:
yield i
i += 1
So your program would then look like this:
def infinite_number_generator(initial_value=2):
""" Generates an infinite amount of numbers """
i = initial_value
while True:
yield i
i += 1
check = 0
limit = int(input("Enter the amount of Prime Numbers"))
for i in infinite_number_generator():
check = 0
for j in range(2,i):
if (i % j) == 0:
check = 1
if check == 0:
print (i)
if i == limit:
break
I should also point out that the code you provided is buggy - it will never stop printing because there's no checking whether you've found your limit number of primes yet or not.
This should do what you want.
check = 0
limit = int(input("Enter the amount of Prime Numbers"))
counter = 0
i = 2
while counter < limit:
check = 0
if i > 1:
for j in range(2,i):
if (i % j) == 0:
check = 1
if check == 0:
counter += 1
print (i)
i += 1
In your code you start i with 2 and always increment by 1, so the i will always remain greater than 1, therefore the test if i > 1 is useless.
For efficiency you can stop the check at the square of i or i/2 (no divisors in [i/2 + 1, i[ ).
you can update your code as follow:
n = int(input("Enter the amount of Prime Numbers: "))
FoundPrimes = 0
i = 2
while FoundPrimes < n:
isPrime = True
for j in range(2,1 + i//2):
if (i % j) == 0:
isPrime = False
if isPrime:
FoundPrimes += 1
print(i, end = '\t')
i += 1

How do I get my num_digit function to give me the correct output and how do I get it to return any integer value in python?

How do I get my num_digit function to return 1 instead of 0 whenever I put in 0 as the parameter in the function?
How do I get the function to return any integer such as negative numbers?
def num_digits(n):
count = 0
while n:
count = count + 1
n = abs(n) / 10
return count
I was working on question number 2 first. Even if I put the abs(n) in the line of code where while is, I still get an infinite loop which I still do not really understand why. I figured if I can get my n value to always be positive and input in say -24, it would convert it to 24 and still count the number of values.
On question 1, I do not know where to start, ive tried:
def num_digits(n):
count = 0
while n:
if n == 0:
count = count + 1
n = n / 10
return count
I forgot to add I have limited tools to use since I am still learning python. I have gotten up to iterations and am studying the while loops and counters. I have not gotten to break yet although I have an idea of what it does.
When in doubt, brute force is always available:
def num_digits(n):
if n == 0:
return 1
if n < 0:
return num_digits(abs(n))
count = 0
while n:
count = count + 1
n = n / 10
return count
Process the exceptional cases first, and then you only have to deal with the regular ones.
If you want to avoid the conditionals, I suggest taking abs(n) only once, at the beginning, and using an infinite loop + break for the 0 case:
def num_digits(n):
n = abs(n)
count = 0
while True:
count = count + 1
n = n / 10
if n == 0:
break
return count
For a more practical solution, you can either count the number of digits in the string (something like len(str(n)) for positive integers) or taking log base 10, which is a mathematical way of counting digits.
def num_digits(n):
if n == 0:
return 0
return math.floor(math.log10(math.abs(n)))

How to generate the 1000th prime in python?

count = 0
i = 11
while count <= 1000 and i <= 10000:
if i%2 != 0:
if (i%3 == 0 or i%4 == 0 or i%5 == 0 or i%6 == 0 or i%7 == 0 or i%9 == 0):
continue
else:
print i,'is prime.'
count += 1
i+=1
I'm trying to generate the 1000th prime number only through the use of loops. I generate the primes correctly but the last prime i get is not the 1000th prime. How can i modify my code to do so. Thank in advance for the help.
EDIT: I understand how to do this problem now. But can someone please explain why the following code does not work ? This is the code I wrote before I posted the second one on here.
count = 1
i = 3
while count != 1000:
if i%2 != 0:
for k in range(2,i):
if i%k == 0:
print(i)
count += 1
break
i += 1
Let's see.
count = 1
i = 3
while count != 1000:
if i%2 != 0:
for k in range(2,i):
if i%k == 0: # 'i' is _not_ a prime!
print(i) # ??
count += 1 # ??
break
i += 1 # should be one space to the left,
# for proper indentation
If i%k==0, then i is not a prime. If we detect that it's not a prime, we should (a) not print it out, (b) not increment the counter of found primes and (c) we indeed should break out from the for loop - no need to test any more numbers.
Also, instead of testing i%2, we can just increment by 2, starting from 3 - they will all be odd then, by construction.
So, we now have
count = 1
i = 3
while count != 1000:
for k in range(2,i):
if i%k == 0:
break
else:
print(i)
count += 1
i += 2
The else after for gets executed if the for loop was not broken out of prematurely.
It works, but it works too hard, so is much slower than necessary. It tests a number by all the numbers below it, but it's enough to test it just up to its square root. Why? Because if a number n == p*q, with p and q between 1 and n, then at least one of p or q will be not greater than the square root of n: if they both were greater, their product would be greater than n.
So the improved code is:
from math import sqrt
count = 1
i = 1
while count < 1000:
i += 2
for k in range(2, 1+int(sqrt(i+1))):
if i%k == 0:
break
else:
# print(i) ,
count += 1
# if count%20==0: print ""
print i
Just try running it with range(2,i) (as in the previous code), and see how slow it gets. For 1000 primes it takes 1.16 secs, and for 2000 – 4.89 secs (3000 – 12.15 ses). But with the sqrt it takes just 0.21 secs to produce 3000 primes, 0.84 secs for 10,000 and 2.44 secs for 20,000 (orders of growth of ~ n2.1...2.2 vs. ~ n1.5).
The algorithm used above is known as trial division. There's one more improvement needed to make it an optimal trial division, i.e. testing by primes only. An example can be seen here, which runs about 3x faster, and at better empirical complexity of ~ n1.3.
Then there's the sieve of Eratosthenes, which is quite faster (for 20,000 primes, 12x faster than "improved code" above, and much faster yet after that: its empirical order of growth is ~ n1.1, for producing n primes, measured up to n = 1,000,000 primes):
from math import log
count = 1 ; i = 1 ; D = {}
n = 100000 # 20k:0.20s
m = int(n*(log(n)+log(log(n)))) # 100k:1.15s 200k:2.36s-7.8M
while count < n: # 400k:5.26s-8.7M
i += 2 # 800k:11.21-7.8M
if i not in D: # 1mln:13.20-7.8M (n^1.1)
count += 1
k = i*i
if k > m: break # break, when all is already marked
while k <= m:
D[k] = 0
k += 2*i
while count < n:
i += 2
if i not in D: count += 1
if i >= m: print "invalid: top value estimate too small",i,m ; error
print i,m
The truly unbounded, incremental, "sliding" sieve of Eratosthenes is about 1.5x faster yet, in this range as tested here.
A couple of problems are obvious. First, since you're starting at 11, you've already skipped over the first 5 primes, so count should start at 5.
More importantly, your prime detection algorithm just isn't going to work. You have to keep track of all the primes smaller than i for this kind of simplistic "sieve of Eratosthanes"-like prime detection. For example, your algorithm will think 11 * 13 = 143 is prime, but obviously it isn't.
PGsimple1 here is a correct implementatioin of what the prime detection you're trying to do here, but the other algorithms there are much faster.
Are you sure you are checking for primes correctly? A typical solution is to have a separate "isPrime" function you know that works.
def isPrime(num):
i = 0
for factor in xrange(2, num):
if num%factor == 0:
return False
return True
(There are ways to make the above function more effective, such as only checking odds, and only numbers below the square root, etc.)
Then, to find the n'th prime, count all the primes until you have found it:
def nthPrime(n):
found = 0
guess = 1
while found < n:
guess = guess + 1
if isPrime(guess):
found = found + 1
return guess
your logic is not so correct.
while :
if i%2 != 0:
if (i%3 == 0 or i%4 == 0 or i%5 == 0 or i%6 == 0 or i%7 == 0 or i%9 == 0):
this cannot judge if a number is prime or not .
i think you should check if all numbers below sqrt(i) divide i .
Here's a is_prime function I ran across somewhere, probably on SO.
def is_prime(n):
return all((n%j > 0) for j in xrange(2, n))
primes = []
n = 1
while len(primes) <= 1000:
if is_prime(n):
primes.append(n)
n += 1
Or if you want it all in the loop, just use the return of the is_prime function.
primes = []
n = 1
while len(primes) <= 1000:
if all((n%j > 0) for j in xrange(2, n)):
primes.append(n)
n += 1
This is probably faster: try to devide the num from 2 to sqrt(num)+1 instead of range(2,num).
from math import sqrt
i = 2
count = 1
while True:
i += 1
prime = True
div = 2
limit = sqrt(i) + 1
while div < limit:
if not (i % div):
prime = False
break
else:
div += 1
if prime:
count += 1
if count == 1000:
print "The 1000th prime number is %s" %i
break
Try this:
def isprime(num):
count = num//2 + 1
while count > 1:
if num %count == 0:
return False
count -= 1
else:
return True
num = 0
count = 0
while count < 1000:
num += 1
if isprime(num):
count += 1
if count == 1000:
prime = num
Problems with your code:
No need to check if i <= 10000.
You are doing this
if i%2 != 0:
if (i%3 == 0 or i%4 == 0 or i%5 == 0 or i%6 == 0 or i%7 == 0 or i%9 == 0):
Here, you are not checking if the number is divisible by a prime number greater than 7.
Thus your result: most probably divisible by 11
Because of 2. your algorithm says 17 * 13 * 11 is a prime(which it is not)
How about this:
#!/usr/bin/python
from math import sqrt
def is_prime(n):
if n == 2:
return True
if (n < 2) or (n % 2 == 0):
return False
return all(n % i for i in xrange(3, int(sqrt(n)) + 1, 2))
def which_prime(N):
n = 2
p = 1
while True:
x = is_prime(n)
if x:
if p == N:
return n
else:
p += 1
n += 1
print which_prime(1000)
n=2 ## the first prime no.
prime=1 ## we already know 2 is the first prime no.
while prime!=1000: ## to get 1000th prime no.
n+=1 ## increase number by 1
pon=1 ## sets prime_or_not(pon) counter to 1
for i in range(2,n): ## i varies from 2 to n-1
if (n%i)==0: ## if n is divisible by i, n is not prime
pon+=1 ## increases prime_or_not counter if n is not prime
if pon==1: ## checks if n is prime or not at the end of for loop
prime+=1 ## if n is prime, increase prime counter by 1
print n ## prints the thousandth prime no.
Here is yet another submission:
ans = 0;
primeCounter = 0;
while primeCounter < 1000:
ans += 1;
if ans % 2 != 0:
# we have an odd number
# start testing for prime
divisor = 2;
isPrime = True;
while divisor < ans:
if ans % divisor == 0:
isPrime = False;
break;
divisor += 1;
if isPrime:
print str(ans) + ' is the ' + str(primeCounter) + ' prime';
primeCounter += 1;
print 'the 1000th prime is ' + str(ans);
Here's a method using only if & while loops. This will print out only the 1000th prime number. It skips 2. I did this as problem set 1 for MIT's OCW 6.00 course & therefore only includes commands taught up to the second lecture.
prime_counter = 0
number = 3
while(prime_counter < 999):
divisor = 2
divcounter = 0
while(divisor < number):
if(number%divisor == 0):
divcounter = 1
divisor += 1
if(divcounter == 0):
prime_counter+=1
if(prime_counter == 999):
print '1000th prime number: ', number
number+=2
I just wrote this one. It will ask you how many prime number user wants to see, in this case it will be 1000. Feel free to use it :).
# p is the sequence number of prime series
# n is the sequence of natural numbers to be tested if prime or not
# i is the sequence of natural numbers which will be used to devide n for testing
# L is the sequence limit of prime series user wants to see
p=2;n=3
L=int(input('Enter the how many prime numbers you want to see: '))
print ('# 1 prime is 2')
while(p<=L):
i=2
while i<n:
if n%i==0:break
i+=1
else:print('#',p,' prime is',n); p+=1
n+=1 #Line X
#when it breaks it doesn't execute the else and goes to the line 'X'
This will be the optimized code with less number of executions, it can calculate and display 10000 prime numbers within a second.
it will display all the prime numbers, if want only nth prime number, just set while condition and print the prime number after you come out of the loop. if you want to check a number is prime or not just assign number to n, and remove while loop..
it uses the prime number property that
* if a number is not divisible by the numbers which are less than its square root then it is prime number.
* instead of checking till the end(Means 1000 iteration to figure out 1000 is prime or not) we can end the loop within 35 iterations,
* break the loop if it is divided by any number at the beginning(if it is even loop will break on first iteration, if it is divisible by 3 then 2 iteration) so we iterate till the end only for the prime numbers
remember one thing you can still optimize the iterations by using the property *if a number is not divisible with the prime numbers less than that then it is prime number but the code will be too large, we have to keep track of the calculated prime numbers, also it is difficult to find a particular number is a prime or not, so this will be the Best logic or code
import math
number=1
count = 0
while(count<10000):
isprime=1
number+=1
for j in range(2,int(math.sqrt(number))+1):
if(number%j==0):
isprime=0
break
if(isprime==1):
print(number,end=" ")
count+=1

Categories