Python Method Returning None - python

I'm having a very odd problem. I wrote a method that determines the degree of a formula describing a set of numbers, when given the said set. The method is fairly simple, I've added in a couple of lines for debugging purposes:
def getdeg(numlist, cnt): #get the degree of the equation describing numlist
count = cnt #initial run should be with cnt as 0
templist = []
for i in range(len(numlist) - 1): #exclude the last item (which doesn't have an item after it)
templist.append(numlist[i+1] - numlist[i]) #append the val of index i+1 minus index i
count += 1
print(templist)
if not allEqual(templist):
print("Not all equal, iterating again")
getdeg(templist, count)
else:
print(count)
return count
def allEqual(numlist):
if len(numlist) == 1:
return True
for i in range(len(numlist) -1):
if not (numlist[i] == numlist[i+1]):
return False
return True
Now, I'm running this on a set of numbers I KNOW to be described by a 3rd-degree equation, like so:
x = getdeg([2, 8, 9, 11, 20], 0)
print(x)
Fairly simple, yes? Except when you run this, it prints out the following:
[6, 1, 2, 9]
Not all equal, iterating again
[-5, 1, 7]
Not all equal, iterating again
[6, 6]
3
None
Everything is looking good, right up until that "None." What is it doing there? I would assume that the else conditional isn't being executed, but it's printing out 3 just fine, so it obviously is. That also means that the program "knows" what the value of count is, but it's not returning it right. Could someone enlighten me as to what on earth is going on?

if not allEqual(templist):
print("Not all equal, iterating again")
getdeg(templist, count)
Remember, when a method recursively calls itself, you still need to explicitly return the value if you want a value to be returned.
if not allEqual(templist):
print("Not all equal, iterating again")
return getdeg(templist, count)

You need to return a value in the if clause as well.
return getdeg(templist, count)

Related

checking duplicates in list using while loop

I'm trying to check for duplicate numbers within a list using only while loops and if statements. For some reason it is returning True for the list [1, 2, 3, 4, 5, 6] and I can't figure out why.
def has_duplicates(xs):
count = 0
while count < len(xs) and len(xs) > 1:
check = 1
while check < len(xs):
if xs[check] == xs[count]:
return True
else:
check += 1
count += 1
return False
I get the correct output using your function. However, there are certainly easier ways to get the same result, as:
def has_duplic2(xs):
return len(set(xs)) != len(xs)
In your first algorithm you shouldn't assing to the check variable the value of 1.
Otherwise on the second cycle of the loop both count and check will be 1 and you'll be comparing the element [1] of your list with itself, which will always return true.
Instead you should set the check variable to check = count + 1. So that you never compare a value with itself.

Getting a function to multiply or sum based on the first element of a list

