From 7595057ff8743c1857540cde4d46f49f765344fd Mon Sep 17 00:00:00 2001 From: "F. Ismail SAHIN" <114308096+fevziismailsahin@users.noreply.github.com> Date: Sat, 11 Jan 2025 13:02:39 -0700 Subject: [PATCH 1/7] Update shipment_time_estimation.py --- solutions/shipment_time_estimation.py | 55 +++++++++++---------------- 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/solutions/shipment_time_estimation.py b/solutions/shipment_time_estimation.py index cfe0319ab..c23ca8b40 100644 --- a/solutions/shipment_time_estimation.py +++ b/solutions/shipment_time_estimation.py @@ -15,49 +15,40 @@ def shipment_time_estimation(distance: float, average_speed: float) -> float: """ Estimate the delivery time based on distance and average speed. - Parameters: - distance (float): The distance to the delivery location in kilometers. - average_speed (float): The average speed of the delivery trucks in kilometers per hour. + Parameters: + distance (float): The distance to the delivery location in kilometers. + average_speed (float): The average speed of the delivery trucks in kilometers per hour. - Returns: - float: The estimated delivery time in hours. + Returns: + float: The estimated delivery time in hours. - Preconditions: - - distance must be a non-negative float or int. - - average_speed must be a positive float or int. + Preconditions: + - distance must be a non-negative float or int. + - average_speed must be a positive float or int. - Raises: - AssertionError: If any of the preconditions are violated. + Raises: + AssertionError: If any of the preconditions are violated. - Examples: - >>> shipment_time_estimation(100, 50) - 2.0 - >>> shipment_time_estimation(1500, 100) - 15.0 - >>> shipment_time_estimation(0, 10) - 0.0 + Examples: + >>> shipment_time_estimation(100, 50) + 2.0 + >>> shipment_time_estimation(1500, 100) + 15.0 + >>> shipment_time_estimation(0, 10) + 0.0 - AssertionError: average_speed must be greater than zero. - AssertionError: distance must be non-negative. + AssertionError: average_speed must be greater than zero. + AssertionError: distance must be non-negative. """ # Defensive checks with assertions - assert isinstance( - distance, (int, float) - ), "distance must be a number (int or float)." + assert isinstance(distance, (int, float)), "distance must be a number (int or float)." assert distance >= 0, "distance must be non-negative." - assert isinstance( - average_speed, (int, float) - ), "average_speed must be a number (int or float)." + assert isinstance(average_speed, (int, float)), "average_speed must be a number (int or float)." assert average_speed > 0, "average_speed must be greater than zero." - # Assign received arguments to local variables - for debugging purpose only - local_distance = distance - - local_average_speed = average_speed - - # Calculate the shipment time using local variables - estimated_time = local_distance / local_average_speed + # Calculate the shipment time using the arguments + estimated_time = distance / average_speed return estimated_time From 53fb00ea5230982399e43364cd1fe7c96e708a70 Mon Sep 17 00:00:00 2001 From: fevziismailsahin Date: Sat, 11 Jan 2025 13:22:52 -0700 Subject: [PATCH 2/7] Add palindrome checker module to verify strings and numbers --- solutions/palindrome_checker.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 solutions/palindrome_checker.py diff --git a/solutions/palindrome_checker.py b/solutions/palindrome_checker.py new file mode 100644 index 000000000..19a565211 --- /dev/null +++ b/solutions/palindrome_checker.py @@ -0,0 +1,20 @@ +""" +Module for checking if given words or numbers are palindromes. + +This module checks a list of strings and numbers to determine if each one +is a palindrome (reads the same forward and backward). The check is done +for multiple inputs using a for loop. + +Author: fevziismailsahin +Created: 01/09/2025 +""" + +strings_to_check = ["Radar", "12321", "Hello", "1.232.1", "12345", "aA", "Test"] + +for value in strings_to_check: + cleaned_value = "".join([char.lower() for char in value if char.isalnum()]) + + if cleaned_value == cleaned_value[::-1]: + print(f"'{value}' is a palindrome.") + else: + print(f"'{value}' is not a palindrome.") From e65159cf3c6b58fde5b1920535716ad9b40e2d63 Mon Sep 17 00:00:00 2001 From: fevziismailsahin Date: Sat, 11 Jan 2025 13:29:09 -0700 Subject: [PATCH 3/7] improvements --- solutions/shipment_time_estimation.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/solutions/shipment_time_estimation.py b/solutions/shipment_time_estimation.py index c23ca8b40..e531a878d 100644 --- a/solutions/shipment_time_estimation.py +++ b/solutions/shipment_time_estimation.py @@ -43,9 +43,13 @@ def shipment_time_estimation(distance: float, average_speed: float) -> float: """ # Defensive checks with assertions - assert isinstance(distance, (int, float)), "distance must be a number (int or float)." + assert isinstance(distance, (int, float)), ( + "distance must be a number (int or float)." + ) assert distance >= 0, "distance must be non-negative." - assert isinstance(average_speed, (int, float)), "average_speed must be a number (int or float)." + assert isinstance(average_speed, (int, float)), ( + "average_speed must be a number (int or float)." + ) assert average_speed > 0, "average_speed must be greater than zero." # Calculate the shipment time using the arguments From 8ad529a13c0c44634f21b5cf7fa2b1831da0c514 Mon Sep 17 00:00:00 2001 From: fevziismailsahin Date: Sat, 11 Jan 2025 15:42:52 -0700 Subject: [PATCH 4/7] solutions/palindrome_checker.py update --- solutions/palindrome_checker.py | 45 +++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/solutions/palindrome_checker.py b/solutions/palindrome_checker.py index 19a565211..3ad660be5 100644 --- a/solutions/palindrome_checker.py +++ b/solutions/palindrome_checker.py @@ -6,15 +6,44 @@ for multiple inputs using a for loop. Author: fevziismailsahin -Created: 01/09/2025 +Created: 01/10/2025 """ -strings_to_check = ["Radar", "12321", "Hello", "1.232.1", "12345", "aA", "Test"] +from typing import List -for value in strings_to_check: - cleaned_value = "".join([char.lower() for char in value if char.isalnum()]) - if cleaned_value == cleaned_value[::-1]: - print(f"'{value}' is a palindrome.") - else: - print(f"'{value}' is not a palindrome.") +def check_palindromes(words_to_check: List[str]) -> None: + """ + Function check_palindromes checks if each word or number in the list is a palindrome. + + Parameters: + words_to_check (List[str]): A list of strings and numbers to check for palindrome + + Returns: + None: + Prints whether each word or number in the list is a palindrome or not + + Example: + + >>> check_palindromes(["Radar", "12321", "Hello", "1.232.1", "12345", "aA", "Test"]) + 'Radar' is a palindrome. + '12321' is a palindrome. + 'Hello' is not a palindrome. + '1.232.1' is a palindrome. + '12345' is not a palindrome. + 'aA' is a palindrome. + 'Test' is not a palindrome. + + """ + for value in words_to_check: + cleaned_value = "".join(filter(str.isalnum, value)).lower() + + if cleaned_value == cleaned_value[::-1]: + print(f"'{value}' is a palindrome.") + else: + print(f"'{value}' is not a palindrome.") + + +if __name__ == "__main__": + words_to_check_list = ["Radar", "12321", "Hello", "1.232.1", "12345", "aA", "Test"] + check_palindromes(words_to_check_list) From f98fdb231fb707131ae57f4c2bdcf49e100706a3 Mon Sep 17 00:00:00 2001 From: fevziismailsahin Date: Sat, 11 Jan 2025 16:08:17 -0700 Subject: [PATCH 5/7] update palindrome file name change --- solutions/{palindrome_checker.py => check_palindromes.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename solutions/{palindrome_checker.py => check_palindromes.py} (100%) diff --git a/solutions/palindrome_checker.py b/solutions/check_palindromes.py similarity index 100% rename from solutions/palindrome_checker.py rename to solutions/check_palindromes.py From c251df7bfc833cfa49c8e147baefd6640b503fc6 Mon Sep 17 00:00:00 2001 From: fevziismailsahin Date: Sat, 11 Jan 2025 16:08:40 -0700 Subject: [PATCH 6/7] Create test_check_palindromes.py --- solutions/tests/test_check_palindromes.py | 52 +++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 solutions/tests/test_check_palindromes.py diff --git a/solutions/tests/test_check_palindromes.py b/solutions/tests/test_check_palindromes.py new file mode 100644 index 000000000..c83b8af52 --- /dev/null +++ b/solutions/tests/test_check_palindromes.py @@ -0,0 +1,52 @@ +""" +Module represents unit test for check_palindromes + +Created on 01/11/2025 +Author fevziismailsahin +""" + +import unittest + +from solutions.check_palindromes import check_palindromes + + +class TestPalindromeChecker(unittest.TestCase): + def test_palindrome_words(self): + """ + Test: Check palindrome words correctly identified. + """ + with self.assertLogs(level="INFO") as log: + check_palindromes(["Radar", "12321", "aA"]) + self.assertIn("'Radar' is a palindrome.", log.output) + self.assertIn("'12321' is a palindrome.", log.output) + self.assertIn("'aA' is a palindrome.", log.output) + + def test_non_palindrome_words(self): + """ + Test: Check non-palindrome words correctly identified. + """ + with self.assertLogs(level="INFO") as log: + check_palindromes(["Hello", "12345", "Test"]) + self.assertIn("'Hello' is not a palindrome.", log.output) + self.assertIn("'12345' is not a palindrome.", log.output) + self.assertIn("'Test' is not a palindrome.", log.output) + + def test_mixed_case(self): + """ + Test: Check case-insensitive palindrome detection. + """ + with self.assertLogs(level="INFO") as log: + check_palindromes(["aA"]) + self.assertIn("'aA' is a palindrome.", log.output) + + def test_special_characters(self): + """ + Test: Check if special characters are correctly removed and palindrome check works. + """ + with self.assertLogs(level="INFO") as log: + check_palindromes(["1.232.1"]) + self.assertIn("'1.232.1' is a palindrome.", log.output) + + +if __name__ == "__main__": + unittest.main() From d0ee4d8cd48a1d9c1f5c9a97f2c4d9a1561061c9 Mon Sep 17 00:00:00 2001 From: fevziismailsahin Date: Sun, 12 Jan 2025 17:11:30 -0700 Subject: [PATCH 7/7] update check_palindromes --- solutions/check_palindromes.py | 10 +-- solutions/tests/test_check_palindromes.py | 104 +++++++++++++--------- 2 files changed, 67 insertions(+), 47 deletions(-) diff --git a/solutions/check_palindromes.py b/solutions/check_palindromes.py index 3ad660be5..5782ab209 100644 --- a/solutions/check_palindromes.py +++ b/solutions/check_palindromes.py @@ -35,15 +35,15 @@ def check_palindromes(words_to_check: List[str]) -> None: 'Test' is not a palindrome. """ + if not isinstance(words_to_check, list): + raise TypeError("Input must be a list") + for value in words_to_check: + if not isinstance(value, str): + raise TypeError("List must contain only strings") cleaned_value = "".join(filter(str.isalnum, value)).lower() if cleaned_value == cleaned_value[::-1]: print(f"'{value}' is a palindrome.") else: print(f"'{value}' is not a palindrome.") - - -if __name__ == "__main__": - words_to_check_list = ["Radar", "12321", "Hello", "1.232.1", "12345", "aA", "Test"] - check_palindromes(words_to_check_list) diff --git a/solutions/tests/test_check_palindromes.py b/solutions/tests/test_check_palindromes.py index c83b8af52..1439c3217 100644 --- a/solutions/tests/test_check_palindromes.py +++ b/solutions/tests/test_check_palindromes.py @@ -1,51 +1,71 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- """ -Module represents unit test for check_palindromes +Unit test module for checking palindromes. -Created on 01/11/2025 -Author fevziismailsahin +Test categories: + - Standard cases: correct inputs for words and numbers; + - Edge cases; + - Defensive tests: wrong input types, assertions; + +Author: fevziismailsahin +Created: 01/11/2025 """ +import sys import unittest +from io import StringIO + +from ..check_palindromes import check_palindromes + + +class TestCheckPalindromes(unittest.TestCase): + """Test suite for checking palindromes.""" + + def setUp(self): + """Set up the test environment.""" + self.held_output = StringIO() + sys.stdout = self.held_output + + def tearDown(self): + """Tear down the test environment.""" + sys.stdout = sys.__stdout__ + + # Standard cases: correct inputs + def test_standard_case_1(self): + """Test with typical valid inputs for words and numbers.""" + check_palindromes(["Radar", "12321", "Hello", "1.232.1", "12345", "aA", "Test"]) + self.assertIn("'Radar' is a palindrome.", self.held_output.getvalue()) + self.assertIn("'12321' is a palindrome.", self.held_output.getvalue()) + self.assertIn("'Hello' is not a palindrome.", self.held_output.getvalue()) + self.assertIn("'1.232.1' is a palindrome.", self.held_output.getvalue()) + self.assertIn("'12345' is not a palindrome.", self.held_output.getvalue()) + self.assertIn("'aA' is a palindrome.", self.held_output.getvalue()) + self.assertIn("'Test' is not a palindrome.", self.held_output.getvalue()) + + # Edge cases: testing empty and single-character strings + def test_empty_string(self): + """Test with an empty string.""" + check_palindromes([""]) + self.assertIn("'' is a palindrome.", self.held_output.getvalue()) + + def test_single_character(self): + """Test with a single character.""" + check_palindromes(["a", "1", "!"]) + self.assertIn("'a' is a palindrome.", self.held_output.getvalue()) + self.assertIn("'1' is a palindrome.", self.held_output.getvalue()) + self.assertIn("'!' is a palindrome.", self.held_output.getvalue()) + + # Defensive tests: wrong input types, assertions + def test_invalid_input_type(self): + """Test when input is not a list.""" + with self.assertRaises(TypeError): + check_palindromes("not a list") -from solutions.check_palindromes import check_palindromes - - -class TestPalindromeChecker(unittest.TestCase): - def test_palindrome_words(self): - """ - Test: Check palindrome words correctly identified. - """ - with self.assertLogs(level="INFO") as log: - check_palindromes(["Radar", "12321", "aA"]) - self.assertIn("'Radar' is a palindrome.", log.output) - self.assertIn("'12321' is a palindrome.", log.output) - self.assertIn("'aA' is a palindrome.", log.output) - - def test_non_palindrome_words(self): - """ - Test: Check non-palindrome words correctly identified. - """ - with self.assertLogs(level="INFO") as log: - check_palindromes(["Hello", "12345", "Test"]) - self.assertIn("'Hello' is not a palindrome.", log.output) - self.assertIn("'12345' is not a palindrome.", log.output) - self.assertIn("'Test' is not a palindrome.", log.output) - - def test_mixed_case(self): - """ - Test: Check case-insensitive palindrome detection. - """ - with self.assertLogs(level="INFO") as log: - check_palindromes(["aA"]) - self.assertIn("'aA' is a palindrome.", log.output) - - def test_special_characters(self): - """ - Test: Check if special characters are correctly removed and palindrome check works. - """ - with self.assertLogs(level="INFO") as log: - check_palindromes(["1.232.1"]) - self.assertIn("'1.232.1' is a palindrome.", log.output) + def test_non_string_elements(self): + """Test when input list contains non-string elements.""" + with self.assertRaises(TypeError): + check_palindromes([123, 456]) if __name__ == "__main__":