I am new to programming and trying to write a program that prints primes less than 100. When I run my program I get an output that has most of the prime numbers, but I also have even numbers and random odd numbers. Here is my code:
a=1
while a<100:
if a%2 == 0:
a+=1
else:
for i in range(2,int(a**.5)+1):
if a%i != 0:
print a
a+=1
else:
a+=1
The first part of my code is meant to eliminate all even numbers (doesn't seem to fully work). I also don't fully understand the part of my code (for i in).
What exactly does the "for i in" part of the code do? What is 'i'?
How can I modify my code that it does accurately find all of the primes from 1-100?
Thanks in advance.
See the comments on your post to find out why your code doesn't work. I'm just here to fix your code.
First of all, make use of functions. They make code so much more readable. In this case, a function to check if a number is a prime would be a good idea.
from math import sqrt
def is_prime(number):
return all(number%i for i in range(2, int(sqrt(number))+1))
There isn't much left to do now - all you need is to count how many primes you've found, and a number that keeps growing:
primes= 0
number= 1
while primes<100:
if is_prime(number):
print number
primes+= 1
number+= 1 # or += 2 for more speed.
Suddenly it's very easy to read and debug, is it not?
I'm going to try to guide you without giving you any code to help you learn, you should probably start from scratch I think and make sure you know how each part of your code works.
Some things about primes, 1 isn't prime and 2 is so you should start with a=3 and print 2 immediately if you want to eliminate even numbers.
By doing that, you will then be able to just increment a by 2 rather than 1 as you're doing now and just skip over even numbers.
As you loop a to be less than 100, you need to check if each value of a is prime by making another loop with another variable that loops downward through all numbers that could possibly divide a (less than or equal to a's square root). If that variable divides a, then exit the inner loop and increment a, but if it makes it all the way to 1, then a is prime and you should print it, then increment a.
There's several things wrong with what you're doing here:
You don't find the first 100 primes, you find the primes less than 100 with while a < 100
You print a every time a is evenly divisble by i, and then increment a. But you've gotten ahead of yourself! a is prime only if it is not divisble by any value i, but you fail to keep track of whether it's failed for any i.
You add +1 to the range up to the square root of the number - but that's not necessary. The square root of the number is the largest number that could possibly be the smaller of two factors. You don't need to add 1 because that number is _bigger than the sqare root - in other words, if a is evenly divisble by sqrt(a)+1 , then a / (sqrt(a)+1) will be smaller than sqrt(a)+1 and therfore would have already been found.
You never print the list of primes you found; you print a every time you find a number that is not a factor ( primes have no factors other than one and themselves, so you're not printing prime numbers at all!)
This might get you thinking in the right direction:
a=0
primes = []
while len(primes) < 100:
a = a + 1
prime=True
maxfactor = int(a ** .5)
for i in primes:
if i == 1:
continue
if i > maxfactor:
break
if a % i == 0:
print a, " is not prime because it is evenly divisble by ", i
prime=False
break
if prime:
print "Prime number: ", a
primes.append(a)
for p in primes:
print p
Related
I am trying to make a simple function to sum the prime numbers of a given input. I am wondering why '7' isn't coming up in my appended list of prime numberS:
def sum_primes(n):
empty = []
for i in range(2,n):
if n % i == 0:
empty.append(i)
print(empty)
sum_primes(10)
Your method for determining if numbers are prime is a bit off. Your function seems to determine if the input num n is prime but not sum all prime numbers to it.
You could make an isprime function and then loop over that for all numbers less than n to find all primes.
Actually your program have logical error. First you have to understand the prime number logic.
Step 1: We must iterate through each number up to the specified number in order to get the sum of prime numbers up to N.
Step 2: Next, we determine whether the given integer is a prime or not. If it is a prime number, we can add it and keep it in a temporary variable.
Step 3: Now that the outer loop has finished, we can print the temporary variable to obtain the total of primes.
sum = 0
for number in range(2, Last_number + 1):
i = 2
for i in range(2, number):
if (int(number % i) == 0):
i = number
break;
if i is not number:
sum = sum + number
print(sum)
def sum_primes(y):
sum = 0
# for each number in the range to the given number
for i in range(2, y):
# check each number in the sub range
for j in range(2, int(i/2)+1):
# and if its divisble by any number between
# 2 and i/2
if i % j == 0:
# then it is not a prime number
break
else:
# print current prime
print(i)
# add prime to grand total
sum += i
return sum
print(sum_primes(10))
I think you have some problems with the way you are checking if your number is prime or not. A much simpler way would be to use a library that does this for you. It takes less time, is usually a better implementation than you or I could come up with, and it takes fewer lines, therefore, looking cleaner.
I would recommend primePy. Its whole point is to work with prime numbers.
I don't have my computer with me atm so I can't make any sample code for you and test it. But something like this should work.
from primePy import primes
prime_list = primes.upto(n)
print(prime_list)
I believe that function returns a list of all prime numbers up to n. And if you wanted to get the sum of all of those numbers, you can go about whatever method you want to do that.
Afterward, slap it into a def and you should be good to go.
If it doesn't work let me know, and I will try to test and fix it when I am in front of a computer next.
Lately am trying to do some Python programming, so am doing some mathematical exercices in some website.
I came across this example and at first I didn't understand the exercise. So I checked the solution to at least understand the question. As a consequence I found myself learning some coding tricks (like the while True loop).
The exercise is simple:
Write a Python program to find the smallest multiple of the first n numbers. Also, display the factors.
Below is the code:
def smallest_multiple(n):
if (n<=2):
return n
i = n * 2
factors = [number for number in range(n, 1, -1) if number * 2 > n]
print(factors)
while True:
for a in factors:
if i % a != 0:
i += n
break
if (a == factors[-1] and i % a == 0):
return i
My questions are:
Why does he create a list of numbers that are superior to the input by a factor of 2?
And then the while loop is just difficult to undestand. Could someone please explain it to me (I mean the content of the loop)?
I think we have here a tiny mixture of mathematic question and programming.
first of all, please note that the spaces are important in coding. see how the code should look like. (with the spaces)
def smallest_multiple(n):
if (n<=2):
return n
i = n * 2
factors = [number for number in range(n, 1, -1) if number * 2 > n]
print(factors)
while True:
for a in factors:
if i % a != 0:
i += n
break
if (a == factors[-1] and i % a == 0):
return i
1- Why does he create a list of numbers that are superior to the input by a factor of 2 ?
Answer : because the numbers that have their double smaller than the highest number will not affect / change the result. (This is a maths question) you can check that by removing the condition and you will see that you will get the same result (same smallest multiple)
2-And then the while loop is just difficult to understand. Could someone please explain it to me (I mean the content of the loop)? Thanks for your response?
Answer : The loop is using the boolean True as the code will only stops until it finds the smallest multiple for the first n numbers. the reason of the coder doing this because he has used the keyword return that will help him to exit the function, ultimately exiting the while loop.
The loop uses the value i which is the first multiple of the highest number of the first n numbers, meaning the double of the value n. Then will check if this first multiple (meaning i) is not dividable (i % a != 0) by the numbers in the list starting from the highest.
if i % a != 0:
i += n
break
this condition is there to increase the value of i as soon as i is not dividable by any number of the first n numbers meaning that the code keeps searching through the multiples of n (n being the highest number of the list) until i is dividable by all the numbers in the list
once the i value is able to satisfy the condition below
if (a == factors[-1] and i % a == 0):
then the while loop is exited through the keyword return which exits the function and the i value is sent as a response to the function call through the line return i
also note that factors[-1] is the last item (number) of the list.
I hope the above make sense and is clear to you.
I am using Python 3.9 and I have created a very simple program to identify whether or not a number is prime when given in integer input.
My code itself works, but it can be very slow even given large numbers
(50 million+). I am using a for loop to check if any numbers between 1
and the input(x) are evenly divisible by the input(x). I want to exclude all
even numbers and multiples of 5 from the range since no primes are even or end in 5.
Is there a way to explicitly remove all evens and multiples of 5 without creating an array of excluded/included values like I did?
Here is a snippet code and time of the program for reference:
#program with filtering out evens and multiples of 5
print("Is your number prime?? Well... let's check!")
#'x' can actually be any input but I am using 60000049 as a constant value for the sake of timing.
x=60000049
factorlist=[]
#Included_values is an array in which all elements are divided into 'x' after it excluded all evens and multiples of 5.
included_values=[]
for i in range (1,x+1):
if i%2!=0 or i%5!=0:
included_values.append(i)
for i in range(1,len(included_values)):
if x%included_values[i]==0:
factorlist.append(i)
if len(factorlist)>2:
print("Oh no! It appears like the number you have entered is not prime. Try again!")
print('The factors to your number are:',factorlist)
if len(factorlist)<=2:
print('Yay! You have chosen a prime number!!')
Yay! You have chosen a prime number!!
~17.96522307395935
The first version of my program is much slower than the one that does not exclude any values:
#My program without filtering out evens or multiples of 5.
#'x' can actually be any number but I am using 60000049 for the sake of timing.
print("Is your number prime?? Well... let's check!")
x=60000049
factorlist=[]
for i in range (1,x+1):
if x%i==0:
factorlist.append(i)
if len(factorlist)>2:
print("Oh no! It appears like the number you have entered is not prime. Try again!")
print('The factors to your number are:',factorlist)
if len(factorlist)==2:
print('Yay! You have chosen a prime number!!')
Yay! You have chosen a prime number!!
~6.147368431091309
As you can see, my second program is much faster because it does not cycle through the range to get an array of excluded values first.
If there is a way to exclude even values and multiples of 5 first without cycling through the entire range (1,x+1), it would make my program much faster. If this is possible, let me know!
To answer your question, you could of course have an if inside the for to skip values. Well you already do, but using a list. I mean you could just have condition there.
Otherwise, a list comprehension is a more efficient way to create a new list than calling append in a loop like you do:
included_values = [i for i in range(1, x+1)
if i%2 !=0 or i%5 != 0]
I did that change in https://replit.com/#ToniAlatalo/DapperSeagreenMacro#main.py
Also the other for I think you could convert from:
for i in range(1,len(included_values)):
to:
for value in included_values:
Which might be a tiny bit faster but probably not much different.
If you want to exclude multiples of 2 or 5 only, you can try using list comprehension included_values = [k for k in range(1,x+1) if k%2!=0 and k%5!=0]
If you want your program to be "more efficient", I suggest checking to the square root of x only. included_values = [k for k in range(1, math.ceil(math.sqrt(x)))]
But, your code is not that efficient.
x = int(input("Is your number prime?? Well... let's check! Type your number here:" ))
from math import sqrt, ceil
if x ==2:
print('Your number is a prime')
elif x < 2:
print("Your number isn't prime")
else:
print('Your number is not prime' if any([k for k in range(2,ceil(sqrt(x))) if x%k==0]) else 'Your number is a prime')
Breakdown of code:
x = int(input("Is your number prime?? Well... let's check! Type your number here:" )) This will get your "x", but if x is predetermined, you can skip this.
from math import sqrt,ceil This will import sqrt and ceil from the math library
if x ==2:
print('Your number is a prime')
elif x < 2:
print("Your number isn't prime")
Check if number is smaller than 3, if it's 2, print the number is prime, else print that it's not prime
print('Your number is not prime' if any([k for k in range(1,ceil(sqrt(x))) if x%k==0]) else 'Your number is a prime') Check if any([k for k in range(2,ceil(sqrt(x))) if x%k==0]) is true, if it's true, number isn't a prime, but if it's false, number is a prime(Since x isn't divisible by any number in range of 2 to square root of x).
Granted, this is not perfect but will be fast enough for normal uses.
The i%2!=0 or i%5!=0 condition will only exclude multiples of 10 from your included_values list. Also, your next loop adds an index (instead of a factor) to the factorlist so it doesn't print the right factors even for the ones it does find (try it with x=15) it will also find that 10 is prime.
All this being said, if you want to list all the factors of the number (when it is not prime), you can't really skip any divisors.
To make it go faster, what you could do is check for factors up to the square root of x and add each divisor along with the resulting quotient for every match you find.
x = 60000049
factors = []
for f in range(1,int(x**0.5)+1):
if x%f == 0:
factors.extend({x//f,f})
print(factors) # [60000049, 1]
By skipping multiples of 2 and 5, appart from skipping factors and producing a wrong result, you'd only reduce the number of tests by 60% but stopping at the square root will eliminate 99.98% of them (for x=60000049).
I have written a recursive Python program which I have attached below, which prints out the palindromic primes in an interval. I cannot use loops.
palindromic_primes.py:
import sys
sys.setrecursionlimit(30000)
# this function places all the numbers between the start and end points into
# a list and determines whether they are prime numbers by seeing if they have
# a remainder of 0 when divided, else numbers that dont have remainder of zero
# are stored.
def check_prime(num_list, number):
if num_list == []:
print(number)
else:
num = num_list[0]
if number % num == 0:
pass
else:
num_list.pop(0)
check_prime(num_list, number)
# this checks whether the numbers in the interval are palindromes by comparing
# the first 'letter' to the last 'letter' for each number and seeing whether
# they match.
def check_palindrome(nums):
nums1 = nums[::-1]
if nums1 == nums:
new_list = list(range(2, int(nums)))
check_prime(new_list, int(nums))
# this takes both functions and only stores the numbers that match in both
# functions.
def check_done(lists):
# takes numbers not stored (so the numbers that are palindromes and primes)
if lists != []:
check_palindrome(str(lists[0]))
lists.pop(0)
check_done(lists)
start_int = int(sys.argv[1])
ending_int = int(sys.argv[2])
palindromic_primes = print("The palindromic primes are:")
# the list will analyse all numbers from the start point till the end point
list1 = list(range(start_int, ending_int+1))
check_done(list1)
I have an error that I am not sure how to fix as the code works fine until I enter an input such as starting point 10000 and ending point 20000, as it gives me a segmentation fault.
when entered to wing IDE, this is what given back [evaluate palindromeprimes.py] Enter the starting point N: 10000 Enter the ending point M: 20000 The palindromic primes are:aborted (disconnected). when I enter it into my school marking system I get this: Your program produced: Enter the starting point N: Enter the ending point M: Segmentation fault Input supplied to your program: 10000 20000 Differences in the files are as follows: 1,29c1,3
Apparently, i need to make my code more efficient, but I'm not sure how to go about this. I saw told to think of the properties of prime numbers and factors, such as the fact that prime numbers are all odd. Factors occur in pairs, so if the number has no factors before some 'midpoint' then it wont have any after that 'midpoint' either
If your problem is one of computational efficiency then it's not necessarily a Python question
These facts should help to reduce the recursion depth:
There are many more palindromic numbers than primes - therefore check
your number is a prime BEFORE you check it's a palindrome
To check a number is not a prime you only need to check that the
modulus is zero when you divide by number up to (and including) the square root of the candidate
You only need to check that the number modulus is zero when you
divide by prime numbers (if it's divisible by 9, 15, 21 ..., it is divisible by 3)
Have a little problem. I'm writing a simple program that takes an input of numbers (for example, 1567) and it adds the odd numbers together as well as lists them in the output. Here is my code:
import math
def oddsum(n):
y=n%10
if(y==0):
return
if(y%2!=0):
oddsum(int(n/10))
print (str(y),end="")
print (" ",end="")
else:
oddsum(int(n/10))
def main():
n=int(input("Enter a value : "))
print("The odd numbers are ",end="")
oddsum(n)
s = 0
while n!=0:
y=n%10
if(y%2!=0):
s += y
n //= 10
print("The sum would be ",end=' ')
print("=",s)
return
main()
It outputs just fine, in the example it will print 1 5 and 7 as the odd numbers. However, when it calculates the sum, it just says "7" instead of 13 like it should be. I can't really understand the logic behind what I'm doing wrong. If anyone could help me out a bit I'd appreciate it :)
I understand it's an issue with the "s += y" as it's just adding the 7 basically, but I'm not sure how to grab the 3 numbers of the output and add them together.
As #Anthony mentions, your code forever stays at 156 since it is an even num.
I would suggest you directly use the string input and loop through each element.
n = input("Enter a value : ") #'1567'
sum_of_input = sum(int(i) for i in n if int(i)%2) #1+5+7=13
[print(i, end="") for i in n if int(i)%2] #prints '157'
Note that int(i)%2 will return 1 if it is odd.
1567 % 10 will return 7. You might want to add the numbers you printed in oddsum to a list, and use the sum function on that list to return the right answer.
The immediate issue is that n only changes if the remainder is odd. eg 1,567 will correctly grab 7 and then n=156. 156 is even, so s fails to increment and n fails to divide by 10, instead sitting forever at 156.
More broadly, why aren't you taking advantage of your function? You're already looping through to figure out if a number is odd. You could add a global parameter (or just keep passing it down) to increment it.
And on a even more efficient scale, you don't need recursion to do this. You could take advantage of python's abilities to do lists. Convert your number (1567) into a string ('1567') and then loop through the string characters:
total = 0
for c in '1567':
c_int = int(c)
if c_int%2!= 0:
total += c_int
print(c)
print(total)