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

Valid anagram (Resolves #94) #95

Merged
merged 17 commits into from
Jan 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions solutions/tests/test_valid_anagram.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""
Unit tests for validating the valid_anagram function.

Test Categories:
- Standard Cases: Basic anagram checking with various words
- Edge Cases: Empty strings and repeated characters
- Special Cases: Strings with numbers, spaces, and special characters
- Defensive Cases: Invalid input handling

The tests verify that the function:
- Correctly identifies anagrams
- Handles case sensitivity
- Processes special characters and numbers
- Validates input types
- Manages empty strings and spaces

Created on: 2025-01-11
@author: Fatima
"""

import unittest
from solutions.valid_anagram import valid_anagram


class TestValidAnagram(unittest.TestCase):
"""Test cases for valid_anagram function."""

# Standard Cases
def test_basic_anagram(self):
"""It should identify basic anagrams correctly."""
self.assertTrue(valid_anagram("listen", "silent"))

def test_not_anagram(self):
"""It should return False for non-anagram strings."""
self.assertFalse(valid_anagram("hello", "world"))

def test_same_word(self):
"""It should identify same words as anagrams."""
self.assertTrue(valid_anagram("word", "word"))

def test_case_sensitive(self):
"""It should be case sensitive in comparison."""
self.assertFalse(valid_anagram("fatima", "Fatima"))

# Edge Cases
def test_empty_string(self):
"""It should identify empty strings as anagrams."""
self.assertTrue(valid_anagram("", ""))

def test_repeated_characters(self):
"""It should handle strings with repeated characters."""
self.assertTrue(valid_anagram("aaccbb", "ccaabb"))

def test_long_strings(self):
"""It should handle long strings with repeated characters efficiently."""
first_string = "a" * 10000 + "b" * 5000 + "c" * 3000
second_string = "c" * 3000 + "a" * 10000 + "b" * 5000
self.assertTrue(valid_anagram(first_string, second_string))

# Special Cases
def test_string_with_numbers(self):
"""It should identify numbers in a string as anagram."""
self.assertTrue(valid_anagram("mad1ha", "aah1dm"))

def test_special_characters(self):
"""It should handle special characters correctly."""
self.assertTrue(valid_anagram("a!b@", "b@a!"))

def test_spaces(self):
"""It should handle spaces as regular characters."""
self.assertTrue(valid_anagram("a b", "b a"))

# Defensive Cases
def test_non_string_first_arg(self):
"""It should raise AssertionError for non-string first argument."""
with self.assertRaises(AssertionError):
valid_anagram(1998, "Jola")

def test_non_string_second_arg(self):
"""It should raise AssertionError for non-string second argument."""
with self.assertRaises(AssertionError):
valid_anagram("Evan", None)


if __name__ == "__main__":
unittest.main()
61 changes: 61 additions & 0 deletions solutions/valid_anagram.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"""
Module for checking if two strings are valid anagrams.

This module provides functionality to determine if two strings are anagrams
of each other (contain exactly the same characters with the same frequency).

Created on: 2025-01-11
@author: Fatima
"""


def valid_anagram(first_word: str, second_word: str) -> bool:
"""
Returns True if two strings are anagrams, otherwise False.

Args:
first_word: First string to compare
Must be a string containing any characters
second_word: Second string to compare
Must be a string containing any characters

Returns:
bool: True if strings are anagrams, False otherwise

Raises:
AssertionError: If either input is not a string

Examples:
>>> valid_anagram("listen", "silent")
True
>>> valid_anagram("hello", "world")
False
>>> valid_anagram("", "")
True
"""

# Ensure both inputs are strings
assert isinstance(first_word, str), "First argument must be a string"
assert isinstance(second_word, str), "Second argument must be a string"

# Anagrams must be of equal length
if len(first_word) != len(second_word):
return False

# Create character frequency dictionary
char_count = {}

# Count occurrences of each character in str1
for char in first_word:
char_count[char] = char_count.get(char, 0) + 1

# Decrease character counts and check if any character is missing or overused
for char in second_word:
if char not in char_count:
return False
char_count[char] -= 1
if char_count[char] == 0:
del char_count[char]

# If all character counts are zero, the strings are anagrams
return len(char_count) == 0
Loading