The program I am writing is tasked with creating a list of all possible factors of a number, excluding the number itself. My code is as follows:
def list_all_factors(num):
result = []
for i in range(0, num):
if num % i == 0:
result.append(i)
return result
When I call this function I get the following error:
ZeroDivisionError: integer division or modulo by zero
What is causing this issue, and how can I resolve it?
The for loop:
for i in range(0, num)
should be
for i in range(1, num)
We change the lower bound to avoid attempting to divide by zero.
That's because you are trying to divide by zero as the error says in the for loop. You should start the range from 1 to avoid it.
def list_all_factors(num):
result = []
for i in range(1, num+1):
if num % i == 0:
result.append(i)
return result
or list comprehension
def list_all_factors(num):
result = [i for i in range(1,num+1) if num % i == 0]
return result
Related
I was trying to write a code to select the prime numbers in a list. The user gives a limit and the program displays all prime number from 2 to the limit. I was trying to reduce the maximum amount of lines I could and was surprised with some situations I can't understand. If you can help me, I'd be grateful.
I wrote this code:
# returns all integers from 2 to a limit given by the user.
def primes(limit):
# generates the numbers.
lista = range(2, limit + 1)
p = 2
while p < limit:
#filters the prime numbers and places in a list.
lista = [i for i in lista if i == p or i % p != 0]
p += 1
return lista
def main():
#asks the user for the limit number.
l = int(input("Enter the limit: "))
#call the function which selects the numbers and returns the result.
return print(primes(l))
#Ensures that the main program only runs when the functions have not been imported into another file.
if __name__ == '__main__':
main()
It runs as I expected, but when I tried deleting the first list assignment line and include the range function directly into the comprehension, it doesn't work. Why?
# returns all integers from 2 to a limit given by the user.
def primes(limit):
p = 2
while p < limit:
#filters the prime numbers and places in a list.
lista = [i for i in range(2, limit + 1) if i == p or i % p != 0]
#or lista = [i for i in range(2, limit + 1) if i == p or i % p != 0]
#or lista = [i for i in [*range(2, limit + 1)] if i == p or i % p != 0]
p += 1
return lista
def main():
#asks the user for the limit number.
l = int(input("Enter the limit: "))
#call the function which selects the numbers and returns the result.
return print(primes(l))
#Ensures that the main program only runs when the functions have not been imported into another file.
if __name__ == '__main__':
main()
Other problem. As the line with range is not a list I fixed it only to improve the code, but when I changed the name of the value from 'lista' to another name, I saw that it doesn't work too. Why?
# returns all integers from 2 to a limit given by the user.
def primes(limit):
# generates the numbers.
nums = range(2, limit + 1)
p = 2
while p < limit:
#filters the prime numbers and places in a list.
lista = [i for i in nums if i == p or i % p != 0]
p += 1
return lista
def main():
#asks the user for the limit number.
l = int(input("Enter the limit: "))
#call the function which selects the numbers and returns the result.
return print(primes(l))
#ensures that the main program only runs when the functions have not been imported into another file.
if __name__ == '__main__':
main()
Thanks for your attention.
This one-liner works perfectly :
def primes(val):
return [x for x in range(2, val) if all(x % y != 0 for y in range(2, x))]
print(primes(10))
Thank you for your attention.I liked the answer of our friend Yash Makan, but when I tried larger numbers, like 100000, it never led me to the result (or I was not so patient to wait). So I continued thinking about the problem and got the following that is the fastest way to compute this problem I could achieve with list comprehension. Note how fast you can compute millions of numbers.
# returns all integers from 2 to a limit given by the user.
def primes(limit):
l = [i for i in range(2, limit + 1) if all(i % j != 0 for j in [2, 3, 5])]
lista = []
return [2, 3, 5] + [lista.append(i) or i for i in l if all( i % j != 0 for j in lista[:int((len(lista) ** .5) + 1)])]
def main():
l = int(input("Enter the limit: "))
return print(primes(l))
if __name__ == '__main__':
main()
When I run the following code for some reason it says that the break is incorrect but works if I delete the break.
Can anyone help me to understand why?
composites = []
for i in range(101):
for j in range(i):
if (i % j) == 0:
composites.append(i)
break
print("Composites: ", *composites)
The sample code provided threw a ZeroDivisionError instead of a break error. Problem is with the second range as the modulo function cannot be done with 0.
Since composites are non-prime numbers, factors checking should start from 2. Changing the second range function to range(2, i) should solve this.
composites = []
for i in range(101):
for j in range(2, i):
if (i % j) == 0:
composites.append(i)
break
print("Composites: ", *composites)
This code works for me in python 3.7, range(10) will produce [0,1,2,3,4,5,6,7,8,9] which will give ZeroDivisionError: integer division or modulo by zero
composites = []
for i in range(1,101):
for j in range(2,i):
if (i % j) == 0:
composites.append(i)
break
print("Composites: ", *composites)
I am about to execute a function which aim is to return a Prime/Not prime statement if its argument is or isn't a prime number. I succeeded using a for loop:
def prime1(n):
z = []
for i in range (1, n+1):
if (n/i).is_integer():
z.append(i)
i=i+1
if len(z) == 2:
print ("Prime")
else:
print ("Not prime")`
Then I tried to do the same but using the while loop:
def prime2(n):
z = []
i = 1
while i < int(len(range(1, n+1))):
if (n/i).is_integer():
z.append(i)
i=i+1
if len(z) == 2:
print ("Prime")
else:
print ("Not prime")
Unfortunately, my system continues to calculating without printing me an output.
Can you explain me where I have made a mistake?
The i = i + 1 does nothing in your for loop, since the value of i is overwritten with the next value of the iterator; effectively, the for loop is performing i = i + 1 for you on every iteration, whether or not i divides n. You need to do the same thing in your while loop:
while i < n + 1:
if (n/i).is_integer():
z.append(i)
i = i + 1
The most pythonic way I could think of is below:
def isPrime(n):
return all(n % i for i in range(2, int(n ** 0.5) + 1)) and n > 1
for i in range(1, 20):
print(isPrime(i))
Explanation:
all makes sure that every item in the given expression returns True
n % i returns True if n != 0 (even negative numbers are allowed)
int(n ** 0.5) is equivalent to sqrt(n) and as range always returns numbers up to n - 1 you must add 1
n > 1 makes sure that n is not 1
The problem in your code is that your i = i + 1 in the wrong scope
Your program checks if (n/i).is_integer() which returns False as n / 2 is not a integer
Improving your code:
Instead of (n/i).is_integer() you can use n % i == 0, which returns the remainder equals 0
Next you must place i = i + 1 in the outer scope
And personally, I was never a fan of i = i + 1. Use i += 1
I think the best way is using the code I have shown above.
Hope this helps!
Edit:
You can make it print 'Prime' or 'Not Prime' as follows:
def isPrime(n):
print('Prime' if all(n % i for i in range(2, int(n ** 0.5) + 1))
and n > 1 else 'Not Prime')
for i in range(1, 20):
isPrime(i)
You are increment the iterable variable i inside the if statement, so the variable is never incremented, stucking on an infinite loop.
When you used for it worked because the iterable changes itself after every full iteration of the block.
Moving the incremenf of i one identation block to the left (inside the while instead of for) will work just fine
Code adapted from https://www.programiz.com/python-programming/examples/prime-number
You don't need to check until num and you can go 2 by 2 if you don't have a database of prime numbers
import math
#num = 437
if num > 1:
# check for factors
for i in range(2, int(math.ceil(math.sqrt(num))), 2):
if (num % i) == 0:
print(num, "is not a prime number")
print(i, "times", num // i, "is", num)
break
else:
print(num, "is a prime number")
# if input number is less than
# or equal to 1, it is not prime
else:
print(num, "is not a prime number")
Our preferred method should not be while loops if we don't need to use them, that being said, we could use list comprehensions:
def prime(n):
z = []
[z.append(i) for i in range(1, n+1) if (n/i).is_integer()]
[print("Prime") if len(z) == 2 else print("Not Prime")]
prime(101)
But lets take a loop at what you got your for loop:
for i in range (1, n+1):
if (n/i).is_integer():
z.append(i)
i=i+1
The line i = i + doesn't serve the purpose you intend, the loop is going to iterate from 1 to n+1 no matter what
Now the while loop:
while i < int(len(range(1, n+1))):
if (n/i).is_integer():
z.append(i)
# i=i+1 does not go inside if statement
i += 1
Now you do need to increment i but if that incrementing only occurs when the if conditions are met, then if the if condition is not met you are going to be stuck at the same i looping over it.
Also try using i += 1 means the same thing
Beginner. I'm trying to return a list that includes all the prime numbers from 0 to num. Could someone please help me find what's wrong with my code? I always get an empty list. Thanks a lot! (I'm using python 3.6)
def task(num):
num = int(num)
lst = []
if num < 3:
return lst
else:
for i in range(3,num):
if not i & 1:
lst = lst
else:
primetest = range(3, int(i ** 0.5) + 1, 2)
for n in primetest:
if i % n != 0:
lst.append(i)
return lst
task(5)
Updates:
Thank you guys for all your comments! Really helpful.
This is what my revised code looks like.
def task(num):
num = int(num)
lst = []
if num < 2:
return lst
if num >= 2:
lst.append(2)
for i in range(3, num + 1):
if i % 2 == 1:
switch = True
for n in range(3, int(i ** 0.5) + 1, 2):
if i % n == 0:
switch = False
break
if switch:
lst.append(i)
return lst
The main problem lies with your inner for loop :
With your code you will append the list with i each time you find a number in the primetestrange that is not a divisor of i.
You might want to use a boolean here to store the fact that you found a divisor of i, then only append it to the list if you didn't.
To answer your question, your list is empty because the primetestrange is always empty in your example :
int(3**0.5) + 1 = 3 and int(5**0.5) + 1 = 3
range(3,3,2) = []
The array is empty because the range function will not include the upper limit, and since the inner loop is not doing what it should be expected to do in your code, the result will be an empty list until the parameter of the task function is superior or equal to 9
Your code gets it wrong on several counts, tell me if you understand why the following works?
def task(num):
num = int(num)
lst = [2]
if num < 3:
return lst
for i in range(3, num + 1):
if i % 2 == 1:
for n in range(3, int(i ** 0.5) + 1, 2):
if i % n == 0:
break
else:
lst.append(i)
return lst
(note: the for else clause is quite natural here, for else clauses are used when you search for something in a loop, you break when you find that something, if not break is encountered and the regular stopIteration is used to exit the loop the else part is performed, I say it is natural here since in pseudo code you would say something like "if my number can be divided by another number less than its square it is not prime, otherwise add it to the list of primes" see http://book.pythontips.com/en/latest/for_-_else.html for more detauls)
Its by no means a fast way to do it but I tried to stay as close to the spirit of your attempt while improving the aesthetics of the code
you can find prime numbers and the most dividable one in a dateset.`
a=[ int(x) for x in input("Enter 10 values: ").split() ]
c=[]
prime=[]
b=max(a)
for num in range(1,b+1):
for i in range(2,num):
if (num%i)==0:
break
else:
prime.append(num)
for i in a:
for j in prime:
if i%j==0:
c.append(i)
from collections import Counter
e=Counter(c)
f=e.most_common(1)
f
def prim(z):
lst = []
for i in range(2, z+1):
for j in range(2,i):
if i % j == 0:
break
else:
lst = lst + [i]
return lst
print(prim(20))
result:
[2, 3, 5, 7, 11, 13, 17, 19]
I am extremely new to programming. I have been working on a project where the user is asked to import a number, which goes through a mathematical series. The output is then put into a function to find the factors of the number. From there I am trying to find the factors that are prime numbers?
This is what i have so far.
enter code here####################################
n = int(input("Enter the n value"))
num = sum(10**x for x in range(n))
print("S",n,"is", num)
#####################################
# Factors
#function name nfactors
def nfactors(x):
# This function takes a number and prints the factors
print("The factors of",x,"are:")
for i in range(1, x + 1):
if x % i == 0:
print(i)
fact = nfactors(num)
print(fact)
#####################################
print('The prime numbers are:')
if fact > 1:
# check for factors
for i in range(2,fact):
if (fact % i) == 0:
break
else:
print(fact)
I know this is bad programming but I am trying to learn through doing this project. How can I then take the factors I received as the output of the function and find which factors are prime numbers. I cannot figure out how to name a variable inside the function and use that outside the function, I don't know if this is even possible. If you need any clarifications please let me know. Thanks for any help.
def nfactors(x):
# This function takes a number and prints the factors
print("The factors of",x,"are:")
for i in range(1, x + 1):
if x % i == 0:
print(i)
return i
fact = nfactors(num)
Use the return keyword to return the value of i or whatever it is you would like to use outside of the function!
I seriously hope that you are trying to find the factors of n instead of num as finding the factors of num for a mere number n=12 is a great deal and it'll take several minutes or even hours even with my optimized code.
Anyway assuming you want to find it for n and not num the below code should do your job.
In case you really want to find factors for num, this code will work fine for that too but it'll take too much time. Just change factors = factors(n) to factors = factors(num).
from math import sqrt
#Block 1 (Correct)
n = int(input("Enter the n value"))
num = sum(10**x for x in range(n))
print("S",n,"is", num)
#---------------------------------------------------
def factors_(x):
# This function takes a number and prints the factors
print("The factors of",x,"are:")
list_of_factors = []
for i in range(1, x + 1):
if x % i == 0:
list_of_factors.append(i)
return(list_of_factors) #This returns a list of factors of a given number x
factors = factors_(n) #I am assuming you want to find the prime factors of n instead of num
print(factors)
#------------------------------------------------------------------------------------
def is_prime(num): #This function returns True(1) if the number is prime else Flase(0)
if num == 2:return 1
if num%2 == 0:return 0
i = 3
while i < int(round(sqrt(num)) + 1):
if num % i == 0:return 0
i += 2
return 1
#---------------------------------------------------------------------------------------
prime_factors = []
for i in factors:
if is_prime(i):
prime_factors.append(i)
print("The prime factors of the numbers are:")
print(prime_factors)