diff --git a/solutions/count_words.py b/solutions/count_words.py new file mode 100644 index 000000000..c2ef107ca --- /dev/null +++ b/solutions/count_words.py @@ -0,0 +1,35 @@ +""" +A module for counting words in a string. + +Module contents: + - count_words: counts the number of words in a string. + +Created on 01 01 2025 +@author: Raghad +""" + + +def count_words(text: str) -> int: + """Count the number of words in a given string. + + Parameters: + text: str, the input string to analyze + + Returns -> int: number of words in the text + + Raises: + AssertionError: if the argument is not a string + + >>> count_words("Hello World") + 2 + >>> count_words("Python programming is fun") + 4 + >>> count_words("") + 0 + """ + # Validate input + assert isinstance(text, str), "Input must be a string" + + # Split the text by whitespace and count the resulting parts + words = text.split() + return len(words) diff --git a/solutions/decimal_to_binary.py b/solutions/decimal_to_binary.py new file mode 100644 index 000000000..ba2f9e08e --- /dev/null +++ b/solutions/decimal_to_binary.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A function to convert decimal numbers to binary. + +Created on 1/1/2025 +@author: Heba Shaheen +""" + + +def decimal_to_binary(decimal_input: int) -> str: + """Give the binary number for a decimal + + Args: + decimal_input (int): Decimal number to be converted + + Returns: + str: Binary representation of the decimal number + + Raises: + AssertionError: if the input is not an integer + + >>> decimal_to_binary(10) + "1010" + + >>> decimal_to_binary(20) + "10100" + + >>> decimal_to_binary(255) + "11111111" + """ + # Handle the edge case for 0 + assert isinstance(decimal_input, int), "The input should be integer" + assert decimal_input >= 0, "Give a positive input" + if decimal_input == 0: + return "0" + binary = "" + while decimal_input > 0: + binary = str(decimal_input % 2) + binary + decimal_input //= 2 + return binary diff --git a/solutions/is_palindrome.py b/solutions/is_palindrome.py new file mode 100644 index 000000000..61ee8e2de --- /dev/null +++ b/solutions/is_palindrome.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for checking if a given string is a palindrome (reads the same backward as forward) + +Module contents: + - palindrome: input string is palindrome if it reads the same backward as forward + +Created on 30.12.2024 +@author: Saad M. Ashour +""" + + +def is_palindrome(input_string: str) -> bool: + """ + Check if a given string is a palindrome. + + A palindrome is a word, phrase, number, or other sequence of characters + that reads the same forward and backward, ignoring spaces, punctuation, + and case sensitivity. + + Parameters: + input_string (str): The input string to be checked. + + Returns: + bool: True if the input string is a palindrome, False otherwise. + + Examples: + >>> is_palindrome("A man, a plan, a canal, Panama") + True + >>> is_palindrome("hello") + False + >>> is_palindrome("Madam") + True + """ + # AssertionError: Input must be a string + assert isinstance(input_string, str), "Input must be a string" + + # Remove non-alphanumeric characters and convert to lowercase + cleaned = "".join(char.lower() for char in input_string if char.isalnum()) + + # Check if the cleaned string is equal to its reverse + return cleaned == cleaned[::-1] diff --git a/solutions/remove_duplicates.py b/solutions/remove_duplicates.py new file mode 100644 index 000000000..3b72fd373 --- /dev/null +++ b/solutions/remove_duplicates.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A Function for removing the duplicates items in a list. + +Created on 2024-12-30 +Author: Heba Shaheen +""" + + +def remove_duplicates(nums: list) -> list: + """ + Given a list, return a new list without any repeated values. + The function goes item by item; if an item is not in the result list, + it appends it; otherwise, it skips it. + + Args: + nums (list): The list from which duplicates will be removed. + + Returns: + list: A list without duplicates. + Raises: + AssertionError: If the input not a list. + + >>> remove_duplicates([2, 4, 2, 5, 5, 7, 2, 6]) + [2, 4, 5, 7, 6] + + >>> remove_duplicates(["a", "v", "e", "e", "q", "v", "q", "a"]) + ['a', 'v', 'e', 'q'] + + >>> remove_duplicates(["Heba", "Noor", "Heba", "Noor"]) + ['Heba', 'Noor'] + """ + assert isinstance(nums, list), "The input should be a list" + result = [] # List to store the result without duplicates + + for num in nums: + if num not in result: + result.append(num) # Add the number to the result list + return result diff --git a/solutions/tests/test_count_words b/solutions/tests/test_count_words new file mode 100644 index 000000000..1429ea00c --- /dev/null +++ b/solutions/tests/test_count_words @@ -0,0 +1,42 @@ +""" +A module for testing count_words.py + +Module contents: + - Unit Test cases for function count_words + +Created on 01 01 2025 +@author: Raghad +""" + +import unittest +from solutions.count_words import count_words + + +class TestCountWords(unittest.TestCase): + def test_empty_string(self): + """Test with an empty string""" + self.assertEqual(count_words(""), 0) + + def test_single_word(self): + """Test with a single word""" + self.assertEqual(count_words("hello"), 1) + + def test_multiple_words(self): + """Test with multiple words""" + self.assertEqual(count_words("Hello, world!"), 2) + + def test_extra_spaces(self): + """Test with extra spaces""" + self.assertEqual(count_words(" Hello world "), 2) + + def test_numbers_and_words(self): + """Test with a mix of numbers and words""" + self.assertEqual(count_words("123 hello 456 world"), 4) + + def test_special_characters(self): + """Test with special characters""" + self.assertEqual(count_words("!@# $%^ &*()"), 3) + + +if __name__ == "__main__": + unittest.main() diff --git a/solutions/tests/test_decimal_to_binary.py b/solutions/tests/test_decimal_to_binary.py new file mode 100644 index 000000000..a2635e9b6 --- /dev/null +++ b/solutions/tests/test_decimal_to_binary.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Unit tests for decimal_to_binary function. + +@author: Heba Shaheen +""" + +import unittest + +from ..decimal_to_binary import decimal_to_binary + + +class TestDecimalToBinary(unittest.TestCase): + """Unit tests for decimal_to_binary function.""" + + def test_number_0(self): + """It should return "0" as binary""" + actual = decimal_to_binary(0) + expected = "0" + self.assertEqual(actual, expected) + + def test_number_2(self): + """It should return "10" as binary""" + actual = decimal_to_binary(2) + expected = "10" + self.assertEqual(actual, expected) + + def test_number_5(self): + """It should return "101" as binary""" + actual = decimal_to_binary(5) + expected = "101" + self.assertEqual(actual, expected) + + def test_number_15(self): + """It should return "1111" as binary""" + actual = decimal_to_binary(15) + expected = "1111" + self.assertEqual(actual, expected) + + def test_non_integer_input(self): + """It should raise an assertion error if the argument is not an integer""" + with self.assertRaises(AssertionError): + decimal_to_binary("1") + + def test_negative_input(self): + """It should raise an assertion error if the argument is negative""" + with self.assertRaises(AssertionError): + decimal_to_binary(-3) diff --git a/solutions/tests/test_is_palindrome.py b/solutions/tests/test_is_palindrome.py new file mode 100644 index 000000000..1f1c8d4b8 --- /dev/null +++ b/solutions/tests/test_is_palindrome.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Unit tests for is_palindrome function. + +@author: Saad M. Ashour +""" + +import unittest + +from ..is_palindrome import is_palindrome + + +class TestIsPalindrome(unittest.TestCase): + """ + Unit tests for the is_palindrome function. + + These tests check various cases to ensure that the is_palindrome function correctly + identifies palindromes, considering case insensitivity, non-alphanumeric characters, + and other edge cases. + """ + + def test_palindrome(self): + """ + Test cases where the string is a palindrome. + """ + actual = is_palindrome("A man, a plan, a canal, Panama") + self.assertTrue(actual) + + def test_non_palindrome(self): + """ + Test cases where the string is not a palindrome. + """ + actual = is_palindrome("hello") + self.assertFalse(actual) + + def test_empty_string(self): + """ + Test case where the input is an empty string, which is considered a palindrome. + """ + actual = is_palindrome("") + self.assertTrue(actual) + + def test_single_character(self): + """ + Test case where the input is a single character, which is always a palindrome. + """ + actual = is_palindrome("a") + self.assertTrue(actual) + + def test_only_non_alphanumeric(self): + """ + Test case where the input contains only non-alphanumeric characters. + The function should ignore them and return True for empty string. + """ + actual = is_palindrome("!@#$$@!") + self.assertTrue(actual) + + +if __name__ == "__main__": + unittest.main() diff --git a/solutions/tests/test_remove_duplicates.py b/solutions/tests/test_remove_duplicates.py new file mode 100644 index 000000000..33bcd99e4 --- /dev/null +++ b/solutions/tests/test_remove_duplicates.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Test module for remove_duplicates function. + +Created on 2024-12-30 +Author: Heba Shaheen +""" + +import unittest + +from ..remove_duplicates import remove_duplicates + + +class TestRemoveDuplicates(unittest.TestCase): + """Test remove_duplicates function""" + + # Standard test cases + def test_numbers_list(self): + """It should remove duplicates numbers""" + self.assertEqual(remove_duplicates([1, 2, 3, 2, 3, 4]), [1, 2, 3, 4]) + + def test_letters_list(self): + """It should remove duplicates letters""" + self.assertEqual( + remove_duplicates(["a", "v", "e", "e", "q"]), ["a", "v", "e", "q"] + ) + + def test_mix_list(self): + """It should remove duplicates items""" + self.assertEqual( + remove_duplicates([1, 2, 3, "e", 2, 1, "e", 5, "a"]), [1, 2, 3, "e", 5, "a"] + ) + + # Edge cases + def test_empty_list(self): + """It should return empty list""" + self.assertEqual(remove_duplicates([]), []) + + # Defensive tests + def test_invalid_type(self): + """It should raise AssertionError if numbers is not a list""" + with self.assertRaises(AssertionError): + remove_duplicates("1, 2, 2") + + +if __name__ == "__main__": + unittest.main()