I am having some trouble writing a function that will sum all the elements of a list or multiply all the elements of a list together based on whether the first element of the list is odd or even.
I would like to get something like this.
def simpleSum(mylist):
#Write your code
number = 1
for n in mylist:
if n % 2 != 0:
return sum(mylist)
else:
number *= n
return number
print(simpleSum([1, 2, 4, 5]))
print(simpleSum([2, 4, 5, 6]))
I added the number = 1 and number *= n based on what I've seen on the internet, but I don't really understand why I have to use number = 1 and also what number *= n is doing.
I would like my output to be
12
240
but so far I keep getting
12
2
Very new to python, and I'm not really sure what I'm doing wrong. I originally tried using
for n in mylist:
if n[0] % 2 != 0:
but I kept getting an error telling me that n[0] is not scriptable.
Any brief explanation would help me tremendously. Thank you in advance.
there
The answer to your question is extremely simple. All you need to correct is your logic or your syntax.
Let us break your program down and try to understand where the error is.
def simpleSum(mylist):
#Write your code
number = 1
for n in mylist:
if n % 2 != 0:
return sum(mylist)
else:
number *= n
return number
print(simpleSum([1, 2, 4, 5]))
print(simpleSum([2, 4, 5, 6]))
The code for n in mylist returns one element of the list at a time, and not the position, so when you say n[0], it returns an error as it is not a list and doesn't have any indexes.
Next up, looking at your logical or syntax error:
If you notice carefully, n becomes the next index of the list everytime. This means that everytime it checks whether the number is odd or even. If it is odd, it returns with the sum, but if it is even, it returns with number multiplied by n. Since it returns at first entry itself, i.e, at the first index itself, this means that if the number is even, the result will be that number(because 1*n=n) and if it is odd, it will return the sum of the whole list.
To change this, the following logic is used.
Create function:
If the first index of the list i.e., mylist[0] is odd:
return the sum
Otherwise/else:
return the product
The code to reproduce this would be:
def simpleSum(mylist):
#Write your code
if mylist[0] % 2 != 0:
return sum(mylist)
else:
number = 1
for n in mylist:
number *= n
return number
print(simpleSum([1, 2, 4, 5]))
print(simpleSum([2, 4, 5, 6]))
Judging by your desired output and inputs, you want the list of numbers multiplied if the first element is even and the sum of the list of numbers if the first element is odd.
number = 1 acts as a base value for multiplication.
number *= n equals to number = number * n
Consider the following code. First, it checks whether the first value of the list is odd or even. Then it calculates and returns values accordingly.
def simpleSum(mylist):
if (mylist[0] % 2) == 0:
number = 1
for n in mylist:
number *= n
return number
else:
return sum(mylist)
print(simpleSum([1, 2, 4, 5]))
print(simpleSum([2, 4, 5, 6]))
I don't think your code is doing what you want. If I'm reading your description correctly, it sounds like you want to know whether the first element of your list is even or odd before you add or multiply all the elements together.
In that case, you want something like this:
if my_list[0] % 2 == 0:
print(sum(my_list)
else:
num = 1
for n in my_list:
num *= n
print(num)
The reason you need to set num = 1 is because num *= n multiplies num by n, and if num doesn't have an initial value, you can't multiply it by n!
you can use functools.reduce for the multiplication part
from functools import reduce
from operator import mul
def my_func(some_list):
return sum(some_list) if some_list[0] % 2 else reduce(mul, some_list)
print(my_func([1, 2, 4, 5]))
print(my_func([2, 4, 5, 6]))
output
12
240

Using recursion to determine a semiperfect number

I am in need of your help again. I'm writing a code that determines whether a number is a semiperfect number or not by returning a boolean value. So first I thought I would make a list of the factors of the number excluding the number itself
def isSemiPerfect(n):
factor = []
for i in range(n-1, 0, -1):
if n%i == 0:
factor.append(i)
If I were to check for the number 12, it would return
factor = [1, 2, 3, 4, 6]
Then I need to make a code to use recursion to check if you add certain numbers it would be equal to 12
True = 6 + 4 + 2 or 6 + 3 + 2 + 1
Can someone tell me how I can use recursion to do trial and error? Like I'll always start with the biggest number and try a path with the next biggest number until I've tried all combinations.
I know there isn't a lot to go on with I just hope that you can tell me how I can use recursion effectively. Thank you!
You can think about it this way.
The question "Can [1,2,3,4,6] sum to 12"?
Is the same as "Can [2,3,4,6] sum to 11" or "Can [2,3,4,6] sum to 12"?
One uses the first element (and has lower sum) and the other does not use the first element and has the same sum.
so a start function would be:
def f(lst,sum_left):
return f(lst[1:], sum_left-lst[0]) or f(lst[1:],sum_left)
However, this function does not know when to stop. So we need some base cases.
Obviously, if sum is 0, the answer is trivially yes:
if sum_left == 0:
return true
Another base case is, if the sum is < 0, we have taken a too big element and we can never recover.
if sum_left < 0:
return true
Also, we can risk running out of elements like [1,2] can never sum to 50, so we add a base case if there are no elements in the list:
if not lst:
return false
Putting it all together:
def f(lst, left):
if left == 0:
return True
if left < 0:
return False
if not lst:
return False
return f(lst[1:],left-lst[0]) or f(lst[1:],left)

Function That Sums All Elements in List Up to But Not Including The First Even Number

I'm trying to write a python function that will sum up all of the elements in a list up to but not including the first even number. The function needs to pass the following tests:
from test import testEqual
testEqual(sum_of_initial_odds([1,3,1,4,3,8]), 5)
testEqual(sum_of_initial_odds([6,1,3,5,7]), 0)
testEqual(sum_of_initial_odds([1, -7, 10, 23]), -6)
testEqual(sum_of_initial_odds(range(1,555,2)), 76729)
I tried the following:
import random
lst = []
def sum_of_initial_odds(nums):
sum = 0
#test if element is odd number - if it's odd, add it to the previous integer
for i in lst:
if i % 2 != 0:
sum = sum + i
return sum
#test if element is even number - if it's even, don't include it and break code
else:
if i % 2 == 0:
break:
I'm currently getting a parse error:
ParseError: bad input on line 11
which is the line:
else:
How else can I write this code so that it adds the elements in a list, but doesn't include the first even number, without getting Parse errors?
You can do this very easily using itertools.takewhile:
>>> import itertools
>>> sum(itertools.takewhile(lambda x: x % 2 == 1, [1,3,1,4,3,8]))
5
takewhile will yield elements from the given sequence while the predicate x % 2 == 1 is True, i.e. it will get you all numbers up to the first even one. And sum, well, sums those values.
You have a few problems:
Indentations, which others have already mentioned
You return sum the first time you hit an odd number; this is so not what you want.
You ignore the input parameter nums and work with the empty global lst.
Your lowest if is redundant: you already know you have an even number when you get here.
In general, stuff partial results into local variables; have a single return at the bottom of your routine.
import random
def sum_of_initial_odds(lst):
sum = 0
#test if element is odd number - if it's odd, add it to the previous integer
for i in lst:
if i % 2 != 0:
sum = sum + i
#test if element is even number - if it's even, don't include it and break code
else:
break
return sum
print sum_of_initial_odds([1,3,1,4,3,8]) == 5
print sum_of_initial_odds([6,1,3,5,7]) == 0
print sum_of_initial_odds([1, -7, 10, 23]) == -6
print sum_of_initial_odds(range(1,555,2)) == 76729
THe output from this is four True values.
You could also use
def sum(numbers):
sum = 0
for number in numbers:
if number % 2 == 0:
break
else:
sum += number
return sum
And test using the asset statement which is a specialized form of raise statement
The advantage is that it throws AssertionError only when __debug__ is true thus avoiding throwing exception in production.
assert sum([1,3,1,4,3,8]) == 5 , "Your message if assertion fails"
You can turn off __debug__ by
Start interactive mode with python -O
Setting variable PYTHONOPTIMIZE to True

Python: Recursive function to find the largest number in the list

I'm trying to do a lab work from the textbook Zelle Python Programming
The question asked me to "write and test a recursive function max() to find the largest number in a list. The max is the larger of the first item and the max of all the other items." I don't quite understand the question from the textbook.
def Max(list):
if len(list) <= 1:
else:
return list[0]
else:
m = Max(list[1:])
return m if m > list[0] else list[0]
def main():
list = eval(raw_input(" please enter a list of numbers: "))
print("the largest number is: ", Max(list))
main()
Or maybe I'm suppose to open a txt file with numbers in it and then use recursive?
I believe recursive works like this
def function()
> if something:
>>return 0
>else:
>>return function()
Your understanding of how recursion works seems fine.
Your if-block is messed up, you have two elses to one if and the alignment is out. You need to remove your first else and un-indent everything below the if one level. eg:
def Max(list):
if len(list) == 1:
return list[0]
else:
m = Max(list[1:])
return m if m > list[0] else list[0]
def main():
list = eval(raw_input(" please enter a list of numbers: "))
print("the largest number is: ", Max(list))
main()
I post a different solution approach of the problem. Most of the answers manipulate the list using the slice operator in each recursive call. By the time the exercise does not provide a strict function prototype to be used, I also pass as function parameter the length of the list.
Suppose that we try to find and return the maximum element from a sequence S, of n elements.
Function prototype: Max(S, n)
Base case: If S contains only one item, return it. (Obviously the only item in the sequence is the max one.)
Recur: If not the base case, call Max each time for one less item, that is call Max(S, n-1). We then store the returning value to a variable called previous that indicate the previous element from the sequence and check that value with the next element in the sequence, which is the right most element in the current recursive call, and return the max of these values.
A recursion trace of the above procedure is given in the following figure. Suppose we try to find the max from a list that contains [5, 10, 20, 11, 3].
Note: To help you further, keep in mind that we recursively iterate the list from the right most element to the left most one.
Finally here is the working code:
def find_max_recursively(S, n):
"""Find the maximum element in a sequence S, of n elements."""
if n == 1: # reached the left most item
return S[n-1]
else:
previous = find_max_recursively(S, n-1)
current = S[n-1]
if previous > current:
return previous
else:
return current
if __name__ == '__main__':
print(find_max_recursively([5, 10, 20, 11, 3], 5))
Note: The recursive implementation will work by default only with sequences of 1000 most elements.
To combat against infinite recursions, the designers of Python made an
intentional decision to limit the overall number of function
activations that can be simultaneously active. The precise value of
this limit depends upon the Python distribution, but a typical default
value is 1000. If this limit is reached, the Python interpreter
raises a RuntimeError with a message, maximum recursion depth exceeded.
Michael T. Goodrich (2013), Data Structures and Algorithms in Python, Wiley
To change the default value do:
import sys
sys.setrecursionlimit(1000000)
here is one more approach to solve above problem
def maximum(L):
if len(L) == 1:
return L[0]
else:
return max(L[0],maximum(L[1:]))
so example input and output:
L= [2,4,6,23,1,46]
print maximum(L)
produces
46
The basic approach is this.
If the list contains only a single element, that element is the max. Return it immediately.
Otherwise, the list contains multiple elements. Either the first element in the list is the maximum, or it is not.
The maximum of the first element is simply the first element in the list.
Recursively call Max on the rest (all but first element) to find the maximum of those elements.
Compare the results from step 3 and 4. The result is the number that is greater. Return it.
Right now you have some syntax errors. For example, you have two else clauses for a single if, and the indentation looks funny. You can only have one else for an if block. But if you follow these instructions, you should have a working algorithm.
def Max(lis,maxx=-float("inf")):
if len(lis) == 1: #only one element in lis
return maxx if maxx>lis[0] else lis[0] #return lis[0] if it's greater than maxx
else:
m=lis[0] if lis[0]>maxx else maxx # m = max(lis[0],maxx)
return Max(lis[1:],m) #call Max with lis[1:] and pass 'm' too
print Max([1,2,39,4,5,6,7,8]) #prints 39
print Max([1,2,3,4,5,6,7,8]) #prints 8
These solutions fail after certain list size.
This is a better version:
def maximum2(a, n):
if n == 1:
return a[0]
x = maximum2(a[n//2:], n - n//2)
return x if x > a[0] else a[0]
def maximum(a):
return maximum2(a, len(a))
maximum(range(99999))
>>> 99998
One simple way would be to sort the list first then use indexing.
Here's a function that would work:
a = [1,233,12,34]
def find_max(a):
return sorted(a)[-1]
def find_max(my_list, max):
if len(my_list) <= 1:
return max
else:
if my_list[0] > max:
return find_max(my_list[1:], my_list[0])
else:
return find_max(my_list[1:], max)
if __name__ == '__main__':
my_list = [1, 5, 16, 9, 20, 40, 5]
print(find_max(my_list, my_list[0]))
def find_max(arr):
"""find maximum number in array by recursion"""
if arr == []: # if its an empty array
return 0
if len(arr) == 1: # if array has only one element
return arr[0]
else: # get max of first item compared to other items recursively
return max(arr[0], find_max(arr[1:])) # 1: means all other excluding 0th element
def main():
print(find_max([2,3,5,6,7,1])) # will print max - 7
if __name__ == "__main__":
main()
You can also do it in this way:
def maximum(data, start, stop):
if start >= stop:
return data[start]
else:
if data[start] >= data[stop - 1]:
return maximum(data, start, stop - 1)
else:
return maximum(data, start + 1, stop)
def recursiveMax(a):
if len(a) == 1:
return a[0]
else:
return a[0] if a[0] > recursiveMax(a[1:]) else recursiveMax(a[1:])
Test:
print(recursiveMax([1, 2, 15, 6, 3, 2, 9]))
print(recursiveMax([98, 2, 1, 1, 1, 1, ]))
TLDR; This code will also work when the list passed to the function is empty!
#jam's answer is amazing. However, I found some problems with the conditions, I think #Blender was hinting at it.
That code will fail in the case when the list passed to the function is empty. There are two base cases:
When the list is empty -> return None
When the list has one item -> return list[0]
And then the recursive case ... to reduce any other case into the base case.
def recursive_max(arr):
if len(arr) == 0:
return None
elif len(arr) == 1:
return arr[0]
else:
maxItem = recursive_max(arr[1:])
return maxItem if maxItem > arr[0] else arr[0]
Here is my answer, with a one line of code :))
def max_value(n_list):
return n_list[0] if len(n_list) == 1 else max(n_list[0], max_value(n_list[1:]))
def getMaxNumber(numbers):
return 'N.A' if len(numbers) == 0 else max(numbers)

Categories