Checking integers in python - python

I need to write a code that asks the user for a range of integers and then calculates which integers in that range have at least 3 factors (excluding 1 and the integer itself). I don't know how to take into consideration the fact that an integer can have multiple same factors, for example, in my code integer 8 returns a false value because the program divides it into two integers, 2 and 4. I want the return value to be true, because 8 can be divided into three factors of 2. How do i fix it?
def does_integer_have_3_or_more_factors(x):
num_of_factors = 0
for i in range(2, x):
if x % i == 0:
num_of_factors += 1
if num_of_factors >= 3 :
return True
else :
return False
def main():
integer1 = int(input("Give first positive integer.\n"))
integer2 = int(input("Give last integer.\n"))
print("These integers have at least 3 factors.")
for x in range(integer1, integer2 + 1):
if does_integer_have_3_or_more_factors(x) == True:
print(x)
main()

You need to use the factors you found, and apply them as often as necessary. Maybe you also want to keep track of the factors you found.
factors = []
...
for ... # see below
while x > 1 and not x%i:
factors.append(i)
x /= i
You can also stop checking for factors after sqrt(x) has been reached.
from math import sqrt
for i in range(2,int(sqrt(x))+1):
Finally, you're handling booleans in an overly complicated way. Just do
return len(factors) > 2 # "len(factors) > 2" will result in True or False directly
and check for
if does_integer_have_3_or_more_factors(x):
print(x)

Related

Creating a function that checks perfect numbers python

I've been trying to create a function that checks for perfect numbers, I've used many of the resources I found here, but they don't seem to work for some reason. In my assignment, I'm required to find different types of numbers in a given range input, but this is the only function that doesn't work properly. This is what I have:
def is_perfect(a): #creates a perfect number checker
sum=0
for i in range(1,a):
if a%1==0:
sum += i
if sum==a:
return True
else:
return False
Change the line from a%1==0 to a%i==0 and your code will work perfectly. Because you've to check that the number is divisible from 1 to a and not only 1. It will return always True until it is not integer. Hence, it will keep adding all nos from 1 to a
A perfect number is any number that has the sum of it's devisors, excluding itself, equal to this number. Like the number six that is divided by 1, 2 and 3 and 1 + 2 + 3 = 6.
def is_perfect(number):
sum_ = sum([x for x in range(1, number) if number % x == 0])
return sum_ == number
is_perfect(6) # Returns True
is_perfect(10) # Returns False
is_perfect(28) # Returns True
I called the variable that sum all the divisors with a underscore because sum is already a function keyword in Python
def isPerfect( n ):
sum = 1
i = 2
while i * i <= n:
if n % i == 0:
sum = sum + i + n/i
i += 1
# If sum of divisors is equal to
# n, then n is a perfect number
return (True if sum == n and n!=1 else False)

Find The Parity Outlier Python

