Skip to content

Commit

Permalink
Merge pull request #36 from MIT-Emerging-Talent/word-frequency-counter
Browse files Browse the repository at this point in the history
Word frequency counter
  • Loading branch information
AhmadHamedDehzad authored Jan 12, 2025
2 parents cd498d6 + 6e39c6c commit d9c4199
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 0 deletions.
71 changes: 71 additions & 0 deletions solutions/tests/test_word_frequency_counter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
This is a test module for counting the frequency of words in a given sentence.
Test categories:
- Standard cases: typical strings with different lengths
- Edge cases: white space input and punctuation handling
- Defensive tests: non-string inputs
Created on 01.01.2025
@author: Ahmad Hamed Dehzad
"""

import unittest
from ..word_frequency_counter import word_frequency_counter


class TestWordFrequencyCounter(unittest.TestCase):
"""Test the word_frequency_counter function"""

def test_empty_string(self):
"""It should evaluate an empty string to an empty dictionary"""
actual = word_frequency_counter("")
expected = {}
self.assertEqual(actual, expected)

def test_single_word(self):
"""It should evaluate a single word correctly"""
actual = word_frequency_counter("Hello")
expected = {"hello": 1}
self.assertEqual(actual, expected)

def test_multiple_words(self):
"""It should count the frequency of multiple words"""
actual = word_frequency_counter("Hello world hello")
expected = {"hello": 2, "world": 1}
self.assertEqual(actual, expected)

def test_case_insensitivity(self):
"""It should treat words case-insensitively"""
actual = word_frequency_counter("Apple apple APPLE")
expected = {"apple": 3}
self.assertEqual(actual, expected)

def test_with_punctuation(self):
"""It should handle punctuation by ignoring it"""
actual = word_frequency_counter("Hello, world! Hello.")
expected = {"hello": 2, "world": 1} # Updated expected result
self.assertEqual(actual, expected)

def test_numbers_in_string(self):
"""It should handle strings with numbers"""
actual = word_frequency_counter("123 123 456")
expected = {"123": 2, "456": 1}
self.assertEqual(actual, expected)

def test_non_string_input(self):
"""It should raise a ValueError if the input is not a string"""
with self.assertRaises(ValueError):
word_frequency_counter(12345)

def test_with_whitespace(self):
"""It should handle extra spaces correctly"""
actual = word_frequency_counter(" Hello world ")
expected = {"hello": 1, "world": 1}
self.assertEqual(actual, expected)


if __name__ == "__main__":
unittest.main()
52 changes: 52 additions & 0 deletions solutions/word_frequency_counter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
A module for counting the frequency of words in a given sentence.
Features:
- Handles case-insensitivity
- Strips punctuation
- Validates input as a string
Created on 01.01.2025
@author: Ahmad Hamed Dehzad
Examples:
>>> word_frequency_counter("Hello world hello")
{'hello': 2, 'world': 1}
>>> word_frequency_counter("Hello, world! Hello.")
{'hello': 2, 'world': 1}
"""

import string


def word_frequency_counter(sentence: str) -> dict[str, int]:
"""
Counts the frequency of each word in a given sentence.
Args:
sentence (str): A sentence containing words.
Returns:
dict[str, int]: A dictionary where keys are words (case-insensitive)
and values are their frequency.
Raises:
ValueError: If the input is not a string.
"""
if not isinstance(sentence, str):
raise ValueError("Invalid input: Please enter a text string.")

# Remove punctuation and split into words
cleaned_sentence = sentence.translate(str.maketrans("", "", string.punctuation))
words = cleaned_sentence.split()

# Count word frequencies
word_frequencies = {}
for word in words:
word = word.lower()
word_frequencies[word] = word_frequencies.get(word, 0) + 1

return word_frequencies

0 comments on commit d9c4199

Please sign in to comment.