I'm trying to make a program that finds the perfect number.(Perfect number=The sum of its divisors except itself is a number equal to itself.)And I want to add one more thing. Firstly I want to define an empty list and put the perfect numbers in it.But When I run the programm I didn't take the right throughput.How can I solve this problem.
My cods
def perfect(number):
total = 0
for i in range(1,number):
if number % i == 0:
total += i
return total
perfect_number_set = []
for i in range(1,1001)
if perfect(i):
perfect_number_set += [perfect(i)]
print(perfect_number_set)
print(i)
The output of the codes I wrote
[True]
6
[True,True]
28
[True,True,True]
You have following issues in your code:
Your implementation of perfect method is incorrect. You need to return True/False if a number is perfect. You are returning the total which is not correct.
Missing colon : in the for loop
def perfect(number):
total = 0
for i in range(1,number):
if number % i == 0:
total += i
return total == number
perfect_number_list = []
for i in range(1,1001):
if perfect(i):
print(i)
perfect_number_list.append(i)
print(perfect_number_list)
There is a difference between set and a list in python. You have used a list.
Set contains only unique entries.
Best practice tip:
defining a list use :
list_name = list()
Better way of adding items to as list by using it's method
list_name.append(list_item_to_add)
Another thing is that returning a number and checking it in if without any condition is not readable. Change it to:
if perfect(i) != 0:
(Altho Yours implementation work, because python if treats 0 like False and any other value as True)
Related
during the Kata on Codewars called 'Find The Parity Outlier' I faced a problem, and have been trying to solve it using dictionary. I pass almost all tests except 4.
Instruction for the Kata is:
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.
The function is:
def find_outlier(integers):
d = dict()
count = 0
count1 = 0
for i in range(len(integers)):
if integers[i] % 2 != 0 :
d['odd'] = integers[i]
else:
d['even'] = integers[i]
for j in range(len(integers)):
if integers[j] % 2 == 0:
count += 1
else:
count1 += 1
if count > count1:
return d['odd']
return d['even']
Test Results:
2 should equal 1
36 should equal 17
36 should equal -123456789
0 should equal 1
So the question is? Why is it so? Can you help me to sort the problem out? Thanks a lot!
I'm not sure what exactly you're referring to with that list of test results. In general though, your method with the dictionary seems like it might be overcomplicating things a bit as well. You shouldn't need to use a dict, and you shouldn't need two for loops either. Here's an alternative solution to this problem using only list comprehension.
def find_outlier(arr):
# input should be an array-like of integers (and length >= 3) with either only one odd element OR only one even element
odd_mask = [n%2 != 0 for n in arr] # boolean array with True in the location(s) where the elements are odd
even_mask = [n%2 == 0 for n in arr] # boolean array with True in the location(s) where the elements are even
N_odd = sum(odd_mask) # number of odd elements in the input
N_even = sum(even_mask) # number of even elements in the input
if N_even == 1: # if even is the 'outlier'...
return arr[even_mask.index(True)] # return the element of the input array at the index we determined we had an even
elif N_odd == 1: # if odd is the 'outlier'...
return arr[odd_mask.index(True)] # return the element of the input array at the index we determined we had an odd
else: # something has gone wrong or the input did not adhere to the standards set by the problem
return None
And even this is technically not as efficient as it could be. Let me know if you try this and whether it solves whatever issue you were experiencing with expected results.
In your code the final part should not be in the else block, nor even in the for loop:
if count > count1:
return d['odd']
return d['even']
Like this is may give a wrong result. For instance, if the first number in the input is odd, and is the only odd one, then this code will return d['even'] which is obviously wrong.
Place these lines after the loop (with correct indentation) and it should work.
However, this problem can be solved without dictionary or extra lists. Have a go at it.
def find_outlier(integers):
parity = integers[-2] % 2
if integers[-1] % 2 != parity:
if integers[0] % 2 != parity:
return integers[-2]
else:
return integers[-1]
for i in integers:
if i % 2 != parity:
return i
This is what my code needs to do:
Write a function, persistence, that takes in a positive parameter num and returns its multiplicative persistence, which is the number of times you must multiply the digits in num until you reach a single digit.
Test.it("Basic tests")
Test.assert_equals(persistence(39), 3)
Test.assert_equals(persistence(4), 0)
Test.assert_equals(persistence(25), 2)
Test.assert_equals(persistence(999), 4)
This is a Codewars challenge. I can test assert samples individually but not all at once. Codewars need to be able to run all its test samples all at once. I need to find a way to reset count after completing one test sample without resetting count during the recursive function.
count = 0
def persistence(n):
# your code
global count
#def recursion(result):
number_str = str(n)
ints = [int(i) for i in number_str if i != '0']
result = 1
for j in ints:
result = result * j
if result >= 10:
print(ints,"\n\n------------------------------------------")
count += 1
print(count)
print(result)
return persistence(result)
else:
if count > 0:
count += 1
return count
else:
return count
This is the code I came up with. I need my function to run all four tests at once. My function can recursively render one test at a time, but not all tests at once. I need to figure out how to reset count after each test sample assertion.
Your recursive function should not need a global variable. You can pass counts as a parameter instead, with a default value to handle the public API case where it's not passed in:
def persistence(n, count=0):
...
# everything is the same up until the recursion
return persistence(result, count)
You could simplify the code a bit by just doing inline addition rather than using += statements on count, if you want, but it won't change the behavior of the code.
I'd also note that since your function is tail recursive, you could pretty easily replace the recursion with a loop. I think something like this might do it:
def persistance(n):
count = 0
while n >= 10:
count += 1
ints = [int(i) for i in str(n) if i != '0']
n = 1
for i in ints:
n *= i
return count
You can just pass along the count down the recursive call, like this:
count = 0
def persistence(n, count):
# ..
# update count
# ..
return persistence(result, count)
# ...
return count
or if you cant change the signature of persistance, use an auxiliary function, which is very common in functional programming.
def persistance(n):
return persistance_aux(n, 0)
def persistance_aux(n, count):
# ....
I'm trying to implement something similar to Sieve of Eratosthenes. I want to remove all non prime numbers in a given range from the set, and sum up all the prime number to the given number.
number_set = set(list(range(1, given_number)))
sum_number = 0
for num in number_set:
if isPrime(num):
sum_number += num
prime_set = set(list(range(0, big_number, num)))
number_set -= prime_set
print(sum_number)
Obviously I got the error -
Set changed size during iteration
I'm new to python so the syntax is unfamiliar. As far as I understood from other threads, I can use dictionary and use the for loop on number_set.keys() (right?), but I wanted to ask, is it possible to correct this for loop?
You must stop itering over the modified iterator.
My approach is to restart the iteration after the modification, try to modify the set such as every already processed value is not re-processed, and maybe call it a day.
The exception you are having is just a limitation about sets not liking being iterated over and modified at the same time.
number_set = set(list(range(1, given_number)))
sum_number = 0
done = False
while not done:
for num in number_set:
if isPrime(num):
sum_number += num
prime_set = set(list(range(0, big_number, num)))
number_set -= prime_set
break
done = True
print(sum_number)
Disclaimer: Script might need adjustments on you part, I'm just illustrating the logic
Write a func/on first_neg that takes a (possibly empty) list of
numbers as input parameter, finds the first occurrence of a
nega/ve number, and returns the index (i.e. the posi/on in the
list) of that number. If the list contains no nega/ve numbers or it
is empty, the program should return None. Use while loop (and
not for loop) and your while loop should stop looping once the
first nega/ve number is found.
This is the question my teacher asked me any ideas this what i did:
def first_neg(list):
count = 0
for number in list:
if number < 0:
count += 1
return count
Dosent seem to work properly i just joined 1st post hope can get some help
x = [1,2,3,-5]
def first_neg(list):
count = 0
for number in list:
count += 1 #moved it outside of the if
if number < 0:
return count
print(first_neg(x)) #prints 4
You want to increment count not when you've found the answer but everytime the forloops loops. Note that this method returns 4 which is the fourth item in the list, not the index, Index of the list starts from 0 so to access it would be 3. Take our list x = [1,2,3,-5], -5 is in the fourth slot of the list, but to access it we have to call x[3] since lists starts at 0 indexing.
If you want to return the index of the list where the first negative number is found try this:
x = [1,2,3,-5]
def first_neg(list):
for count, number in enumerate(list):
if number < 0:
return count
print(first_neg(x)) # prints 3
This is because enumerate creates a "pairing" of the item in the list and it's the current count. Enumerate just counts from 0 everytime it gets an item out of the list.
Also as a side note ( I didn't change it in my answer since I wanted you to understand what's going on ). Don't name your variables keywords like list, tuple, int, str... Just a bad idea and habit, it works as you can see but it can cause issues.
Return the index immediately once you encounter the negative element. Increment the index otherwise:
def first_neg(lst):
count = 0
while count < len(lst):
if lst[count] < 0:
return count
count = count + 1
return None
Note : Better if you use enumerate() rather than using extra count variable. The code you mentioned is not written in pythonic way.
You may try this as well:
def first_neg(lst):
res = [i for i,x in enumerate(lst) if x<0]
return None if res == [] else res[0]
The code above can be improved using generators as suggested by #Chris_Rands.
Title pretty much says it all. This is the code I wrote that I've been tinkering around with.
def sum_evens(tup):
for num in tup:
if num % 2 ==0:
total = num+num
print(total)
I'm pretty lost here, any ideas on what I can do?
Thank you in advance!
you need to start total at 0 and add to it when you find matching numbers
def sum_evens(tup):
total = 0
for num in tup:
if num % 2 ==0:
total = total+num
return total
finally you need to return the total to whatever called it so it can be used
there are lots of better ways to do this ... but I just edited your function to work
print sum_evens([1,2,3,4,5,6,7]) # 2+4+6 = 12
You need to learn about list comprehensions. Basically, they are backwards for loops such that you can define a new list by iterating over an old list. You can also add a conditional clause to pick and choose.
In this scenario, we loop through an existing tuple and look for the individual members with a remainder of zero when divided by two. We then construct a list with these members and find a sum.
print sum([x for x in my_tuple if x % 2 == 0])