Skip to content

bugfix: Add empty list detection for find_max/min #4881

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions maths/find_max.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
# NguyenU
from __future__ import annotations


def find_max(nums):
def find_max(nums: list[int | float]) -> int | float:
"""
>>> for nums in ([3, 2, 1], [-3, -2, -1], [3, -3, 0], [3.0, 3.1, 2.9]):
... find_max(nums) == max(nums)
True
True
True
True
>>> find_max([2, 4, 9, 7, 19, 94, 5])
94
>>> find_max([])
Traceback (most recent call last):
...
ValueError: find_max() arg is an empty sequence
"""
if len(nums) == 0:
raise ValueError("find_max() arg is an empty sequence")
max_num = nums[0]
for x in nums:
if x > max_num:
max_num = x
return max_num


def main():
print(find_max([2, 4, 9, 7, 19, 94, 5])) # 94


if __name__ == "__main__":
main()
import doctest

doctest.testmod(verbose=True)
39 changes: 36 additions & 3 deletions maths/find_max_recursion.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,48 @@
from __future__ import annotations


# Divide and Conquer algorithm
def find_max(nums, left, right):
def find_max(nums: list[int | float], left: int, right: int) -> int | float:
"""
find max value in list
:param nums: contains elements
:param left: index of first element
:param right: index of last element
:return: max in nums

>>> for nums in ([3, 2, 1], [-3, -2, -1], [3, -3, 0], [3.0, 3.1, 2.9]):
... find_max(nums, 0, len(nums) - 1) == max(nums)
True
True
True
True
>>> nums = [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
>>> find_max(nums, 0, len(nums) - 1) == max(nums)
True
>>> find_max([], 0, 0)
Traceback (most recent call last):
...
ValueError: find_max() arg is an empty sequence
>>> find_max(nums, 0, len(nums)) == max(nums)
Traceback (most recent call last):
...
IndexError: list index out of range
>>> find_max(nums, -len(nums), -1) == max(nums)
True
>>> find_max(nums, -len(nums) - 1, -1) == max(nums)
Traceback (most recent call last):
...
IndexError: list index out of range
"""
if len(nums) == 0:
raise ValueError("find_max() arg is an empty sequence")
if (
left >= len(nums)
or left < -len(nums)
or right >= len(nums)
or right < -len(nums)
):
raise IndexError("list index out of range")
if left == right:
return nums[left]
mid = (left + right) >> 1 # the middle
Expand All @@ -21,5 +53,6 @@ def find_max(nums, left, right):


if __name__ == "__main__":
nums = [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
assert find_max(nums, 0, len(nums) - 1) == 10
import doctest

doctest.testmod(verbose=True)
21 changes: 15 additions & 6 deletions maths/find_min.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
def find_min(nums):
from __future__ import annotations


def find_min(nums: list[int | float]) -> int | float:
"""
Find Minimum Number in a List
:param nums: contains elements
Expand All @@ -10,17 +13,23 @@ def find_min(nums):
True
True
True
>>> find_min([0, 1, 2, 3, 4, 5, -3, 24, -56])
-56
>>> find_min([])
Traceback (most recent call last):
...
ValueError: find_min() arg is an empty sequence
"""
if len(nums) == 0:
raise ValueError("find_min() arg is an empty sequence")
min_num = nums[0]
for num in nums:
if min_num > num:
min_num = num
return min_num


def main():
assert find_min([0, 1, 2, 3, 4, 5, -3, 24, -56]) == -56


if __name__ == "__main__":
main()
import doctest

doctest.testmod(verbose=True)
39 changes: 36 additions & 3 deletions maths/find_min_recursion.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,48 @@
from __future__ import annotations


# Divide and Conquer algorithm
def find_min(nums, left, right):
def find_min(nums: list[int | float], left: int, right: int) -> int | float:
"""
find min value in list
:param nums: contains elements
:param left: index of first element
:param right: index of last element
:return: min in nums

>>> for nums in ([3, 2, 1], [-3, -2, -1], [3, -3, 0], [3.0, 3.1, 2.9]):
... find_min(nums, 0, len(nums) - 1) == min(nums)
True
True
True
True
>>> nums = [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
>>> find_min(nums, 0, len(nums) - 1) == min(nums)
True
>>> find_min([], 0, 0)
Traceback (most recent call last):
...
ValueError: find_min() arg is an empty sequence
>>> find_min(nums, 0, len(nums)) == min(nums)
Traceback (most recent call last):
...
IndexError: list index out of range
>>> find_min(nums, -len(nums), -1) == min(nums)
True
>>> find_min(nums, -len(nums) - 1, -1) == min(nums)
Traceback (most recent call last):
...
IndexError: list index out of range
"""
if len(nums) == 0:
raise ValueError("find_min() arg is an empty sequence")
if (
left >= len(nums)
or left < -len(nums)
or right >= len(nums)
or right < -len(nums)
):
raise IndexError("list index out of range")
if left == right:
return nums[left]
mid = (left + right) >> 1 # the middle
Expand All @@ -21,5 +53,6 @@ def find_min(nums, left, right):


if __name__ == "__main__":
nums = [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
assert find_min(nums, 0, len(nums) - 1) == 1
import doctest

doctest.testmod(verbose=True)