Skip to content

Commit

Permalink
Merge pull request #58 from MIT-Emerging-Talent/check_palindrome
Browse files Browse the repository at this point in the history
check_palindrome
  • Loading branch information
theabdallahnjr authored Jan 12, 2025
2 parents f4913e3 + a58c15e commit 8e53312
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 0 deletions.
73 changes: 73 additions & 0 deletions solutions/is_palindrome.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
A module for checking if a string is a palindrome.
Module contents:
- is_palindrome: checks whether a given string is a palindrome,
ignoring spaces, punctuation, and case differences.
Created on 2024-12-30
@author: Huda Alamassi
"""

import unicodedata


def is_palindrome(text_to_check: str) -> bool:
"""
The function takes in a string and returns True if the string is a palindrome
(reads the same backward as forward ignoring spaces, punctuation,
and case differences) and False otherwise.
Arguments:
text_to_check (str): The input string to be checked.
Returns:
bool:
- True if the string is a palindrome after removing spaces, punctuation,
and case differences.
- False if the string is not a palindrome or contains only spaces/punctuation.
Raises:
AssertionError: If the input is not a string.
Examples:
>>> is_palindrome("radar")
True
>>> is_palindrome("hello")
False
>>> is_palindrome("A man, a plan, a canal, Panama!")
True
>>> is_palindrome("No 'x' in Nixon")
True
"""
# validate input type
assert isinstance(text_to_check, str), "text_to_check must be a string"

# ensure case-insensitivity
text_to_check = text_to_check.lower()

# whitespace should not impact the palindrome check
text_to_check = "".join(text_to_check.split())

# punctuation should not impact the palindrome check
cleaned_text = ""
for text_char in text_to_check:
if not unicodedata.category(text_char).startswith("P"):
cleaned_text += text_char

# exclude empty or non-informative strings
if cleaned_text == "":
return False

reversed_text = cleaned_text[::-1]

return reversed_text == cleaned_text
92 changes: 92 additions & 0 deletions solutions/tests/test_is_palindrome.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Test module for is_palindrome function.
Contains tests for checking palindrome functionality with spaces, punctuation, and other edge cases.
Test categories:
- Functionality tests: checking if the function correctly identifies palindromes
and non-palindromes
- Palindrome tests: typical palindromes with various punctuations and spaces
- Non-palindrome tests: strings that are not palindromes, even with punctuation and spaces
- Edge cases: empty strings, strings with only spaces, single, double characters
and and case insensitivity
- Defensive tests: incorrect input types such as booleans and non-string values
Created on 2024-12-30
Author: Huda Alamassi
"""

import unittest

from solutions.is_palindrome import is_palindrome


class TestIsPalindrome(unittest.TestCase):
"""Test the is_palindrome function."""

def test_palindrome_string(self):
"""it should return True if you pass a palindrome string."""
actual = is_palindrome("radar")
self.assertEqual(actual, True)

def test_non_palindrome_string(self):
"""it should return False if you pass a non-palindrome string."""
actual = is_palindrome("hello")
self.assertEqual(actual, False)

def test_ignore_spaces_and_punctuation(self):
"""It should return True for a palindrome string that includes spaces and punctuation."""
actual = is_palindrome("A man, a plan, a canal, Panama!")
self.assertEqual(actual, True)

def test_ignore_spaces_and_punctuation_2(self):
"""It should return True for another palindrome string with spaces and punctuation."""
actual = is_palindrome(
"Are we not pure? “No, sir!” Panama’s moody Noriega brags. "
"“It is garbage!” Irony dooms a man—a prisoner up to new era."
)
self.assertEqual(actual, True)

def test_empty_string(self):
"""it should return False if you pass an empty string"""
actual = is_palindrome("")
self.assertEqual(actual, False)

def test_space_string(self):
"""it should return False if you pass a string containing space"""
actual = is_palindrome(" ")
self.assertEqual(actual, False)

def test_single_character(self):
"""it should return True if you pass a single character"""
actual = is_palindrome("a")
self.assertEqual(actual, True)

def test_two_identical_characters(self):
"""it should return True if you pass two-character string with identical characters"""
actual = is_palindrome("aa")
self.assertEqual(actual, True)

def test_string_with_identical_punctuation(self):
"""it should return False if you pass two identical punctuation characters"""
actual = is_palindrome("!!")
self.assertEqual(actual, False)

def test_string_with_different_punctuation(self):
"""it should return False if you pass strings with different punctuation marks."""
actual = is_palindrome("!?")
self.assertEqual(actual, False)

def test_case_insensitivity(self):
"""It should return True for a palindrome string regardless of letter case."""
actual = is_palindrome("Level")
self.assertEqual(actual, True)

# test defensive assertions
def test_defensive_assertion_for_integer_input(self):
"""It should raise an AssertionError if the input is not a string."""
with self.assertRaises(AssertionError):
is_palindrome(123321)

0 comments on commit 8e53312

Please sign in to comment.