def find_outlier(lstOfints):
for integer in lstOfints:
#print(integer)
if integer % 2 ==1:
integer
elif integer % 2 == 0:
integer
return integer
I keep getting the incorrect answer and I don't know what's going on.
This is the problem:
You are given an array (which will have a length of at least 3, but could be very large) containing integers. The array is either entirely comprised of odd integers or entirely comprised of even integers except for a single integer N. Write a method that takes the array as an argument and returns this "outlier" N.
This seems to work for me:
def find_outlier(lstOfints):
if lstOfints[0] % 2 == 1 and lstOfints[1] % 2 == 1:
for integer in lstOfints[2::]:
if integer % 2 == 0:
return integer
elif lstOfints[0] % 2 == 0 and lstOfints[1] % 2 == 0:
for integer in lstOfints[2::]:
if integer % 2 == 1:
return integer
else:
if lstOfints[0] % 2 == lstOfints[2] % 2:
return lstOfints[1]
else:
return lstOfints[0]
Firstly, I am seeing if this list is either all odds, or all evens, bar the outlier. Then if it is even, it goes through the list looking for an odd number, the same for if the list is all odd. However, if the outlier is in the first two numbers, then it checks to see whether the outlier is the first number or the second number by comparing the modulos to the modulo of the third number in the list.
A pythonic answer might be something like that:
def find_outlier(lst):
mods = [n % 2 for n in lst]
return lst[mods.index(0)] if sum(mods[:3]) > 1 else lst[mods.index(1)]
print(find_outlier([5, 31, 57, 45, 9, 17, 8, 37, 123, 67])) # --> 8
print(find_outlier([4, 30, 56, 44, 8, 16, 7, 36, 122, 66])) # --> 7
Explanation: first create the list of all n % 2 for all n in the provided list. Then you simply have to check the sum of the first 3 elements of this new list to know whether the outlier is odd or even. Then find index of the outlier remainder (either 0 or 1) and return the corresponding integer from the first list...
There are many things to change in your code, so I will try to change it at steps to get it working at the end.
Run the function from the question
Well, I tested your code here and I see why it is confusing. I have this script:
def find_outlier(lstOfints):
for integer in lstOfints:
#print(integer)
if integer % 2 ==1:
integer
elif integer % 2 == 0:
integer
return integer
print(find_outlier([1,3,4,5]))
print(find_outlier([1,2,3,4]))
...and if I run it, we get this:
$ python disparity.py
5
4
It is just printing the last number! Why so?
Why is it always printing the last number from the list?
Well, because you just return at the end of the function. You expect the function to return from inside the if statement, but you did not used the return command. It is easy to solve:
def find_outlier(lstOfints):
for integer in lstOfints:
if integer % 2 ==1:
return integer
elif integer % 2 == 0:
return integer
return integer
print(find_outlier([1,3,4,5]))
print(find_outlier([0,2,3,4]))
So now we run it and get
$ python disparity.py
1
0
Now it is just returning the first element!
Why is it now always printing the first number from the list?
It prints the first element because your if statements are complementary. Given any element, regardless of its parity, it modulo 2 will be either 0 or 1. If it is zero, the first if returns; if it is 1, the second returns! Since it is true to all elements, it is true to the first one, so the function ends at the very first iteration.
This is not the algorithm you want. What you want is to first know which parity is the outlier, and then look for the outlier number.
How to discover which parity is an outlier if I don't know which number is the outlier?
Since the list has at least three elements, that is easy: we consider two scenarios.
The first scenario is, the outlier is one of the first three elements. In this case, we will have one outlier parity and two "normal" parities.
The second scenario is, the outlier is not one of the first three elements. In this case, we will have three equal parities, and the outlier will be the opposite one.
So, if we count the number of even numbers and odd numbers in the first three values, we know that the parity with less numbers is the outlier one.
If there are more even numbers than odd numbers (either two even and one odd, or three even and no odd), then we know the outlier is odd.
If there are more odd numbers than even numbers, we know the outlier is even.
Now, how to do it in code?
To do that, I will write pieces of code below that, at then end, put together, will give us the answer. First I create two variables to count the even and odd numbers (with 0 at first).
even_numbers = 0
odd_numbers = 0
Then, I see if the first element is even. If so, I increment the counter of even numbers:
if listOfints[0] % 2 == 0:
even_numbers = even_numbers + 1
else:
odd_numbers = odd_numbers + 1
Then I do the same thing with the second and third elements:
if listOfints[1] % 2 == 0:
even_numbers = even_numbers + 1
else:
odd_numbers = odd_numbers + 1
if listOfints[2] % 2 == 0:
even_numbers = even_numbers + 1
else:
odd_numbers = odd_numbers + 1
If we have more even numbers than odd numbers, we know the outlier parity is odd (that is, the rest of the division of the outlier to 2 is 1); if we have more odd numbers than even numbers, the outlier parity will be even (that is, the rest will be zero)
if even_numbers > odd_numbers:
outlier_parity = 1
else:
outlier_parity = 0
So, now I know if the outlier number is even or odd, I agree. But I want to know what is the number!
Now that we do know the parity of the outlier, we just need to look for it:
for integer in lstOfints:
if integer % 2 == outlier_parity:
return integer
Bundling all together, this is our new function:
def find_outlier(lstOfints):
even_numbers = 0
odd_numbers = 0
if lstOfints[0] % 2 == 0:
even_numbers = even_numbers + 1
else:
odd_numbers = odd_numbers + 1
if lstOfints[1] % 2 == 0:
even_numbers = even_numbers + 1
else:
odd_numbers = odd_numbers + 1
if lstOfints[2] % 2 == 0:
even_numbers = even_numbers + 1
else:
odd_numbers = odd_numbers + 1
if even_numbers > odd_numbers:
outlier_parity = 1
else:
outlier_parity = 0
for integer in lstOfints:
if integer % 2 == outlier_parity:
return integer
print(find_outlier([1,3,4,5]))
print(find_outlier([0,2,3,4]))
Does it work? Let's test:
$ python disparity.py
4
3
Oh, it worked! Not bad, right? :)
Some considerations
This code here isn't the most elegant, but my purpose here is mostly that you understand what is going on. It could be done with a waaaaaay shorter, more readable function, but since you are still looking for basic concepts, I did a more detailed, explainable function, which is kind of cumbersome as a consequence.
my solution is:
def find_outlier(integers):
odd = []
even = []
for i in integers:
if i% 2 != 0:
odd.append(i)
elif i% 2 == 0:
even.append(i)
if len(odd) < len(even):
return odd[0]
else:
return even[0]

