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)
Related
I am pretty new to Python and just got started in Leet and I am doing the Happy Number question, only half of the test cases have been passed. I would appreciate any help. Thanks
A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.
My test cases were 19, 100 where it output True correctly but when I do 7, it is wrong
def isHappy(self, n: int) -> bool:
if (n == 1):
return True
sum = 0
flag = False
for j in range(1,100):
x = str(n)
a = list(x)
for i in range(0,len(a)):
sum += int(a[i])*int(a[i])
if sum == 1:
return True
break
else:
x = sum
return False
Here is an implementation using a set to keep track of numbers that we have already seen. (I've removed the self argument here for sake of something that can be run outside of your test class.)
def isHappy(n: int) -> bool:
seen = set()
while True:
if n == 1:
return True
if n in seen:
return False
seen.add(n)
n = sum(int(c) ** 2 for c in str(n))
Your code has various issues aside from the fact that the number 100 is arbitrary.
Mainly that you never update n in your loop. Also you do not wait for the completion of the for loop before testing sum (in fact your break is never reached), you initialise sum only once, and you return False prematurely. Here is a minimally corrected version of your code, although still subject to the fact that there is no rule about 100 maximum iterations.
def isHappy(n: int) -> bool:
if (n == 1):
return True
for j in range(1,100):
x = str(n)
a = list(x)
sum = 0
for i in range(0,len(a)):
sum += int(a[i])*int(a[i])
if sum == 1:
return True
else:
n = sum
return False
I seem to have created an infinite loop in my python code. My aim was to create a function 'check' which uses my previous 'goldbach' function to confirm that every even number greater than 4 and up to the inputted N comply with the Goldbach Conjecture (a pretty pointless procedure, I know, but it's for my assignment). I know that my 'goldbach' function is working well and produces a pair of primes that sum to N for 'good' inputs and (0,0) for 'bad' inputs. I want my check function to return True for all even inputs greater than 4 (as these comply with the conjecture), and False for any odd inputs. However, my code won't run when I try my check function in the console so something has gone wrong - any ideas what it is?
def goldbach(N):
x, y = 0, 0
result = 0
if N % 2 == 0:
prime = odd_primes(N)
while result != N:
for i in range(len(prime)):
if result == N: break
x = prime[i]
for j in range(len(prime)):
y = prime[j]
result = x + y
if result == N: break
return x, y
def check(N):
for n in range(4, N+1):
if n % 2 ==0:
g = goldbach(n)
if g == (0,0):
return False
else:
return True
You're returning immediately after checking the first item in the range. You need to return False as soon as you encounter an item that doesn't match expectations, and return True at the end if all of them match expectations.
If you only want to look at even numbers, use a stride of 2 in the range() function rather than testing each number to see if it's even or odd.
def check(N):
for n in range(4, N+1, 2):
if goldbach(n) == (0, 0):
return False
return True
You don't need the while loop in goldbach(). The two for loops test all combinations of primes. If they don't find a matching pair, there's no reason to restart them.
You can also simplify and optimize your loops. The inner loop only needs to test primes starting from x, because pairs of primes where y < x would have already been tested in an earlier iteration of x.
def goldbach(N):
if N % 2 == 0:
prime = odd_primes(N)
for i, x in enumerate(prime):
for y in prime[i:]:
if x + y == N:
return x, y
return 0, 0
However, I think your code should still work, which suggests that the problem is actually that odd_primes() isn't returning all primes up to N.
I just created a replacement for your function odd_primes(N), to return a list of all the primes less than or equal to N (having 2 in the there doesn't seem to make a difference). Your check() function seems to check all integers between 4 and N inclusive, and return False if it finds something for which no Goldbach sum was found. However, as somebody else pointed out, it also immediately returns True once it finds a pair. So what happens when you run check() is that starts with the number 4, finds that its Goldbach pair is (2,2), then immediately quits the function by returning True, ignoring any other values between 4 and N.
When I replace the return True with a print statement and just add a `return True after the entire loop:
def check(N):
for n in range(4, N+1):
if n % 2 ==0:
g = goldbach(n)
if g == (0,0):
print("No sum found for %d !" % n)
return False
else:
print("%d is equal to %d + %d" % (n, g[0], g[1]))
return True
and then run check(20) for example, I get:
4 is equal to 2 + 2
6 is equal to 3 + 3
8 is equal to 3 + 5
10 is equal to 3 + 7
12 is equal to 5 + 7
14 is equal to 3 + 11
16 is equal to 3 + 13
18 is equal to 5 + 13
20 is equal to 3 + 17
By the way, if you just want to know whether a given even number can be written as the sum of two primes but you don't care what the actual pair of primes is, you could do something like this:
def goldbach(N):
if N % 2 == 0:
primes = odd_primes(N)
# Generate a list of all the i+j sums where j >= i (skipping
# most duplicates this way), and see if N is among the sums.
sums = [i + j for i in primes for j in primes[primes.index(i):]]
return(N in sums)
else:
print("N must be even.")
return(False)
I'm new to programming. While trying to solve this problem, I'm getting the wrong answer. I checked my code a number of times but was not able to figure out the mistake. Please, help me on this simple problem. The problem is as follows:
Given a positive integer N, calculate the sum of all prime numbers between 1 and N (inclusive). The first line of input contains an integer T denoting the number of test cases. T testcases follow. Each testcase contains one line of input containing N. For each testcase, in a new line, print the sum of all prime numbers between 1 and N.
And my code is:
from math import sqrt
sum = 0
test = int(input())
for i in range(test):
max = int(input())
if max==1:
sum = 0
elif max==2:
sum += 2
else:
sum = sum + 2
for x in range(3,max+1):
half = int(sqrt(max)) + 1
for y in range(2,half):
res = x%y
if res==0:
sum = sum + x
break
print(sum)
For input 5 and 10, my code is giving output 6 and 48 respectively, while the correct answer is 10 and 17 respectively. Please, figure out the mistake in my code.
Here, I implemented simple program to find the sum of all prime numbers between 1 to n.
Consider primeAddition() as a function and ip as an input parameter. It may help you to solve your problem.Try it.
Code snippet:
def primeAddition(ip):
# list to store prime numbers...
prime = [True] * (ip + 1)
p = 2
while p * p <= ip:
# If prime[p] is not changed, then it is a prime...
if prime[p] == True:
# Update all multiples of p...
i = p * 2
while i <= ip:
prime[i] = False
i += p
p += 1
# Return sum of prime numbers...
sum = 0
for i in range (2, ip + 1):
if(prime[i]):
sum += i
return sum
#The program is ready... Now, time to call the primeAddition() function with any argument... Here I pass 5 as an argument...
#Function call...
print primeAddition(5)
This is the most broken part of your code, it's doing the opposite of what you want:
res = x%y
if res==0:
sum = sum + x
break
You only increment sum if you get through the entire loop without breaking. (And don't use sum as you're redefining a Python built-in.) This can be checked using the special case of else on a for loop, aka "no break". I've made that change below as well as corrected some inefficiencies:
from math import sqrt
T = int(input())
for _ in range(T):
N = int(input())
sum_of_primes = 0
if N < 2:
pass
elif N == 2:
sum_of_primes = 2
else:
sum_of_primes = 2
for number in range(3, N + 1, 2):
for odd in range(3, int(sqrt(number)) + 1, 2):
if (number % odd) == 0:
break
else: # no break
sum_of_primes += number
print(sum_of_primes)
OUTPUT
> python3 test.py
3
5
10
10
17
23
100
>
A slight modification to what you have:
from math import sqrt
sum = 0
test = int(input())
max = int(input())
for x in range(test,max+1):
if x == 1:
pass
else:
half = int(sqrt(x)) + 1
for y in range(2,half):
res = x%y
if res==0:
break
else:
sum = sum + x
print(sum)
Your biggest error was that you were doing the sum = sum + x before the break rather than outside in an else statement.
PS: (although you can) I'd recommend not using variable names like max and sum in your code. These are special functions that are now overridden.
Because your logic is not correct.
for y in range(2,half):
res = x%y
if res==0:
sum = sum + x
break
here you check for the factors and if there is a factor then adds to sum which is opposite of the Primes. So check for the numbers where there is no factors(except 1).
from math import sqrt
test = int(input())
for i in range(test):
sum = 0
max = int(input())
if max==1:
sum = 0
elif max==2:
sum += 2
else:
sum = sum + 2
for x in range(3,max+1):
half = int(sqrt(x)) + 1
if all(x%y!=0 for y in range(2,half)):
sum = sum + x
print(sum)
First of all, declare sum to be zero at the beginning of the for i loop.
The problem lies in the if statement at almost the very end of the code, as you add x to the sum, if the res is equal to zero, meaning that the number is indeed not a prime number. You can see that this is the case, because you get an output of 6 when entering 5, as the only non-prime number in the range 1 to and including 5 is 4 and you add 2 to the sum at the beginning already.
Last but not least, you should change the
half = int(sqrt(max)) + 1
line to
half = int(sqrt(x)) + 1
Try to work with my information provided and fix the code yourself. You learn the most by not copying other people's code.
Happy coding!
I believe the mistake in your code might be coming from the following lines of code:
for x in range(3,max+1):
half = int(sqrt(max)) + 1
Since you are looping using x, you should change int(sqrt(max)) to int(sqrt(x)) like this:
for x in range(3,max+1):
half = int(sqrt(x)) + 1
Your code is trying to see if max is prime N times, where you should be seeing if every number from 1-N is prime instead.
This is my first time answering a question so if you need more help just let me know.
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))
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)