diff --git a/.vscode/settings.json b/.vscode/settings.json index 66af31ed7..4815272c0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -123,5 +123,5 @@ "source.organizeImports.ruff": "explicit" } }, - "cSpell.words": ["unittests"] +"cSpell.words": ["dcbae", "doctests", "unittests"] } diff --git a/solutions/README.md b/solutions/README.md index a3f85b77b..bd3e4395e 100644 --- a/solutions/README.md +++ b/solutions/README.md @@ -1,30 +1,37 @@ # Solutions -## Merge Dictionaries Solution +This folder contains implementations for the challenges. -This repository contains a Python solution to merge two dictionaries. -The solution merges two dictionaries by resolving conflicts based on an optional - conflict resolution function. +## Challenges -### Features +1. **Merge Dictionaries**: + - A utility to merge two dictionaries with conflict resolution. + - See `merge_dictionaries.py` for the implementation. -- Merges two dictionaries. -- Resolves conflicts with a custom function, or by default, `dict2` overwrites `dict1`. +2. **Anagram Finder**: + - A function to check if two strings are anagrams. + - See `anagram_finder.py` for the implementation. + +## Usage + +To use any solution, simply import the +required function and pass the appropriate arguments. ### How to Run 1. Clone the repository. -2. Install dependencies (if any). -3. Run the tests: +2. Navigate to the folder containing the solution. +3. Run the desired script: ```bash - python -m unittest solutions/tests/test_merge_dictionaries.py + python .py ``` ### Example ```python -dict1 = {"a": 1, "b": 2} -dict2 = {"b": 3, "c": 4} -merged = merge_dictionaries(dict1, dict2) -print(merged) # Output: {'a': 1, 'b': 3, 'c': 4} +# Example for Anagram Finder +from anagram_finder import are_anagrams + +result = are_anagrams("listen", "silent") +print(result) # Output: True diff --git a/solutions/Remove_Duplicates.py b/solutions/Remove_Duplicates.py deleted file mode 100644 index 16c1562d9..000000000 --- a/solutions/Remove_Duplicates.py +++ /dev/null @@ -1,50 +0,0 @@ -""" -A module for removing duplicates from a list of numbers - -Module contents: - - Remove_Duplicates: Remove any duplicate numbers in the list - -Created on 2025-1-4 -@author: Safaa Osman -""" - - -def Remove_Duplicates(items: list) -> list: - """ - This Function Removes any duplicates elements from the list - - Arguments: list of elements - - Returns: list of elements without duplicates. - - Raises: - AssertionError: if the input is not a list - - - Examples: - >>> Remove_Duplicates(['a','b','a']) - ['a', 'b'] - - >>> Remove_Duplicates([1,1,2]) - [1, 2] - - >>> Remove_Duplicates([1,2,2,3,3,3]) - [1, 2, 3] - - >>> Remove_Duplicates([1]) - [1] - - >>> Remove_Duplicates([]) - [] - - >>> Remove_Duplicates([5,5,5,5,5,5,5]) - [5] - - """ - assert isinstance(items, list), "input must be a list" - - Final_list = [] - for item in items: - if item not in Final_list: - Final_list.append(item) - return Final_list diff --git a/solutions/Swap_letters.py b/solutions/Swap_letters.py deleted file mode 100644 index 05a21bf18..000000000 --- a/solutions/Swap_letters.py +++ /dev/null @@ -1,39 +0,0 @@ -""" -Created on 08/01/2024 - -@author: Tibyan Khalid - -This file contains the function Swap_letters that swaps the case of each letter in a string. -""" - - -def Swap_letters(string: str) -> str: - """Swap_letters will return the string given with switched cases. - - Parameters: - String(str) "the word that will get modified" - - Returns: modified_string(str) "the string with swapped cases" - - >>> Swap_letters("hello") - 'HELLO' - - >>> Swap_letters("HELLO") - 'hello' - - >>> Swap_letters("HeLlO") - 'hElLo' - """ - if not isinstance(string, str): - "Make sure the expected input is a string" - raise AssertionError("Input must be a string") - - changed_string = "" - for char in string: - if char.islower(): - changed_string += char.upper() - elif char.isupper(): - changed_string += char.lower() - else: - changed_string += char - return changed_string diff --git a/solutions/Time_Conversion.py b/solutions/Time_Conversion.py deleted file mode 100644 index 524818bca..000000000 --- a/solutions/Time_Conversion.py +++ /dev/null @@ -1,65 +0,0 @@ -""" -A module for Converting time from Eastern Standard Time zone (EST) to Arabia -Standard Time (AST) - -Created on 2025-01-07 -Author: Safaa Osman -""" - - -def Time_Conversion(est_time: str) -> str: - """Returns a time in Arabia Standard Time zone (AST) - - Takes input time in the format HH:MM (24-hours format) and returns - the equavelent time in AST in the same format. - - Parameters: - EST_Time (str): time in EST in the format 24 hour - - Returns -> str: time in AST in the format 24 hour - - Raises: - TypeError: if the input is not a string - AssertionError: if the hours are not between the boundary of (0-23) - AssertionError: if the minutes are not between the boundary of (0-59) - AssertionError: if the input is empty string - - - Examples: - >>> Time_Conversion("14:30") - '22:30' - - >>> Time_Conversion("08:15") - '16:15' - - >>> Time_Conversion("00:00") - '08:00' - - - """ - assert est_time != "", "input should be a time in HH:MM format" - - assert isinstance(est_time, str), "The input must be string" - - # split the input to hours and minutes in integers - hours, minutes = est_time.split(":") - - # Assert hours and minutes are numbers - assert hours.isdigit(), "hours must be integers" - assert minutes.isdigit(), "minutes must be integers" - - hours = int(hours) - minutes = int(minutes) - - # Assert boundary - if not (0 <= hours <= 23): - raise ValueError("hours must be between 0 and 23") - if not (0 <= minutes <= 59): - raise ValueError("minutes must be between 0 and 59") - - hours += 8 - - if hours >= 24: - hours -= 24 - - return f"{str(hours).zfill(2)}:{str(minutes).zfill(2)}" diff --git a/solutions/anagram_finder.py b/solutions/anagram_finder.py new file mode 100644 index 000000000..61b09afeb --- /dev/null +++ b/solutions/anagram_finder.py @@ -0,0 +1,63 @@ +""" +Anagram Finder Module + +This module provides a function to determine if two strings are anagrams of each other. +It checks if the strings are anagrams, handling edge cases like empty strings, special characters, and case-insensitivity. + +Created on 12 01 2025 +@author: Frankline Ambetsa +""" + + +def anagram_finder(string1: str, string2: str) -> bool: + """ + Check if two strings are anagrams of each other. + + Anagrams are words or phrases made by rearranging the letters of another word or phrase. + This function will check for anagram status while ignoring spaces and case sensitivity. + + Args: + string1 (str): The first string. + string2 (str): The second string. + + Returns: + bool: True if the strings are anagrams, False otherwise. + + Raises: + ValueError: If any string is empty except when both are empty. + + >>> anagram_finder("listen", "silent") + True + >>> anagram_finder("evil", "vile") + True + >>> anagram_finder("hello", "world") + False + >>> anagram_finder("a gentleman", "elegant man") + True + >>> anagram_finder("clint eastwood", "old west action") + True + """ + + # Defensive assertions for valid string inputs + assert isinstance(string1, str), "string1 must be a string" + assert isinstance(string2, str), "string2 must be a string" + + # If any string is empty, raise an error, unless both are empty + if string1 == "" and string2 == "": + return True # Both empty strings are considered anagrams of each other + + if string1 == "": + raise AssertionError("string1 cannot be empty") + if string2 == "": + raise AssertionError("string2 cannot be empty") + + # To Remove spaces and convert to lowercase + string1 = string1.replace(" ", "").lower() + string2 = string2.replace(" ", "").lower() + + # Check if sorted strings are equal (anagram check) + return sorted(string1) == sorted(string2) + + +if __name__ == "__main__": + pass diff --git a/solutions/calculate_square_area.py b/solutions/calculate_square_area.py deleted file mode 100644 index 2f30ef110..000000000 --- a/solutions/calculate_square_area.py +++ /dev/null @@ -1,44 +0,0 @@ -# !/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -A module for calculating the area of a square given the side_length - -Module contents: - calculate_square_area: calculates the area of a square - -Created on 04 01 2025 -@author: Kareiman Altayeb -""" - - -def calculate_square_area(side_length: float) -> float: - """The function asks the user to enter the side length of the square - and the function returns the area of the square. - - parameter: - side_length in integer or float - - raises: - AssertionError: if side_length was =< 0 - ValueError: if the value entered was or str or text - - returns: - side_length ** 2 - - >>> calculate_square_area(5) - 25 - - >>> calculate_square_area(12.30) - 151.91 - - >>> calculate_square_area(0.42) - 0.1764 - - """ - # The entry cannot be a text or letters, only numbers - assert isinstance(side_length, (int, float)), "input must be a number" - - if side_length <= 0: - raise AssertionError("side length must be bigger than zero") - - return side_length**2 diff --git a/solutions/check_number_type.py b/solutions/check_number_type.py deleted file mode 100644 index 3fe4685dc..000000000 --- a/solutions/check_number_type.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -This function asks the user to enter a number and checks if the number -is even or odd. It then returns the result as a string. - -Created on 05 01 2025 -@author: Eman Alfalouji. - -""" - - -def check_number_type(user_input: str) -> str: - """ - The function asks the user to enter a number and determines if it is type (even or odd.) - - - Parameters: - user_input (str): str - A string that represents an integer. - Floats or non-integer formats are not allowed. - Raises: - ValueError: If the input is empty. - ValueError: If the input is not a valid integer. - - Returns: - results will be a text whether "The number is even", "The number is odd" - or raises an appropriate error. - Examples : - >>> check_number_type("20") - "The number is even" - >>> check_number_type("11") - "The number is odd" - >>> check_number_type("-11") - "The number is odd" - >>> check_number_type("") - Traceback (most recent call last): - ... - ValueError:"Input cannot be empty. Enter a valid number." - >>> check_number_type("Eman") - Traceback (most recent call last): - ... - ValueError:"Please enter a valid number" - - - - - """ - user_input = user_input.strip() - # Check if it is empty - if not user_input: - raise ValueError("Input cannot be empty. Enter a valid number.") - # check if it is a number - if not user_input.lstrip("-").isdigit(): - raise ValueError("Please enter a valid number") - number = int(user_input) - # Check if the number is even or odd - if number % 2 == 0: - return "The number is even" - else: - return "The number is odd" diff --git a/solutions/convert_hours_to_minutes.py b/solutions/convert_hours_to_minutes.py deleted file mode 100644 index 0aa0ff896..000000000 --- a/solutions/convert_hours_to_minutes.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -A module for converting hours to minutes. - -Module contents: - - convert_hours_to_minutes: calculates the time in minutes based on hours. - -Created on 31-12-2024 -@author: Azza Omer -""" - - -def convert_hours_to_minutes(hour_wasted: int) -> int: - """ - Convert hours to minutes. - - Parameters: - hour_wasted (int): The number of hours wasted. Must be a positive integer. - - Returns: - int: The equivalent time in minutes. - - Examples: - >>> convert_hours_to_minutes(1) - 60 - >>> convert_hours_to_minutes(5) - 300 - >>> convert_hours_to_minutes(12) - 720 - >>> convert_hours_to_minutes(0) - 0 - >>> convert_hours_to_minutes(3) - 180 - >>> convert_hours_to_minutes("2") # Raises AssertionError - Traceback (most recent call last): - ... - AssertionError: hour_wasted must be an integer. - >>> convert_hours_to_minutes(-5) # Raises AssertionError - Traceback (most recent call last): - ... - AssertionError: hour_wasted must be greater than or equal to 0. - """ - assert isinstance(hour_wasted, int), "hour_wasted must be an integer." - assert hour_wasted >= 0, "hour_wasted must be greater than or equal to 0." - minutes = hour_wasted * 60 - return minutes diff --git a/solutions/convert_to_capital.py b/solutions/convert_to_capital.py deleted file mode 100644 index 197f516ed..000000000 --- a/solutions/convert_to_capital.py +++ /dev/null @@ -1,39 +0,0 @@ -# !/usr/bin/env python3 -# -*- coding: utf-8 -*- - -""" -A module that converts letters to uppercase - -Created on 31 12 2024 - -@author: Kareiman Altayeb -""" - - -def convert_to_capital(user_text: str) -> str: - """Asks the user to enter a text and returns the text in capital - - Parameters: - user_text (str): The user input text to be converted to uppercase. - - Returns: - str : user_text in capital letters - - Raises: - AssertionError: If the input is empty or contains only spaces. - - Examples: - >>> convert_to_capital('hello') - 'HELLO' - >>> convert_to_capital('HelLo') - 'HELLO' - >>> convert_to_capital('123hello') - '123HELLO' - """ - - user_text = user_text.strip() - - if not user_text: - raise AssertionError("Entry cannot be empty or just spaces") - - return user_text.upper() diff --git a/solutions/convert_to_uppercase.py b/solutions/convert_to_uppercase.py deleted file mode 100644 index cc462976c..000000000 --- a/solutions/convert_to_uppercase.py +++ /dev/null @@ -1,40 +0,0 @@ -# !/usr/bin/env python3 -# -*- coding: utf-8 -*- - -""" -A module that converts letters to uppercase - -Created on 31 12 2024 - -@author: Kareiman Altayeb -""" - - -def convert_to_uppercase(user_text: str) -> str: - """Asks the user to enter a text and returns the text in capital - with all characters in uppercase - - Parameters: - user_text (str): The user input text to be converted to uppercase. - - Returns: - str : user_text in upper case - - Raises: - AssertionError: If the input is empty or contains only spaces. - - Examples: - >>> convert_to_uppercase('hello') - 'HELLO' - >>> convert_to_uppercase('HelLo') - 'HELLO' - >>> convert_to_uppercase('123hello') - '123HELLO' - """ - - user_text = user_text.strip() - - if not user_text: - raise AssertionError("Entry cannot be empty or just spaces") - - return user_text.upper() diff --git a/solutions/is_palindrome.py b/solutions/is_palindrome.py deleted file mode 100644 index ab275c185..000000000 --- a/solutions/is_palindrome.py +++ /dev/null @@ -1,42 +0,0 @@ -""" -Created on 04/01/2025 - -@author: Tibyan Khalid -""" - - -def is_palindrome(string): - """is_palindrome fuction will return whether the entry given is a palindrome or not. - Palindrome: a word whose reverse is the same as the original word. - - Parameters: - string(str): the string to be checked. - - Returns: - string (str): "Palindrome" if the word is a palindrome, otherwise "Not Palindrome". - - Raises: - AssertionError: If the argument is not a string or if it's too long. - - >>> is_palindrome("RADAR") - 'Palindrome' - - >>> is_palindrome("radar") - 'Palindrome' - - >>> is_palindrome("Radar") - 'Not Palindrome' - - >>> is_palindrome("hello") - 'Not Palindrome' - """ - # Defensive assertions - assert isinstance(string, str), "Argument(Input) must be a string" - assert len(string) <= 100, ( - "Argument (Input) is too long, max allowed length is 100 characters" - ) - - if string == string[::-1]: - return "Palindrome" - else: - return "Not Palindrome" diff --git a/solutions/largest_number.py b/solutions/largest_number.py deleted file mode 100644 index 2e45b6dc3..000000000 --- a/solutions/largest_number.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -A module for finding the largest number. - -Module contents: - - largest_number: Extracts the largest number from a list of integers. - -Created on 11-01-2025 -@author: Azza -""" - - -def largest_number(list_numbers: list) -> int: - """Extract the largest number from the given list of integers. - - Args: - list_numbers (list): A list of integers. - - Returns: - int: The largest number in the list. - - Raises: - TypeError: If the input is not a list or contains non-integer elements. - ValueError: If the input list is empty. - - Examples: - >>> largest_number([0, 1, 9, 2, 6, 4]) - 9 - >>> largest_number([12]) - 12 - >>> largest_number([8, -1, -8, 5]) - 8 - >>> largest_number([-9, -1, -6, -5]) - -1 - >>> largest_number([0, 0]) - 0 - >>> largest_number([]) # Raises ValueError - Traceback (most recent call last): - ... - ValueError: The list must not be empty. - >>> largest_number(["-5", 5, "0"]) # Raises TypeError - Traceback (most recent call last): - ... - TypeError: All elements in the list must be integers. - >>> largest_number(42) # Raises TypeError - Traceback (most recent call last): - ... - TypeError: The input must be a list. - >>> largest_number([2**32, 2**16, 2**8, 1]) - 4294967296 - """ - - # Ensure the input is a list of integers - if not isinstance(list_numbers, list): - raise TypeError("The input must be a list.") - if not list_numbers: - raise ValueError("The list must not be empty.") - if not all(isinstance(i, int) for i in list_numbers): - raise TypeError("All elements in the list must be integers.") - - return max(list_numbers) diff --git a/solutions/merge_dictionaries.py b/solutions/merge_dictionaries.py deleted file mode 100644 index 7b07cd3db..000000000 --- a/solutions/merge_dictionaries.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -This module contains the implementation of the `merge_dictionaries` function. - -The `merge_dictionaries` function allows merging two dictionaries into one, -with support for resolving key conflicts through a custom resolution function. - -Created on 03 01 2025 -@author: Frankline Ambetsa -""" - - -def merge_dictionaries(dict1, dict2, conflict_resolution=None): - """ - Merge two dictionaries into one. - - If keys conflict, a conflict resolution function can be provided - to decide which value to keep. If no function is provided, the value - from `dict2` will overwrite the value from `dict1`. - - Parameters: - dict1 (dict): The first dictionary. - dict2 (dict): The second dictionary. - conflict_resolution (function, optional): A function that takes - two arguments (value1, value2) and returns the resolved value. - - Returns: - dict: A merged dictionary. - - Raises: - AssertionError: If `dict1` or `dict2` is not a dictionary. - AssertionError: If `conflict_resolution` is not callable when provided. - - Examples: - >>> merge_dictionaries({'a': 1}, {'a': 2, 'b': 3}) - {'a': 2, 'b': 3} - >>> merge_dictionaries({'a': 1}, {'a': 2, 'b': 3}, max) - {'a': 2, 'b': 3} - >>> merge_dictionaries({'x': 1}, {'y': 2}) - {'x': 1, 'y': 2} - """ - # Defensive assertions - assert isinstance(dict1, dict), "dict1 must be a dictionary." - assert isinstance(dict2, dict), "dict2 must be a dictionary." - if conflict_resolution is not None: - assert callable(conflict_resolution), ( - "conflict_resolution must be a callable function." - ) - - merged = dict1.copy() # Start with a copy of the first dictionary - - for key, value in dict2.items(): - if key in merged and conflict_resolution: - # Resolve conflict using the provided function - merged[key] = conflict_resolution(merged[key], value) - else: - # Add or overwrite key with dict2's value - merged[key] = value - - return merged diff --git a/solutions/sum_of_list.py b/solutions/sum_of_list.py deleted file mode 100644 index 1e722050c..000000000 --- a/solutions/sum_of_list.py +++ /dev/null @@ -1,42 +0,0 @@ -""" -This function asks the user to enter numbers and return the sum of the numbers . - -Created on 05 01 2025 -@author: Eman Alfalouji. - -""" - -from typing import List, Union - - -def sum_of_list(numbers: List[Union[int, float]]) -> Union[int, float]: - """ - Calculate the sum of a list of numbers. - - Args: - numbers (list): A list of numbers (int or float). - - Returns: - int/float: The sum of the numbers in the list. - - Raises: - TypeError: If the input is not a list. - ValueError: If any element in the list is not an int or float. - - Examples : - >>> sum_of_list([1,2,5]) - The sum of the list is:8 - >>> sum_of_list([-1,-2,-5]) - The sum of the list is:-8 - >>> sum_of_list([-1,-2,"l"]) - Please enter valid numbers separated by spaces. - >>> sum_of_list(["l"]) - Please enter valid numbers separated by spaces. - >>> sum_of_list([]) - Please enter valid numbers separated by spaces. - """ - if not isinstance(numbers, list): - raise TypeError("Input must be a list of numbers.") - if not all(isinstance(num, (int, float)) for num in numbers): - raise ValueError("All elements in the list must be int or float.") - return sum(numbers) diff --git a/solutions/tests/README.md b/solutions/tests/README.md index 647035671..72a49f6c2 100644 --- a/solutions/tests/README.md +++ b/solutions/tests/README.md @@ -1,34 +1,29 @@ # Tests -## Tests for Dictionary Merging with Conflict Resolution - -This folder contains unit tests for the dictionary merging and conflict resolution - functionalities implemented in the `merge_dictionaries.py` script. +This folder contains unit tests for the challenges in the `solutions` module. ## Purpose -The purpose of the tests is to ensure that the dictionary merging logic, -including handling conflicts, works as expected. The tests verify that: - -- Dictionaries are merged correctly. -- Conflict resolution logic (e.g., using the `max` function) - is applied properly when keys conflict. -- Edge cases and various scenarios are handled appropriately. +The purpose of these tests is to ensure the functionality of +the implemented solutions, including handling edge cases and verifying correct behavior. -## Test File Structure +## Test Files -- `test_merge_dictionaries.py`: Contains unit tests for the `merge_dictionaries` - function. It includes tests for: - - Default dictionary merging (where dictionary B overwrites dictionary A). - - Conflict resolution merging (using the `max` value). - - Various edge cases, such as empty dictionaries, overlapping keys, and more. +- **`test_merge_dictionaries.py`**: + - Tests for the Merge Dictionaries challenge. + - Verifies: + - Default dictionary merging (where dictionary B overwrites dictionary A). + - Conflict resolution merging (e.g., using the `max` value). + - Handling of edge cases, such as empty dictionaries and overlapping keys. -## Running the Tests +- **`test_anagram_finder.py`**: + - Tests for the Anagram Finder challenge. + - Ensures the function correctly identifies whether two strings are anagrams, + - handling both typical and edge cases. -To run the tests, follow these steps: +## Running Tests -1. **Navigate to the project root directory** (where the `solutions` folder is located): +Run the following command to execute all tests: - ```bash - cd /path/to/your/project - python -m unittest discover -s solutions/tests +```bash +python -m unittest discover -s solutions/tests -p "test_*.py" diff --git a/solutions/tests/test_Remove_Duplicate.py b/solutions/tests/test_Remove_Duplicate.py deleted file mode 100644 index e10ae1267..000000000 --- a/solutions/tests/test_Remove_Duplicate.py +++ /dev/null @@ -1,43 +0,0 @@ -""" -Test module for Remove Duplicate function. - -Created on 2024-01-10 -Author: Safaa Osman - -""" - -import unittest - -from ..Remove_Duplicates import Remove_Duplicates - - -class TestRemoveDuplicates(unittest.TestCase): - """Test the Remove_Duplicates function - some tests are buggy!""" - - def test_empty_list(self): - """It should return [] for an empty list""" - self.assertEqual(Remove_Duplicates([]), []) - - def test_no_duplicates(self): - """It should return the same list for list without duplicates""" - self.assertEqual(Remove_Duplicates([1, 2, 3]), [1, 2, 3]) - - def test_not_list(self): - """It should raise AssertionError for non-list input""" - with self.assertRaises(AssertionError): - Remove_Duplicates("123") - - def test_All_duplicates(self): - """It should return the list of one item that duplicates""" - self.assertEqual(Remove_Duplicates([1, 1, 1, 1, 1, 1]), [1]) - - def test_list_with_duplicates(self): - """It should return the list without duplicates""" - self.assertEqual(Remove_Duplicates([1, 1, 2, 2, 3, 4]), [1, 2, 3, 4]) - - def test_Mix_types_of_elements(self): - """It should return the list of elements without duplicates""" - self.assertEqual( - Remove_Duplicates([1, "Safaa", 3.5, "Safaa", "safaa", 3.5]), - [1, "Safaa", 3.5, "safaa"], - ) diff --git a/solutions/tests/test_Swap_letters.py b/solutions/tests/test_Swap_letters.py deleted file mode 100644 index f4cb40d90..000000000 --- a/solutions/tests/test_Swap_letters.py +++ /dev/null @@ -1,49 +0,0 @@ -""" -Created on 08/01/2024 - -@author: Tibyan Khalid - -This file contains boundary cases and defensive assertion tests for the function Swap_letters. -""" - -import unittest - -from ..Swap_letters import Swap_letters - - -class TestSwapLettersFunctionality(unittest.TestCase): - """Test cases for validating the behavior of the Swap_letters function, - including edge cases and defensive assertions.""" - - def test_lowercase_all(self): - "Testing from lowercase to uppercase" - self.assertEqual(Swap_letters("tibyan"), "TIBYAN") - - def test_uppercase_all(self): - "Testing from uppercase to lowercase" - self.assertEqual(Swap_letters("TIBYAN"), "tibyan") - - def test_mixed_cases(self): - "Testing mixed spaces" - self.assertEqual(Swap_letters("TiByAn"), "tIbYaN") - - def test_non_string_entry(self): - "Raise an error if entry is not a string" - with self.assertRaises(AssertionError): - Swap_letters(57) - - def test_spaces(self): - "Handle spaces correctly" - self.assertEqual(Swap_letters("Hello World"), "hELLO wORLD") - - def test_empty_string(self): - "Test for an empty string input" - self.assertEqual(Swap_letters(""), "") - - def test_special_characters(self): - "Test for special characters input" - self.assertEqual(Swap_letters("1234!@#$"), "1234!@#$") - - -if __name__ == "__main__": - unittest.main() diff --git a/solutions/tests/test_Time_Conversion.py b/solutions/tests/test_Time_Conversion.py deleted file mode 100644 index d8078193d..000000000 --- a/solutions/tests/test_Time_Conversion.py +++ /dev/null @@ -1,69 +0,0 @@ -""" -Test module for Time Conversion function. -Contains intentionally buggy tests for debugging practice. - -Created on 2024-01-09 -Author: Safaa Osman -""" - -import unittest -from ..Time_Conversion import Time_Conversion - - -class TestTimeConversion(unittest.TestCase): - """Test suite for the Time Conversion function""" - - def test_equal_minutes_hours(self): - """It should return the time conversion properly""" - self.assertEqual(Time_Conversion("12:12"), "20:12") - - def test_regular_time(self): - """It should return the time conversion properly""" - self.assertEqual(Time_Conversion("08:00"), "16:00") - - # Boundary cases - - def test_minimum_time(self): - """It should return the time conversion properly""" - self.assertEqual(Time_Conversion("00:00"), "08:00") - - def test_maximum_time(self): - """It should return the time conversion properly""" - self.assertEqual(Time_Conversion("23:59"), "07:59") - - # Defensive cases - - def test_not_string(self): - """It should raise AssertionError for input not string""" - with self.assertRaises(AssertionError): - Time_Conversion(1230) - - def test_hours_out_of_range(self): - """It should raise ValueError for hours are out of range""" - with self.assertRaises(ValueError): - Time_Conversion("25:30") - - def test_minutes_out_of_range(self): - """It should raise ValueError for minutes are out of range""" - with self.assertRaises(ValueError): - Time_Conversion("12:69") - - def test_empty_string(self): - """It should raise AssertionError for string is empty""" - with self.assertRaises(AssertionError): - Time_Conversion("") - - def test_mix_types(self): - """It should raise AssertionError for string is mix types""" - with self.assertRaises(AssertionError): - Time_Conversion("hg:45") - - def test_invalid_minutes(self): - """It should raise ValueError for minutes are out of range""" - with self.assertRaises(ValueError): - Time_Conversion("00:60") - - def test_invalid_hours(self): - """It should raise ValueError for minutes are out of range""" - with self.assertRaises(ValueError): - Time_Conversion("24:00") diff --git a/solutions/tests/test_anagram_finder.py b/solutions/tests/test_anagram_finder.py new file mode 100644 index 000000000..fe04ce5cf --- /dev/null +++ b/solutions/tests/test_anagram_finder.py @@ -0,0 +1,78 @@ +""" +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. + +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 anagram_finder function.""" + + def test_anagrams(self): + """Test cases for valid anagrams.""" + 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(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(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(anagram_finder("abc", "ab")) + self.assertFalse(anagram_finder("abcd", "abcde")) + + def test_empty_strings(self): + """Test edge cases with empty strings.""" + self.assertTrue( + anagram_finder("", "") + ) # Both empty strings should be considered anagrams + with self.assertRaises(AssertionError): + anagram_finder( + "a", "" + ) # A non-empty string and empty string shouldn't be anagrams + with self.assertRaises(AssertionError): + 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(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): + anagram_finder(123, "silent") # Non-string input + with self.assertRaises(AssertionError): + anagram_finder("listen", 123) # Non-string input + + with self.assertRaises(AssertionError): + anagram_finder("a", "") # Empty string as second argument + with self.assertRaises(AssertionError): + anagram_finder("", "b") # Empty string as first argument + + +if __name__ == "__main__": + # Run the tests + unittest.main() diff --git a/solutions/tests/test_calculate_square_area.py b/solutions/tests/test_calculate_square_area.py deleted file mode 100644 index ebfbf5ee7..000000000 --- a/solutions/tests/test_calculate_square_area.py +++ /dev/null @@ -1,59 +0,0 @@ -# !/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Test module for square_area function. - -Test categories: -- Standard cases: positive numbers -- Edge cases: numbers that are positive but less than 1 -- Defensive cases: wrong input types, value that is zero, and less than zero - -Created on 07 01 2024 -Author: Kareiman Altayeb -""" - -import unittest - -from solutions.calculate_square_area import calculate_square_area - - -class CalculateSquareArea(unittest.TestCase): - """Tests the calculate_square_area function""" - - def test_positive_integers(self): - """It should return value ^ 2""" - self.assertEqual(calculate_square_area(7), 49) - - def test_positive_float(self): - """It should return value ^ 2""" - self.assertEqual(calculate_square_area(5.5), 30.25) - - def test_bigger_values(self): - """It should return the value ^ 2""" - self.assertEqual(calculate_square_area(2222), 4937284) - - # Edge cases - - def test_small_values(self): - """It should return the value ^ 2""" - self.assertEqual(calculate_square_area(0.75), 0.5625) - - # Defensive cases - - def test_string_entry(self): - """It should raise AssertionError if entry was text or letters""" - with self.assertRaises(AssertionError): - calculate_square_area("a") - - def test_value_zero(self): - """It should raise AssertionError if entry was zero""" - with self.assertRaises(AssertionError): - calculate_square_area(0) - - def test_value_negative(self): - """It should raise AssertionError if value was less than zero""" - with self.assertRaises(AssertionError): - calculate_square_area(-3) - - if __name__ == "__main__": - unittest.main() diff --git a/solutions/tests/test_check_number_type.py b/solutions/tests/test_check_number_type.py deleted file mode 100644 index ee39a41a1..000000000 --- a/solutions/tests/test_check_number_type.py +++ /dev/null @@ -1,58 +0,0 @@ -""" -Unit tests for the check_number_type function. - -Test categories: - - Standard cases: typical lists with different lengths - - Edge cases: empty lists, single element - - Defensive tests: wrong input types, assertions - - -Created on 05 01 2025 -@author: Eman Alfalouji -""" - -import unittest - -from solutions.check_number_type import check_number_type - - -class TestCheckNumberType(unittest.TestCase): - """Tests the check_number_type function.""" - - def test_even_number(self): - """It should identify even numbers.""" - self.assertEqual(check_number_type("22"), "The number is even") - - def test_odd_number(self): - """It should identify odd numbers.""" - self.assertEqual(check_number_type("15"), "The number is odd") - - def test_zero(self): - """It should identify zero as even.""" - self.assertEqual(check_number_type("0"), "The number is even") - - def test_negative_even_number(self): - """It should identify negative even numbers.""" - self.assertEqual(check_number_type("-4"), "The number is even") - - def test_negative_odd_number(self): - """It should identify negative odd numbers.""" - self.assertEqual(check_number_type("-7"), "The number is odd") - - def test_input_with_whitespace(self): - """It should handle inputs with leading/trailing whitespace.""" - self.assertEqual(check_number_type(" 8 "), "The number is even") - - def test_invalid_input(self): - """It should raise ValueError for invalid inputs.""" - with self.assertRaises(ValueError): - check_number_type("abc") - - def test_empty_input(self): - """It should raise ValueError for empty inputs.""" - with self.assertRaises(ValueError): - check_number_type("") - - -if __name__ == "__main__": - unittest.main() diff --git a/solutions/tests/test_convert_hours_to_minutes.py b/solutions/tests/test_convert_hours_to_minutes.py deleted file mode 100644 index ee34d7c6b..000000000 --- a/solutions/tests/test_convert_hours_to_minutes.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Unit tests for the convert_hours_to_minutes function. - -Test cases include: - - Valid inputs for standard calculations - - Boundary cases - - Defensive tests for invalid inputs - -Created on 2024-12-31 -Author: Azza -""" - -import unittest - -from solutions.convert_hours_to_minutes import convert_hours_to_minutes - - -class TestConvertHoursToMinutes(unittest.TestCase): - """Unit tests for the convert_hours_to_minutes function.""" - - def test_one_hour(self): - """It should return 60 minutes for 1 hour.""" - self.assertEqual(convert_hours_to_minutes(1), 60) - - def test_multiple_hours(self): - """It should return 300 minutes for 5 hours.""" - self.assertEqual(convert_hours_to_minutes(5), 300) - - def test_zero_hours(self): - """It should return 0 minutes for 0 hours.""" - self.assertEqual(convert_hours_to_minutes(0), 0) - - def test_large_number_of_hours(self): - """It should return 60000 minutes for 1000 hours.""" - self.assertEqual(convert_hours_to_minutes(1000), 60000) - - def test_negative_hours(self): - """It should raise an AssertionError for negative hours.""" - with self.assertRaises(AssertionError): - convert_hours_to_minutes(-5) - - def test_string_input(self): - """It should raise an AssertionError for string input.""" - with self.assertRaises(AssertionError): - convert_hours_to_minutes("3") - - def test_float_input(self): - """It should raise an AssertionError for float input.""" - with self.assertRaises(AssertionError): - convert_hours_to_minutes(2.5) - - def test_none_input(self): - """It should raise an AssertionError for None input.""" - with self.assertRaises(AssertionError): - convert_hours_to_minutes(None) - - def test_list_input(self): - """It should raise an AssertionError for list input.""" - with self.assertRaises(AssertionError): - convert_hours_to_minutes([1, 2]) - - -if __name__ == "__main__": - unittest.main() diff --git a/solutions/tests/test_convert_to_capital.py b/solutions/tests/test_convert_to_capital.py deleted file mode 100644 index 2fc8a8a83..000000000 --- a/solutions/tests/test_convert_to_capital.py +++ /dev/null @@ -1,55 +0,0 @@ -# !/usr/bin/env python3 -# -*- coding: utf-8 -*- - -""" -A module to test convert_to_capital function - -Test categories: - - Standard cases: Regular text with different length - - Edge cases: Mix of different data types - - Defensive tests: Empty input - -Created on 03 01 2025 - -@author: Kareiman Altayeb -""" - -import unittest - -# To test convert_to_capital -from solutions.convert_to_capital import convert_to_capital - - -class TestConvertCapitalLetters(unittest.TestCase): - "Tests convert_to_capital function" - - # Standard test cases - - def test_all_small_letters(self): - """It should convert all letters to capital""" - self.assertEqual(convert_to_capital("kareiman"), "KAREIMAN") - - def test_some_are_capital_letters(self): - """It should convert all letters to capital""" - self.assertEqual(convert_to_capital("kAREiMan"), "KAREIMAN") - - def test_full_sentence(self): - """It should convert all words to capital""" - self.assertEqual(convert_to_capital("happy new year"), "HAPPY NEW YEAR") - - # Edge cases - - def test_mixed_with_numbers(self): - """It should return the numbers the same""" - self.assertEqual(convert_to_capital("12345kareiman"), "12345KAREIMAN") - - def test_special_characters(self): - """It should return special characters the same""" - self.assertEqual(convert_to_capital("?!!!"), "?!!!") - - # Defensive tests - - def test_empty_entry(self): - """It should raise an error for space or empty entry""" - with self.assertRaises(AssertionError): - convert_to_capital("") diff --git a/solutions/tests/test_convert_to_uppercase.py b/solutions/tests/test_convert_to_uppercase.py deleted file mode 100644 index 682450133..000000000 --- a/solutions/tests/test_convert_to_uppercase.py +++ /dev/null @@ -1,55 +0,0 @@ -# !/usr/bin/env python3 -# -*- coding: utf-8 -*- - -""" -A module to test convert_to_uppercase function - -Test categories: - - Standard cases: Regular text with different length - - Edge cases: Mix of different data types - - Defensive tests: Empty input - -Created on 03 01 2025 - -@author: Kareiman Altayeb -""" - -import unittest - -# To test convert_to_uppercase -from solutions.convert_to_uppercase import convert_to_uppercase - - -class TestConvertToCapitalLetters(unittest.TestCase): - "Tests convert_to_capital function" - - # Standard test cases - - def test_all_small_letters(self): - """It should convert all letters to capital letter""" - self.assertEqual(convert_to_uppercase("kareiman"), "KAREIMAN") - - def test_some_are_capital_letters(self): - """It should convert all letters to capital letters""" - self.assertEqual(convert_to_uppercase("kAREiMan"), "KAREIMAN") - - def test_full_sentence(self): - """It should convert all words to capital letters""" - self.assertEqual(convert_to_uppercase("happy new year"), "HAPPY NEW YEAR") - - # Edge cases - - def test_mixed_with_numbers(self): - """It should return the numbers the same""" - self.assertEqual(convert_to_uppercase("12345kareiman"), "12345KAREIMAN") - - def test_special_characters(self): - """It should return special characters the same""" - self.assertEqual(convert_to_uppercase("?!!!"), "?!!!") - - # Defensive tests - - def test_empty_entry(self): - """It should raise an error for space or empty entry""" - with self.assertRaises(AssertionError): - convert_to_uppercase("") diff --git a/solutions/tests/test_is_palindrome.py b/solutions/tests/test_is_palindrome.py deleted file mode 100644 index 2713bdf41..000000000 --- a/solutions/tests/test_is_palindrome.py +++ /dev/null @@ -1,43 +0,0 @@ -""" -Created on 04/01/2025 - -@author: Tibyan Khalid -""" - -import unittest - -from ..is_palindrome import is_palindrome - - -class TestIsPalindrome(unittest.TestCase): - """Unittests for the is_palindrome function""" - - def test_palindrome(self): - self.assertEqual(is_palindrome("level"), "Palindrome") - - def test_not_palindrome(self): - self.assertEqual(is_palindrome("world"), "Not Palindrome") - - # Boundary Cases Tests - def test_empty_string(self): - "Empty string is considered a Palindrome" - self.assertEqual(is_palindrome(""), "Palindrome") - - def test_single_character(self): - "Any single character is a palindrome as it reads the same backward" - self.assertEqual(is_palindrome("t"), "Palindrome") - - def test_non_string_entry(self): - "Raise an error if entry is not a string" - with self.assertRaises(AssertionError): - is_palindrome(34) - - def test_upper_lower_cases(self): - "Case matters here, radar is a Palindrome but Radar is not" - self.assertEqual(is_palindrome("Radar"), "Not Palindrome") - self.assertEqual(is_palindrome("Radar".lower()), "Palindrome") - - def test_special_characters(self): - "Handles special characters correctly" - self.assertEqual(is_palindrome("t@a@t"), "Palindrome") - self.assertEqual(is_palindrome("a@b@c"), "Not Palindrome") diff --git a/solutions/tests/test_largest_number.py b/solutions/tests/test_largest_number.py deleted file mode 100644 index d855b6241..000000000 --- a/solutions/tests/test_largest_number.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Unit tests for the largest_number function. - -Test categories: -Standard cases: Typical lists with positive, negative, and mixed integers. -Edge cases: Empty lists, lists with a single element, lists with duplicate values. -Defensive tests: Non-list inputs (e.g., integers, strings), lists with non-integer elements, -assertions for invalid inputs. - -Created on 2025-01-11 -Author: Azza -""" - -import unittest - -from ..largest_number import largest_number - - -class TestLargestNumber(unittest.TestCase): - """Unit tests for the largest_number function.""" - - def test_standard_list(self): - """It should return 9 for [0, 1, 9, 2, 6, 4].""" - self.assertEqual(largest_number([0, 1, 9, 2, 6, 4]), 9) - - def test_single_element(self): - """It should return 12 for [12].""" - self.assertEqual(largest_number([12]), 12) - - def test_mixed_positive_and_negative(self): - """It should return 8 for [8, -1, -8, 5].""" - self.assertEqual(largest_number([8, -1, -8, 5]), 8) - - def test_all_negative_numbers(self): - """It should return -1 for [-9, -1, -6, -5].""" - self.assertEqual(largest_number([-9, -1, -6, -5]), -1) - - def test_all_zeros(self): - """It should return 0 for [0, 0].""" - self.assertEqual(largest_number([0, 0]), 0) - - def test_large_numbers(self): - """It should return 4294967296 for [2**32, 2**16, 2**8, 1].""" - self.assertEqual(largest_number([2**32, 2**16, 2**8, 1]), 2**32) - - def test_empty_list(self): - """It should raise ValueError for an empty list.""" - with self.assertRaises(ValueError): - largest_number([]) - - def test_non_list_input(self): - """It should raise TypeError for non-list input, e.g., 42.""" - with self.assertRaises(TypeError): - largest_number(42) - - def test_list_with_non_integer(self): - """It should raise TypeError for a list with non-integer elements.""" - with self.assertRaises(TypeError): - largest_number(["-5", 5, "0"]) - - -if __name__ == "__main__": - unittest.main() diff --git a/solutions/tests/test_merge_dictionaries.py b/solutions/tests/test_merge_dictionaries.py deleted file mode 100644 index e26e106b0..000000000 --- a/solutions/tests/test_merge_dictionaries.py +++ /dev/null @@ -1,83 +0,0 @@ -# solutions/tests/test_merge_dictionaries.py - -""" -Unit tests for the `merge_dictionaries` function. - -These tests ensure correct behavior of the `merge_dictionaries` function, -including standard merging, conflict resolution, edge cases, and input validation. - -Created on 03 01 2025 -@author: Frankline Ambetsa -""" - -import unittest -from solutions.merge_dictionaries import merge_dictionaries - - -class TestMergeDictionaries(unittest.TestCase): - """Unit tests for the `merge_dictionaries` function.""" - - def test_no_conflicts(self): - """It should merge dictionaries with no conflicting keys.""" - dict1 = {"a": 1, "b": 2} - dict2 = {"c": 3, "d": 4} - expected = {"a": 1, "b": 2, "c": 3, "d": 4} - self.assertEqual(merge_dictionaries(dict1, dict2), expected) - - def test_overwrite_conflicts(self): - """It should overwrite conflicting keys with values from dict2.""" - dict1 = {"a": 1, "b": 2} - dict2 = {"b": 3, "c": 4} - expected = {"a": 1, "b": 3, "c": 4} - self.assertEqual(merge_dictionaries(dict1, dict2), expected) - - def test_conflict_resolution_max(self): - """It should resolve conflicts using the max function.""" - dict1 = {"a": 1, "b": 5} - dict2 = {"b": 3, "c": 4} - expected = {"a": 1, "b": 5, "c": 4} - self.assertEqual(merge_dictionaries(dict1, dict2, max), expected) - - def test_conflict_resolution_min(self): - """It should resolve conflicts using the min function.""" - dict1 = {"a": 1, "b": 5} - dict2 = {"b": 3, "c": 4} - expected = {"a": 1, "b": 3, "c": 4} - self.assertEqual(merge_dictionaries(dict1, dict2, min), expected) - - def test_empty_dicts(self): - """It should return an empty dictionary when both inputs are empty.""" - dict1 = {} - dict2 = {} - expected = {} - self.assertEqual(merge_dictionaries(dict1, dict2), expected) - - def test_one_empty_dict(self): - """It should return the non-empty dictionary when one input is empty.""" - dict1 = {"a": 1, "b": 2} - dict2 = {} - expected = {"a": 1, "b": 2} - self.assertEqual(merge_dictionaries(dict1, dict2), expected) - - def test_only_conflicts(self): - """It should overwrite keys with values from dict2 for conflicting keys.""" - dict1 = {"a": 1} - dict2 = {"a": 2} - expected = {"a": 2} - self.assertEqual(merge_dictionaries(dict1, dict2), expected) - - def test_non_dict_inputs(self): - """It should raise a TypeError for non-dictionary inputs.""" - with self.assertRaises(AssertionError): - merge_dictionaries([], {"a": 1}) - with self.assertRaises(AssertionError): - merge_dictionaries({"a": 1}, 42) - - def test_invalid_conflict_resolution(self): - """It should raise a ValueError for non-callable conflict resolution.""" - with self.assertRaises(AssertionError): - merge_dictionaries({"a": 1}, {"a": 2}, conflict_resolution=42) - - -if __name__ == "__main__": - unittest.main() diff --git a/solutions/tests/test_sum_of_list.py b/solutions/tests/test_sum_of_list.py deleted file mode 100644 index 3c8efac3f..000000000 --- a/solutions/tests/test_sum_of_list.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -Unit tests for the sum_of_list function. - -Test categories: - - Standard cases: typical lists with positive, negative, and mixed numbers - - Edge cases: empty lists, single elements - - Defensive tests: wrong input types, invalid elements - -Created on 05 01 2025 -@author: Eman Alfalouji -""" - -import unittest - -from solutions.sum_of_list import sum_of_list - - -class TestSumOfList(unittest.TestCase): - """Tests the sum_of_list function.""" - - # Standard test cases - def test_positive_numbers(self): - """Test that the function correctly sums a list of positive integers.""" - self.assertEqual(sum_of_list([8, 7, 3, 4, 5]), 27) - - def test_negative_numbers(self): - """Test that the function correctly sums a list of negative integers.""" - self.assertEqual(sum_of_list([-1, -4, -7]), -12) - - def test_mixed_numbers(self): - """ - Test that the function correctly sums a list with both positive and negative numbers, - including floats. - """ - self.assertEqual(sum_of_list([1, -2, 3.5]), 2.5) - - # Edge cases - def test_empty_list(self): - """Test that the function returns 0 for an empty list.""" - self.assertEqual(sum_of_list([]), 0) - - def test_single_element(self): - """Test that the function returns the single element value when the list has only one number.""" - self.assertEqual(sum_of_list([10]), 10) - - # Defensive cases - def test_invalid_input_type(self): - """Test that the function raises a TypeError when the input is not a list.""" - with self.assertRaises(TypeError): - sum_of_list("not a list") - - def test_invalid_element_type(self): - """Test that the function raises a ValueError when the list contains non-numeric elements.""" - with self.assertRaises(ValueError): - sum_of_list([1, "two", 3]) - - -if __name__ == "__main__": - unittest.main() diff --git a/solutions/tests/test_word_frequency.py b/solutions/tests/test_word_frequency.py deleted file mode 100644 index 5381b5000..000000000 --- a/solutions/tests/test_word_frequency.py +++ /dev/null @@ -1,37 +0,0 @@ -# test_word_frequency.py -""" -This module contains unit tests for the word_frequency module. - -The tests verify the functionality of the count_word_frequency function, -which counts the frequency of words in a given text. -""" - -import unittest - -from ..word_frequency import count_word_frequency - - -class TestWordFrequency(unittest.TestCase): - """Test cases for the count_word_frequency function.""" - - def test_count_word_frequency(self): - """Test counting word frequency in a simple text.""" - text = "hello world hello" - expected_output = {"hello": 2, "world": 1} - self.assertEqual(count_word_frequency(text), expected_output) - - def test_empty_text(self): - """Test counting word frequency in an empty string.""" - text = "" - expected_output = {} - self.assertEqual(count_word_frequency(text), expected_output) - - def test_case_insensitive(self): - """Test counting word frequency with case-insensitive matching.""" - text = "Hello hello HeLLo" - expected_output = {"hello": 3} - self.assertEqual(count_word_frequency(text), expected_output) - - -if __name__ == "__main__": - unittest.main() diff --git a/solutions/word_frequency.py b/solutions/word_frequency.py deleted file mode 100644 index bb0f3e1fc..000000000 --- a/solutions/word_frequency.py +++ /dev/null @@ -1,38 +0,0 @@ -def count_word_frequency(text): - """ - Counts the frequency of each word in a given string. - - Args: - text (str): The input text to analyze. - - Returns: - dict: A dictionary where keys are words and values are their frequencies. - - Raises: - ValueError: If the input text is not a string. - - Examples: - >>> count_word_frequency("hello hello world") - {'hello': 2, 'world': 1} - - >>> count_word_frequency("apple banana apple") - {'apple': 2, 'banana': 1} - - >>> count_word_frequency("The quick brown fox jumps over the lazy dog") - {'the': 2, 'quick': 1, 'brown': 1, 'fox': 1, 'jumps': 1, 'over': 1, 'lazy': 1, 'dog': 1} - """ - if not isinstance(text, str): - raise ValueError("Input must be a string.") - - # Normalize case and split text into words - words = text.lower().split() - - # Remove punctuation from each word - cleaned_words = [word.strip('.,!?;:"()') for word in words] - - # Count word frequencies - word_counts = {} - for word in cleaned_words: - word_counts[word] = word_counts.get(word, 0) + 1 - - return word_counts