Improving Python user defined max function - python

I am new to programming and am trying to understand how to "think" more programmatically in Python. I wrote a function that returns the largest element in an array without using max:
def max_userdefined(array):
"""
Finds largest value of nonempty array of numbers in O(n)
:param: list/tuple of values
:return: max value
"""
try:
assert isinstance(array, list or tuple)
result = array[0]
for element in array:
if element > result:
result = element
return result
except IndexError:
return 'Please pass in a nonempty array'
except AssertionError:
return 'Please pass in a list or tuple'
except TypeError:
return 'Please make sure elements of array are all floats or ints'
How can I improve the above code? Open to any criticism or if anyone can recommend a good Pythonic style guide.

def max_userdefined(array):
myMax = l[0]
for num in l:
if myMax < num:
myMax = num
return myMax
print max_userdefined ([1,2,3,4,5])
Output
5
Or You can do something like following by using sorted.
def max_userdefined(array):
return sorted(array)[-1]

>>> def umax(array):
global biggest
for num in array:
if num > biggest:
biggest = num
>>> biggest = int()
>>> nums = (1, 9, 6, 4, 5, 3, 2, 7, 0)
>>> umax(nums)
>>> biggest
9

For returning the greatest number from a list the simple algorithm followed is compare two numbers and keep the larger number in a variable, then print the variable OR you can use python shortcut using sort.
Using user defined function:
def greatest_ele_list(listobj):
greatest=listobj[0]
for i in range(len(listobj)):
if listobj[i]>greatest:
greatest=listobj[i]
else:
pass
return greatest
print greatest_ele_list([4,5,3,8,1])
Using sort:
def greatest_ele_list(listobj):
listobj2=listobj.sort()
return listobj2[-1]
print greatest_ele_list([4,5,3,8,1])
Output: >>> 8

Related

Linear search in Python - always going to else statement

I'm a beginner that is currently working on a program with Python for fun and I am attempting to complete a linear search for a given list. Instead of the program returning the index of the value that is being searched for in the list, it is returning the else condition.
I created another function which is called getVal and this is so that the output of getVal will be passed into the linear search function as one of the parameters/arguments.
How would I be able to correct this so that the index number of the value being searched for in the linear search function will be the output? Any help will be greatly appreciated.
def getVal():
userNum = int(input("Enter a number: "))
return userNum
if userNum != int:
get Val
def linearSearch(searchList, getVal):
for i in range(len(searchList)):
if i == getVal:
return searchList.index(i)
else:
return "Value not found"
getVal()
linearSearch(searchList, getVal)
searchList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Welcome to Python - this is the wrong way for searching in a list.
You are comparing the value you want to find to indexes (result of range) instead of to actual values in the list.
Your else clause instructs the function to return immediately after the first check (in the first iteration of the loop) fails.
To make a for loop in Python iterate over both list values and their indexes you need to use the enumerate function, like this:
def linearSearch(searchList, searchVal):
for index, value in enumerate(searchList):
if value == searchVal:
return index
# this line must only be reached if the loop ends without finding a match!
return "Value not found"
Note also that while Python does allow a function to return different types of values, it is bad practice to have a function return a string in one case and a number in another.
Especially since your function can be used to search for lists containing strings, or any other type of data.
Instead, if match is not found, your function should return None.
You can than check for that specific value and print the appropriate error message:
val = getVal()
res = linearSearch(searchList, val)
for is not None:
print("{} found at index {}".format(val, res))
else:
print("Value not found")
Finally, your getVal function will not check if the value is an integer as you expected, and instead will crush the program if something that isn't an integer is entered by the user.
Usually, testing input for integer is done with a try .. except block, but since you are new to Python, you may not have reached the topic of exceptions yet here are several suggestions on other ways of checking if you got an integer:
How can I check if a string represents an int, without using try/except?
A couple of issues with your code:
if userNum != int: get Val - this will never execute because it's after a return statement, and it contains a syntax error (get Val), and you're comparing userNum which is an integer, with int which is a type
in the for loop "Value not found" would always be returned except if the user wanted to find the 1st element
the way you're calling getVal() - you're not assigning the result to any variable
you're passing getVal as argument to linearSearch but getVal is a function, not the value input by user
Fixed code:
In [1]: def getVal():
...: userNum = int(input("Enter a number: "))
...: return userNum
...:
...: def linearSearch(searchList, val):
...: for i, item in enumerate(searchList):
...: if item == val:
...: return i
...: else:
...: return "Value not found"
...:
...: val = getVal()
...: searchList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
...: linearSearch(searchList, val)
...:
...:
Enter a number: 3
Out[1]: 2

For Loop function only returning the same value

