forked from MIT-Emerging-Talent/ET6-practice-code-review
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #39 from MIT-Emerging-Talent/largest-perfect-squar…
…e-less-than-number Largest perfect square less than number
- Loading branch information
Showing
3 changed files
with
170 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
|
||
""" | ||
A module for finding the largest perfect square less than a given number. | ||
Module contents: | ||
- largest_perfect_square_less_than_number: | ||
returns the largest perfect square that is less than the given number. | ||
Created on 2025-01-06 | ||
@author: Huda Alamassi | ||
""" | ||
|
||
from typing import Union | ||
|
||
|
||
def largest_perfect_square_less_than_number(number: Union[int, float]) -> int: | ||
""" | ||
The function takes in a number (either int or float) and returns the largest perfect square | ||
that is less than the given number. | ||
Arguments: | ||
number (int, float): The input number to check for the largest perfect square less than it. | ||
Assumptions: | ||
- The input number must be a non-negative number (either integer or float). | ||
Returns: | ||
int: | ||
- The largest perfect square that is less than the input number. | ||
- If no perfect square exists (i.e., for inputs less than or equal to 1 or equal to 0), | ||
the function will return 0. | ||
Raises: | ||
AssertionError: If the input is a negative number (integer or float). | ||
AssertionError: If the input is not a number (neither integer nor float). | ||
Examples: | ||
>>> largest_perfect_square_less_than_number(50) | ||
49 | ||
>>> largest_perfect_square_less_than_number(16.5) | ||
9 | ||
>>> largest_perfect_square_less_than_number(1) | ||
0 | ||
>>> largest_perfect_square_less_than_number(100.99) | ||
81 | ||
""" | ||
# Validate input type to avoid errors in mathematical operations | ||
assert isinstance(number, (int, float)), ( | ||
"Input must be a number (either integer or float)." | ||
) | ||
|
||
# Negative numbers do not have valid perfect squares | ||
assert number >= 0, "Input must be a non-negative number." | ||
|
||
# Handle edge cases where no perfect square exists below 1 | ||
if number <= 1: | ||
return 0 | ||
|
||
# Ensure we work with the integer part of the square root | ||
square_root = int(number**0.5) | ||
|
||
# Find the largest perfect square less than the number | ||
perfect_square = square_root**2 | ||
|
||
# Adjust when the number is exactly or close to a perfect square | ||
if perfect_square == int(number): | ||
square_root -= 1 | ||
perfect_square = square_root**2 | ||
|
||
return perfect_square |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +0,0 @@ | ||
# Tests | ||
92 changes: 92 additions & 0 deletions
92
solutions/tests/test_largest_perfect_square_less_than_number.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
|
||
""" | ||
Test module for largest_perfect_square_less_than function. | ||
Contains tests for checking the functionality of finding | ||
the largest perfect square less than a given number. | ||
Test categories: | ||
- Functionality tests: checking if the function correctly identifies | ||
the largest perfect square less than a number. | ||
- Edge tests: | ||
- Small positive numbers (the input is less than or equal to 1) | ||
- Perfect squares and slightly below or above it | ||
- Very large numbers | ||
- Zero | ||
- Defensive tests: ensuring the function handles invalid inputs such as: | ||
- Negative numbers | ||
- Non-numeric inputs | ||
Created on 2025-01-06 | ||
@author: Huda Alamassi | ||
""" | ||
|
||
import unittest | ||
|
||
from solutions.largest_perfect_square_less_than_number import ( | ||
largest_perfect_square_less_than_number, | ||
) | ||
|
||
|
||
class TestLargestPerfectSquareLessThanNumber(unittest.TestCase): | ||
"""Test the largest_perfect_square_less_than_number function.""" | ||
|
||
# Test functionality | ||
def test_integer_input(self): | ||
"""It should return the largest perfect square less than the given integer.""" | ||
actual = largest_perfect_square_less_than_number(50) | ||
self.assertEqual(actual, 49) | ||
|
||
def test_float_input(self): | ||
"""It should return the largest perfect square less than the given float.""" | ||
actual = largest_perfect_square_less_than_number(2.6) | ||
self.assertEqual(actual, 1) | ||
|
||
# Test edge cases | ||
def test_small_positive_number(self): | ||
"""It should return 0 when the input is less than or equal to 1.""" | ||
actual = largest_perfect_square_less_than_number(0.5) | ||
self.assertEqual(actual, 0) | ||
|
||
def test_perfect_square(self): | ||
"""It should return the largest perfect square less than the given perfect square.""" | ||
actual = largest_perfect_square_less_than_number(16) | ||
self.assertEqual(actual, 9) | ||
|
||
def test_slightly_above_perfect_square(self): | ||
"""It should return the largest square less than input slightly above a perfect square.""" | ||
actual = largest_perfect_square_less_than_number(16.5) | ||
self.assertEqual(actual, 9) | ||
|
||
def test_slightly_below_perfect_square(self): | ||
"""It should return the largest square less than input slightly below a perfect square.""" | ||
actual = largest_perfect_square_less_than_number(15.9) | ||
self.assertEqual(actual, 9) | ||
|
||
def test_very_large_number(self): | ||
"""It should return the largest perfect square less than a very large input.""" | ||
actual = largest_perfect_square_less_than_number(10**6) | ||
self.assertEqual(actual, 998001) | ||
|
||
def test_zero(self): | ||
"""It should return 0 when the input is 0.""" | ||
actual = largest_perfect_square_less_than_number(0) | ||
self.assertEqual(actual, 0) | ||
|
||
# Test defensive assertions | ||
def test_defensive_assertion_for_negative_input(self): | ||
"""It should raise an AssertionError when the input is negative.""" | ||
with self.assertRaises(AssertionError): | ||
largest_perfect_square_less_than_number(-10) | ||
|
||
def test_defensive_assertion_for_non_numeric_input(self): | ||
"""It should raise an AssertionError when the input is not a number.""" | ||
with self.assertRaises(AssertionError): | ||
largest_perfect_square_less_than_number("abc") |