print factors of a number in python - python

I'm trying to print the factors of the number 20 in python so it goes:
20
10
5
4
2
1
I realize this is a pretty straightforward question, but I just had a question about some specifics in my attempt. If I say:
def factors(n):
i = n
while i < 0:
if n % i == 0:
print(i)
i-= 1
When I do this it only prints out 20. I figure there's something wrong when I assign i=n and then decremented i, is it also affecting n? How does that work?
Also I realize this could probably be done with a for loop but when I use a for loop I can only figure out how to print the factors backwards so that I get: 1, 2, 5, 10....
Also I need to do this using just iteration. Help?
Note: This isn't a homework question I'm trying to relearn python on my own since it's been a while so I feel pretty silly being stuck on this question :(

while i < 0:
This will be false right from the start, since i starts off positive, presumably. You want:
while i > 0:
In words, you want to "start i off at n, and decrement it while it is still greater than 0, testing for factors at each step".
>>> def factors(n):
... i = n
... while i > 0: # <--
... if n % i == 0:
... print(i)
... i-= 1
...
>>> factors(20)
20
10
5
4
2
1

The while condition should be i > 0 and not i < 0 because it will never satisfy it as i begins in 20 (or more in other cases)

Hope my answer helps!
#The "while True" program allows Python to reject any string or characters
while True:
try:
num = int(input("Enter a number and I'll test it for a prime value: "))
except ValueError:
print("Sorry, I didn't get that.")
continue
else:
break
#The factor of any number contains 1 so 1 is in the list by default.
fact = [1]
#since y is 0 and the next possible factor is 2, x will start from 2.
#num % x allows Python to see if the number is divisible by x
for y in range(num):
x = y + 2
if num % x is 0:
fact.append(x)
#Lastly you can choose to print the list
print("The factors of %s are %s" % (num, fact))

Related

List of conditions

I wanted to make a list of conditions for if. I wanted to make a program that would find very high prime numbers. I don't want to write: number % 2 == 0 or - for every number that I divide with. If you know how to make a list of conditions or know how to easier get high prime numbers using yield please give me a hint.
def very_high_prime_numbers_generator():
number = 0
while True:
number = yield
if not (number % 2 == 0 or number % 3 == 0 or number % 7 == 0 or number % 5 == 0 or number % 11 == 0 or number % 17 == 0 or number % 19 == 0 or number % 13 == 0):
print(number)
number_generator = very_high_prime_numbers_generator()
number_generator.send(None)
for i in range(1000,10000):
number_generator.send(i)
You can use a nested loop or any or all to test the divisibility of the number against all those values:
if not any(number % k == 0 for k in (2, 3, 5, 7, 11, 13, 17, 19)):
print(number)
Of course, this still tests only those values, which will not be enough for "very high prime numbers". Instead, you could keep track of the prime number generated so far an test against all of those:
def very_high_prime_numbers_generator():
primes = []
number = 2
while True:
if not any(number % p == 0 for p in primes):
yield number
primes.append(number)
number += 1
number_generator = very_high_prime_numbers_generator()
for _ in range(100):
print(next(number_generator))
(This could be further enhanced by stopping once k**2 > number, e.g. using itertools.takewhile, and only testing odd numbers above 2.)
Also note that your "generator" was rather odd. By using send to set the value of number and then printing inside the function, your "generator" behaved rather like a regular "check if this number is prime" function than a proper generator. The above also fixes that.
This seems to be what you're trying to do although as others have pointed out it's far from efficient.
def find_prime(number, previous_primes):
for value in previous_primes:
if number % value == 0:
return False
return True
known_primes = [2, 3, 5, 7]
for i in range(8, 1000):
is_prime = find_prime(i, known_primes)
if is_prime:
known_primes.append(i)
I would advise having a look here.
a possible solution (yet not that efficient) for printing primes might be as described by Eli Bendersky, in the above link:
import math
def main():
count = 3
while True:
isprime = True
for x in range(2, int(math.sqrt(count) + 1)):
if count % x == 0:
isprime = False
break
if isprime:
print count
count += 1

Python - My query to extract prime numbers does not work

