Skip to content

Commit

Permalink
Complete Anagram Finder implementation with tests and docstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
Frank2446-dotcom committed Jan 12, 2025
1 parent 2a7afa2 commit 6815cdc
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 37 deletions.
18 changes: 8 additions & 10 deletions solutions/anagram_finder.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@
@author: Frankline Ambetsa
"""

import doctest


def is_anagram(string1: str, string2: str) -> bool:
def anagram_finder(string1: str, string2: str) -> bool:
"""
Check if two strings are anagrams of each other.
Expand All @@ -28,15 +26,15 @@ def is_anagram(string1: str, string2: str) -> bool:
Raises:
ValueError: If any string is empty except when both are empty.
>>> is_anagram("listen", "silent")
>>> anagram_finder("listen", "silent")
True
>>> is_anagram("evil", "vile")
>>> anagram_finder("evil", "vile")
True
>>> is_anagram("hello", "world")
>>> anagram_finder("hello", "world")
False
>>> is_anagram("a gentleman", "elegant man")
>>> anagram_finder("a gentleman", "elegant man")
True
>>> is_anagram("clint eastwood", "old west action")
>>> anagram_finder("clint eastwood", "old west action")
True
"""

Expand All @@ -61,6 +59,6 @@ def is_anagram(string1: str, string2: str) -> bool:
return sorted(string1) == sorted(string2)


# Run doctests when executed directly
# No doctest or function call here.
if __name__ == "__main__":
doctest.testmod()
pass
62 changes: 35 additions & 27 deletions solutions/tests/test_anagram_finder.py
Original file line number Diff line number Diff line change
@@ -1,68 +1,76 @@
# Import statements must be at the top of the file
import unittest
"""
Unit tests for the `anagram_finder` function.
These tests ensure correct behavior of the `anagram_finder` function,
including standard merging, conflict resolution, edge cases, and input validation.
from solutions.anagram_finder import is_anagram
Created on 03 01 2025
@author: Frankline Ambetsa
"""

import unittest
from solutions.anagram_finder import anagram_finder


class TestAnagramFinder(unittest.TestCase):
"""Test cases for the is_anagram function."""
"""Test cases for the anagram_finder function."""

def test_anagrams(self):
"""Test cases for valid anagrams."""
self.assertTrue(is_anagram("listen", "silent"))
self.assertTrue(is_anagram("evil", "vile"))
self.assertTrue(is_anagram("dusty", "study"))
self.assertTrue(is_anagram("night", "thing"))
self.assertTrue(is_anagram("brag", "grab"))
self.assertTrue(anagram_finder("listen", "silent"))
self.assertTrue(anagram_finder("evil", "vile"))
self.assertTrue(anagram_finder("dusty", "study"))
self.assertTrue(anagram_finder("night", "thing"))
self.assertTrue(anagram_finder("brag", "grab"))

def test_not_anagrams(self):
"""Test cases for invalid anagrams."""
self.assertFalse(is_anagram("hello", "world"))
self.assertFalse(is_anagram("python", "java"))
self.assertFalse(is_anagram("test", "tess"))
self.assertFalse(is_anagram("abcd", "dcbae"))
self.assertFalse(anagram_finder("hello", "world"))
self.assertFalse(anagram_finder("python", "java"))
self.assertFalse(anagram_finder("test", "tess"))
self.assertFalse(anagram_finder("abcd", "dcbae"))

def test_case_insensitivity(self):
"""Test that the function is case-insensitive."""
self.assertTrue(is_anagram("Listen", "Silent"))
self.assertTrue(is_anagram("Evil", "Vile"))
self.assertTrue(anagram_finder("Listen", "Silent"))
self.assertTrue(anagram_finder("Evil", "Vile"))

def test_different_lengths(self):
"""Test cases where the strings have different lengths."""
self.assertFalse(is_anagram("abc", "ab"))
self.assertFalse(is_anagram("abcd", "abcde"))
self.assertFalse(anagram_finder("abc", "ab"))
self.assertFalse(anagram_finder("abcd", "abcde"))

def test_empty_strings(self):
"""Test edge cases with empty strings."""
self.assertTrue(
is_anagram("", "")
anagram_finder("", "")
) # Both empty strings should be considered anagrams
with self.assertRaises(AssertionError):
is_anagram(
anagram_finder(
"a", ""
) # A non-empty string and empty string shouldn't be anagrams
with self.assertRaises(AssertionError):
is_anagram(
anagram_finder(
"", "b"
) # An empty string and non-empty string shouldn't be anagrams

def test_special_characters(self):
"""Test cases with special characters and spaces."""
self.assertTrue(is_anagram("a gentleman", "elegant man"))
self.assertTrue(is_anagram("clint eastwood", "old west action"))
self.assertFalse(is_anagram("hello world", "world hello!"))
self.assertTrue(anagram_finder("a gentleman", "elegant man"))
self.assertTrue(anagram_finder("clint eastwood", "old west action"))
self.assertFalse(anagram_finder("hello world", "world hello!"))

def test_defensive_assertions(self):
"""Test defensive assertions for invalid inputs."""
with self.assertRaises(AssertionError):
is_anagram(123, "silent") # Non-string input
anagram_finder(123, "silent") # Non-string input
with self.assertRaises(AssertionError):
is_anagram("listen", 123) # Non-string input
anagram_finder("listen", 123) # Non-string input

with self.assertRaises(AssertionError):
is_anagram("a", "") # Empty string as second argument
anagram_finder("a", "") # Empty string as second argument
with self.assertRaises(AssertionError):
is_anagram("", "b") # Empty string as first argument
anagram_finder("", "b") # Empty string as first argument


if __name__ == "__main__":
Expand Down

0 comments on commit 6815cdc

Please sign in to comment.