Skip to content
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

Fevzi palindrome checker #34

Merged
merged 9 commits into from
Jan 13, 2025
49 changes: 49 additions & 0 deletions solutions/check_palindromes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""
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/10/2025
"""

from typing import List


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.

"""
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.")
47 changes: 21 additions & 26 deletions solutions/shipment_time_estimation.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,31 @@ 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
Expand All @@ -52,12 +52,7 @@ def shipment_time_estimation(distance: float, average_speed: float) -> 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
72 changes: 72 additions & 0 deletions solutions/tests/test_check_palindromes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Unit test module for checking palindromes.

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")

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__":
unittest.main()
Loading