diff --git a/solutions/is_palindrome.py b/solutions/is_palindrome.py new file mode 100644 index 000000000..61ee8e2de --- /dev/null +++ b/solutions/is_palindrome.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for checking if a given string is a palindrome (reads the same backward as forward) + +Module contents: + - palindrome: input string is palindrome if it reads the same backward as forward + +Created on 30.12.2024 +@author: Saad M. Ashour +""" + + +def is_palindrome(input_string: str) -> bool: + """ + Check if a given string is a palindrome. + + A palindrome is a word, phrase, number, or other sequence of characters + that reads the same forward and backward, ignoring spaces, punctuation, + and case sensitivity. + + Parameters: + input_string (str): The input string to be checked. + + Returns: + bool: True if the input string is a palindrome, False otherwise. + + Examples: + >>> is_palindrome("A man, a plan, a canal, Panama") + True + >>> is_palindrome("hello") + False + >>> is_palindrome("Madam") + True + """ + # AssertionError: Input must be a string + assert isinstance(input_string, str), "Input must be a string" + + # Remove non-alphanumeric characters and convert to lowercase + cleaned = "".join(char.lower() for char in input_string if char.isalnum()) + + # Check if the cleaned string is equal to its reverse + return cleaned == cleaned[::-1] diff --git a/solutions/tests/test_is_palindrome.py b/solutions/tests/test_is_palindrome.py new file mode 100644 index 000000000..1f1c8d4b8 --- /dev/null +++ b/solutions/tests/test_is_palindrome.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Unit tests for is_palindrome function. + +@author: Saad M. Ashour +""" + +import unittest + +from ..is_palindrome import is_palindrome + + +class TestIsPalindrome(unittest.TestCase): + """ + Unit tests for the is_palindrome function. + + These tests check various cases to ensure that the is_palindrome function correctly + identifies palindromes, considering case insensitivity, non-alphanumeric characters, + and other edge cases. + """ + + def test_palindrome(self): + """ + Test cases where the string is a palindrome. + """ + actual = is_palindrome("A man, a plan, a canal, Panama") + self.assertTrue(actual) + + def test_non_palindrome(self): + """ + Test cases where the string is not a palindrome. + """ + actual = is_palindrome("hello") + self.assertFalse(actual) + + def test_empty_string(self): + """ + Test case where the input is an empty string, which is considered a palindrome. + """ + actual = is_palindrome("") + self.assertTrue(actual) + + def test_single_character(self): + """ + Test case where the input is a single character, which is always a palindrome. + """ + actual = is_palindrome("a") + self.assertTrue(actual) + + def test_only_non_alphanumeric(self): + """ + Test case where the input contains only non-alphanumeric characters. + The function should ignore them and return True for empty string. + """ + actual = is_palindrome("!@#$$@!") + self.assertTrue(actual) + + +if __name__ == "__main__": + unittest.main()