How to find the majority integer that is divisible by the integer 10?

I'm writing a function "most_of" that takes a list of numbers as a argument. The objective of the function is to take the list, iterate over it and find out if the majority of the list integers are divisible by 10.
So for example, if I had passed the argument:
[1,10,10,50,5]
The output would be:
True
Because 3/5 of the integers are divisible by 10. However, if I had passed:
[1,2,55,77,6]
The output would be:
False
Because 4/5 of the list integers are not divisible by 10.
Here is what I have tried:
def most_of(lst):
for i in lst:
if lst[i] % 10 == 0:
lst == True
else:
lst == False
I'm basically stuck at this point because this doesn't check if the majority of the numbers are divisible by ten, it just divides.
Thanks for the help!
Count how many integers are divisible by ten, and test whether that number is "the majority" - that is, if it's greater than or equal to half the lists' length. Like this:
def most_of(lst):
num = sum(1 for n in lst if n % 10 == 0)
return num >= len(lst) / 2.0
For example:
>>> most_of([1,10,10,50,5])
True
>>> most_of([1,2,55,77,6])
False
The objective of the function is to take the list, iterate over it and
find out if the majority of the list integers are divisible by 10.
Your list will contain two kind of integers: those that are divisible by 10 and those that aren't. You need to find the number of integers in each of the two categories, compare those numbers and return True or False accordingly. So, your function would look like this:
def most_of(lst):
divisible_counter = 0
non_divisible_counter = 0
for element in lst:
if element % 10 == 0:
divisible_counter +=1
else:
non_divisible_counter += 1
if divisible_counter > non_divisible_counter:
return True
else:
return False
Of course, all the above code could be reduced a lot. But I wanted to show an algorithm that would be easier to understand for Python beginners.
A slight modification of the answer by Oscar:
def most_of(lst):
return sum(1 if n % 10 == 0 else -1 for n in lst) >= 0
with the same results of course
lst1 = [1,10,10,50,5]
lst2 = [1,2,55,77,6]
print(most_of(lst1)) # True
print(most_of(lst2)) # False
you assign your list a bool after you test your first number, but you have to count all numbers which can divide by ten without rest and all other numbers and then compare this counters:
def most_of(lst):
divideByTen = 0
otherNumbers = 0
for i in lst:
if i % 10 == 0:
divideByTen+=1
else:
otherNumbers+=1
if(divideByTen > otherNumbers):
return True
else:
return False
a = [1,10,10,50,5]
b = [1,2,55,77,6]
print(most_of(a))
print(most_of(b))

given and integer, return the next integer that is a prime number and a palindrome . Python