I am attending a course on Udemy and one of the exercises is to return all the prime numbers from a range of numbers (for example all prime numbers before 100)
This is the query that the teacher made
def count_primes2(num):
#Check for 1 or 0
if num < 2:
return 0
######################
#2 or greater
#Store our prime numbers
primes = [2] #I start my list with 2 that is a prime number
#Counter going up to the input num
x = 3 #I create a variable on which I will continue adding until I reach num
# x is going through every number up to the input num
while x <= num:
#Check if x is prime
for y in range(3,x,2): # for y in range from 3 to x in even steps, we only wantto check odd numbers there
if x%y == 0:
x += 2
break
else:
primes.append(x)
x += 2
print(primes)
return len(primes)
count_primes2(100)
However, I came up with the one below that is not working. My idea is:
Given each number i between between 3 and num+1 (for example 100 would be 101 so that 100 can be included in the calculation):
Open a for loop in which I divide i by each number g before i (including i) and I have a counter checking when this division gives no remainder. This implies that in case of prime numbers the counter should always be 2 (for example 3--> 3:1 and 3:3 would give remainder 0).
If the counter is equal to 2, then i is a prime and I want to append it to the list.
I am not using any while loop in my query. Can you help me to identify why my query is not working?
def count_prime(num):
counter=0
list_prime=[2]
if num<2:
return 0
for i in range(3,num+1):
for g in range(1,i+1):
if i%g==0:
counter+=1
if counter==2:
list_prime.append(i)
return list_prime
count_prime(100)
Kudos to Khelwood for the help. Below the working query:
def count_prime(num):
counter=0
list_prime=[2]
if num<2:
return 0
for i in range(3,num+1):
for g in range(1,i+1):
if i%g==0:
counter+=1
if counter==2:
list_prime.append(i)
counter=0
return list_prime
count_prime(100)
you may do this :
for i in range(2,num):
if (num % i) == 0:`
Instead of using two for loops, you can simply eliminate one of the for loop and do this, I hope this may work for you.
thankyou.

hailstone program in python

i have to write a hailstone program in python
you pick a number, if it's even then half it, and if it's odd then multiply it by 3 and add 1 to it. it says to continue this pattern until the number becomes 1.
the program will need methods for the following:
accepting user input
when printing the sequence, the program should loop until the number 1.
print a count for the number of times the loop had to run to make the sequence.
here's a sample run:
prompt (input)
Enter a positive integer (1-1000). To quit, enter -1: 20
20 10 5 16 8 4 2 1
The loop executed 8 times.
Enter a positive integer (1-1000). To quit, enter -1: 30
30 15 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
The loop executed 19 times.
Enter a positive integer (1-1000). To quit, enter -1: -1
Thank you for playing Hailstone.
right now i have this:
count = 0
def hailstone(n):
if n > 0
print(n)
if n > 1:
if n % 2 == 0:
hailstone(n / 2)
else:
hailstone((n * 3) + 1)
count = count + 1
i don't know what to do after this
Try to think in a modular way, make two functions: check_number() and user_call(). Check_number will verify if the current number in the loop is odd or even and the user_call() just wraps it to count how many times the loop did iterate.
I found the exercise in a great book called Automate Boring Stuff with Python, you have to check it out, if you don't know it already.
Here's my code. Try to use what serves you the best.
from sys import exit
def check_number(number):
if number % 2 ==0:
print(number // 2)
return(number // 2)
else:
print(number*3+1)
return number*3+1
def user_call(number):
count = 0
while number != 1:
count += 1
number = check_number(number)
return count
if __name__ == "__main__":
try:
number = int(input('Give a number \n'))
count = user_call(number)
print('count ',count)
except Exception as e:
exit()
you can use global
visit https://www.programiz.com/python-programming/global-keyword to learn more
import sys
res = []
def hailstone(number):
global res
if number > 1:
if number % 2 == 0:
res.append( number // 2 )
hailstone(res[len(res)-1])
else:
res.append(number * 3 + 1)
hailstone(res[len(res)-1])
return res
number = int(input('Enter a positive integer. To quit, enter -1: '))
if number <= 0 or number == 0:
print('Thank you for playing Hailstone.')
sys.exit()
else:
answers = hailstone(number)
for answer in answers:
print(answer)
print('The loop executed {} times.'.format(len(answers) + 1))
I used recursion to solve the problem.
Heres my code:
Edit: All criteria met
count = 0
list_num = []
def input_check():
number = int(input("Enter a positive integer (1-1000). To quit, enter -1: "))
if number >= 1 and number <= 1000:
hailstone_game(number)
elif number == -1:
return
else:
print("Please type in a number between 1-1000")
input_check()
def hailstone_game(number):
global count
while number != 1:
count += 1
list_num.append(number)
if number % 2 == 0:
return hailstone_game(int(number/2))
else:
return hailstone_game(int(number*3+1))
list_num.append(1) # cheap uncreative way to add the one
print(*list_num, sep=" ")
print(f"The loop executed {count} times.")
return
input_check()
Additional stuff that could be done:
- Catching non-integer inputs using try / except
Keep in mind when programming it is a good habit to keep different functions of your code separate, by defining functions for each set of 'commands'. This leads to more readable and easier to maintain code. Of course in this situation it doesn't matter as the code is short.
Your recursive function is missing a base/terminating condition so it goes into an infinite loop.
resultArray = [] #list
def hailstone(n):
if n <= 0: # Base Condition
return
if n > 0:
resultArray.append(n)
if n > 1:
if n % 2 == 0:
hailstone(int(n/2))
else:
hailstone((n * 3) + 1)
# function call
hailstone(20)
print(len(resultArray), resultArray)
Output
8 [20, 10, 5, 16, 8, 4, 2, 1]
Here's a recursive approach for the problem.
count=0
def hailstone(n):
global count
count+=1
if n==1:
print(n)
else:
if n%2==0:
print(n)
hailstone(int(n/2))
else:
print(n)
hailstone(3*n+1)
hailstone(21)
print(f"Loop executed {count} times")

can I get the for loop to run the whole range?

This is my code. I am trying to find the prime numbers before or equal to the integer inputted. However, it seems that the loop stops when it sees an integer in the range that fits the requirements. Unfortunately, this is not I wanted it to do. I would like to make it run through all the tests in the range before making the judgement. Is this possible? If so, how do I do this? Thank you.
def getNumber(main):
n = int(input())
return n
def isPrime(n):
list=[2]
if n > 1:
for i in range(2, n+1):
for a in range (2, n):
if i*a != i and i%a != 0 and i%2 != 0:
list.append(i)
break
return "\n".join(map(str, list))`
def main():
n = getNumber(main)
print(isPrime(n))
main()
You've got your logic a bit wrong. Here's what your code is doing:
Examine numbers in increasing order from 2 to the inputted n.
For each number i, check if any number a between 2 and n divides i
If a divides i, add i to the list, and then move to the next i
This isn't going to get you a prime number. In fact, I'm having trouble figuring out what it will give you, but a prime number probably isn't it. Look at this function instead, which will return all the prime numbers less than or equal to the given number - you can compare it to your code to figure out where you went wrong:
def getPrimesLessThanOrEqualTo(n):
if n <= 1: # Anything 1 or less has no primes less than it.
return "" # So, return nothing.
list = [2] # 2 is the lowest prime number <= n
for i in range(3, n+1): # We start at 3 because there's no need to re-check 2
for a in list: # Instead of iterating through everything less than
# i, we can just see if i is divisible by any of
# the primes we've already found
if i % a == 0: # If one of the primes we've found divides i evenly...
break # then go ahead and try the next i
list.append(i) # Now, if we got through that last bit without
# hitting the break statement, we add i to our list
return "\n".join(list) # Finally, return our list of primes <= i
If you wanted to be more efficient, you could even use range(3, n+1, 2) to count by twos - thus avoiding looking at even numbers at all.
You can use a if/else block if your break is never executed by any item in the iterable the else statement will triggered. https://docs.python.org/3/tutorial/controlflow.html 4.4 demonstrates this accomplishing this almost exact task.
n = int(input('Enter number: '))
if n <= 1:
print('No primes')
else:
primes = []
for i in range(2, n +1):
for k in range(2, i):
if not i % k:
break
else:
primes.append(i)
print(*primes)
# Enter number: 50
# 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47

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

Categories