I am trying to create a function that accepts a list (of integers) and an integer value and returns the number of elements in the list that are less than the given value. However, the code I have so far only ever returns 1 or 0 and I am not sure why. Can anyone help?
def lesser_than(alist, value):
"""
Returns: number of elements in alist strictly less than value
Example: lesser_than([5, 9, 1, 7, 89], 6) evaluates to 2
Parameter alist: the list to check (WHICH SHOULD NOT BE MODIFIED)
Precondition: alist is a list of ints
Parameter value: the value to compare to the list
Precondition: value is an int
"""
ret = 0
for a in alist:
a = int(a)
value = int(value)
if a < value:
ret += 1
return ret
You have your return in the for loop; it'll return as soon as the first entry is done. Remove a level of indentation on return ret.
This is because your return statement is in the for loop causing it to return at the first value less than the input. Move it outside the loop.
def lesser_than(alist,value):
"""
Returns: number of elements in alist strictly less than value
Example: lesser_than([5, 9, 1, 7, 89], 6) evaluates to 2
Parameter alist: the list to check (WHICH SHOULD NOT BE MODIFIED)
Precondition: alist is a list of ints
Parameter value: the value to compare to the list
Precondition: value is an int
"""
ret = 0
value = int(value) #moved this outside the loop as it's only needed once
for a in alist:
a = int(a)
if a < value:
ret += 1
return ret

Python Function with Lists and Sets

So I'm trying to figure out this problem and I can't figure out why it isn't working.
The premise is that you're given an input list and you have to find the second-lowest value. The list can have any number of integers and can repeat values; you can't change the list.
My code:
def second_min(x):
input_list = list(x)
print input_list
list_copy = list(input_list)
list_set = set(list_copy)
if len(list_set) > 1:
list_copy2 = list(list_set)
list_copy2 = list_copy2.sort()
return list_copy2[1]
else:
return None
print second_min([4,3,1,5,1])
print second_min([1,1,1])
The outputs for those two inputs are:
3
None
It's giving me errors on lines 9 and 13.
TypeError: 'NoneType' object has no attribute '__getitem__'
Thanks!
list_copy2 = list_copy2.sort()
.sort() sorts the list in place and returns None. So you're sorting the list, then throwing it away. You want just:
list_copy2.sort()
Or:
list_copy2 = sorted(list_set)
sorted always returns a list, so you can use it to sort the set and convert it to a list in one step!
You need to use sorted instead of sort. sorted returns a new list, that is a sorted version of the original. sort will sort the list in-place, and returns None upon doing so.
def second_min(x):
if len(x) > 1:
return sorted(x)[1]
else:
return None
>>> second_min([4,3,1,5,1])
1
Help, I can't use sorted! It's not allowed!
def second_min(li):
if len(li) < 2:
return None
it = iter(li)
a, b = next(it), next(it)
next_lowest, lowest = max(a, b), min(a, b)
for x in it:
if x < next_lowest:
if x < lowest:
lowest, next_lowest = x, lowest
else:
next_lowest = x
return next_lowest

In-built sum function in python

def sum_elements(l):
sum = 0
string = ""
k = 0
for i in l:
if type(i) is int:
sum = sum + l[k]
k += 1
elif type(i)is str:
string = string + str(l[k])
k += 1
print "sum of integers in list" + str(sum)
print "sum of strings in list" + string
Python has a built-in function sum to find sum of all elements of a list. In case the list is integer numbers sum_elements([1, 2, 3]), it will return 6. sum function works for a list of strings as well. sum_elements(["hello", "world"]) returns helloworld. I have written an implementation for the sum built-in function in the above code. It works.
I am a newbie in Python, I just want to know if it's correct or is there any better approach?
Are there are any links available for the python built-in functions source code?
from operator import add
def sum_elements(l):
return reduce(add, l)
You don't need to access an element by its index. If the list is not empty and all elements are of the same type, you can code as follows:
>>> def sum_elements(l):
... s = l[0]
... for element in l[1:]:
... s += element
... return s
...
>>> sum_elements([1, 2, 3])
6
>>> sum_elements(['hello', 'world'])
'helloworld'

data structure list class in python

I am working on a data structure list class in python. I would like to get the largest item in the list.
inlist = self.data
if inlist[0] > inlist[1]:
largest = inlist[0]
else:
largest = inlist[1]
for item in inlist[2]:
if item > largest:
largest = item
return largest
With the above getting stuck at largest gets returns
<bound method ListData.largest2 of <list.ListData instance at 0x2b35602c3440>>
while the data
[2, 5]
Trust the loop to get all the indicies rather than specifying them yourself.
if len(self.data) == 0:
return None
result = self.data[0]
for item in self.data:
if item > result:
result = item
return result
that for loop is going through all your data. Trying to coerce an index got you into trouble.
You can use the build in max() function.
mylist = [2, 5]
mymax = max(mylist)

Categories