Given any random integer, create a function to find the next number that is a prime number and also a palindrome.
My attempt
def golf(number):
x = number + 1
for i in range(2, x):
if x % i == 0 or str(x) != str(x)[::-1]:
golf(number + 1)
return x
E.g golf(13) = 101
I'm actually looking for an alternative option than the recursion method i used. How can this best be accomplished without using recursion?
Thanks
Here's a variation on byron he's answer which adds several optimizations:
We can eliminate all even x values (other than 2) before doing any elaborate tests, since we can trivially tell they are not prime.
A small improvement is to only call str(x) once, and reuse the value later.
We can take advantage of the fact that all even-length palindromes are multiples of 11, which means that (except for 11 itself) they're not prime. We can jump ahead to the next odd-length x value.
Since we've already eliminated even numbers, our prime test only needs to test odd divisors. Further we can stop our loop when we reach sqrt(x), rather than going all the way to x itself.
Finally, there's no need to use a Boolean flag variable to carry the primeness out of the loop. If we don't break, the else block attached to the loop will be run.
The code:
import math
def next_prime_palindrome(x):
while True:
x += 1
if x > 2 and x % 2 == 0: # even numbers greater than 2 are non-prime
continue
s = str(x) # compute str(x) just once
if x > 11 and len(s) % 2 == 0: # all even-length palindromes are multiples of 11
x = 10 ** len(s) # so jump to the next odd-length integer
continue
if s != s[::-1]: # palindrome test
continue
for i in xrange(3, round(math.sqrt(x))+1, 2): # loop over odd potential divisors
if x % i == 0: # prime test
break
else: # this else block runs only if no break happened in the loop, so x is prime
return x
Here are some tests runs, showing a few cases where the optimizations save significant time:
>>> next_prime_palindrome(1)
2
>>> next_prime_palindrome(3)
5
>>> next_prime_palindrome(9)
11
>>> next_prime_palindrome(11)
101
>>> next_prime_palindrome(99999)
1003001
>>> next_prime_palindrome(999999999)
10000500001
A further improvement might be to directly generate palindromes, rather than working with integers to start with, and doing a palindrome test to filter them. That would get quite a bit further from your original design, so I'll leave that for someone else.
Palindrome are a sparser set of numbers than primes, and you can generate palindromes directly.
Consider the sequence 98.102
These are palidrome numbers you can base on these
989, 9889, 999, 9999, 10001, 100001, 10101, 101101, 10201, 102201
ADDED
Not also that all of the palidromes with an odd number of digits will come before the palidromes with an even number of digits.
If you write this as a generator (ie using yield) get get a straightforward algorithm for generating palindromic numbers in order.
For 1..9 you generate either 9 or 18 palindromes depending upon whether you consider 1 digit numbers palindromic.
For 10..99 you generate 90 even digit and 90 odd digit palindromes.
For 100..999 you generate 900 even digit and 900 odd digit palindromes.
You have just generated all 1989 (or 1997 if including single digit numbers) of the palindromic numbers less than 1 million. There are 78,498 primes less than 1 million
Any algorithm that is based on generating primes then testing for a palindrome will be much slower that generating palindromes and then testing for primes
def golf(number):
primes = []
i = 2
while i <= number:
if isPrime(i, primes):
primes.append(i)
i += 1
answer = primes[-1] + 1
while True:
if isPrime(answer, primes):
primes.append(answer)
if str(answer) == str(answer)[::-1]:
return answer
answer += 1
def isPrime(n, primes):
for (p for p in primes if p<=n**0.5):
if n%p == 0:
return False
return True
Your solution can be slightly modified in order to create an iterative solution:
def golf(number):
x = number + 1
while True:
is_golf = True
for i in range(2, x):
if x % i == 0 or str(x) != str(x)[::-1]:
is_golf = False
break
if is_golf:
return x
x += 1
improved according to Blckknght's advice, thanks.
def golf(number):
x = number
while True:
x += 1
if str(x) != str(x)[::-1]:
continue
for i in xrange(2, x):
if x % i == 0 :
break
else:
return x

Prime number checker function is faulty

I wrote a function to calculate whether or not a number is prime, but try as it might, it just seems unable to give the correct response. It also prints the n value that is being incremented. Here is the code for the function (in Python, by the way):
def isPrime(x):
for n in range(1, x):
print n
if x % n == 0:
return False
return True
If I input
isPrime(17)
the function returns
1
False
What is going wrong here?
Every number is divisible by 1 and itself. A prime number is a natural number that has no positive divisors other than 1 and itself. Therefore, if you start your for-loop with 1, every number x will pass the condition x % 1 == 0 in the first iteration, returning False.
To fix it, you need to start your loop with 2 instead of 1. Also, as a side-note, you just need to loop from 2 to sqrt(x), since if there exists a number q > sqrt(x) that divides x, then there must also be a number p = x / q which also divides x, and p < sqrt(x).

Categories

Resources