Skip to content

Commit

Permalink
solved challenge_8 and ran test
Browse files Browse the repository at this point in the history
  • Loading branch information
SEMIRATESFAI committed Jan 9, 2025
1 parent 9ac28df commit 2cff250
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 0 deletions.
Empty file added solutions/challenge_8/README.md
Empty file.
45 changes: 45 additions & 0 deletions solutions/challenge_8/palindrome_detector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
A module for checking if a given string or bytes is a palindrome.
Module contents:
- is_palindrome: Determines if a string or bytes is a palindrome.
Created on 09/01/2025
Author: Semira Tesfai
"""

import re
from typing import Union


def is_palindrome(s: Union[str, bytes]) -> bool:
"""Determines if a given string or bytes is a palindrome.
Parameters:
s: Union[str, bytes], the input string or bytes to be checked
Returns -> bool: True if the input is a palindrome, False otherwise
Raises:
TypeError: If the input is not a string or bytes
Examples:
>>> is_palindrome("A man, a plan, a canal, Panama")
True
>>> is_palindrome("hello")
False
>>> is_palindrome(b"racecar")
True
>>> is_palindrome(b"hello")
False
"""
if not isinstance(s, (str, bytes)):
raise TypeError("Input must be a string or bytes")

if isinstance(s, bytes):
s = s.decode("utf-8") # Decode bytes to string

cleaned_s = re.sub(r"[^A-Za-z0-9]", "", s).lower()
return cleaned_s == cleaned_s[::-1]
83 changes: 83 additions & 0 deletions solutions/tests/challenge_8/test_palindrome_detector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Unit tests for palindrome_detector.py
Created on 09/01/2025
Author: Semira Tesfai
"""

import unittest

from solutions.challenge_8.palindrome_detector import is_palindrome


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

def setUp(self):
"""
Set up any state tied to the test execution. Invoked for every test method.
"""
self.simple_palindromes = ["racecar", "madam"]
self.complex_palindromes = ["A Santa at NASA", "A man, a plan, a canal, Panama"]
self.non_palindromes = ["hello", "This is not a palindrome"]
self.bytes_palindromes = [b"racecar", b"madam"]
self.bytes_non_palindromes = [b"hello", b"This is not a palindrome"]

def test_simple_palindrome(self):
"""
Test that simple palindromes are correctly identified.
"""
for sp in self.simple_palindromes:
with self.subTest(sp=sp):
self.assertTrue(is_palindrome(sp))

def test_complex_palindrome(self):
"""
Test that complex palindromes are correctly identified.
"""
for cp in self.complex_palindromes:
with self.subTest(cp=cp):
self.assertTrue(is_palindrome(cp))

def test_non_palindrome(self):
"""
Test that non-palindromic words and phrases are correctly identified.
"""
for np in self.non_palindromes:
with self.subTest(np=np):
self.assertFalse(is_palindrome(np))

def test_bytes_palindrome(self):
"""
Test that palindromes with bytes input are correctly identified.
"""
for bp in self.bytes_palindromes:
with self.subTest(bp=bp):
self.assertTrue(is_palindrome(bp))

def test_bytes_non_palindrome(self):
"""
Test that non-palindromic words and phrases with bytes input are correctly identified.
"""
for bnp in self.bytes_non_palindromes:
with self.subTest(bnp=bnp):
self.assertFalse(is_palindrome(bnp))

def test_invalid_input(self):
"""
Test that invalid input raises the appropriate exception.
"""
with self.assertRaises(TypeError):
is_palindrome(12345)
with self.assertRaises(TypeError):
is_palindrome(None)

def tearDown(self):
"""
Tear down any state that was previously set up with a call to setUp().
"""
pass

0 comments on commit 2cff250

Please sign in to comment.