diff --git a/solutions/count_vowels.py b/solutions/count_vowels.py new file mode 100644 index 000000000..7d7328559 --- /dev/null +++ b/solutions/count_vowels.py @@ -0,0 +1,47 @@ +""" +This module provides a function to count the number of vowels in a given text. +The vowels here are a,e,i,o,u,A,E,I,O,U. + +Function: +- count_vowels: Counts vowels in a provided string. + +Raises: + TypeError: If the input `s` is not a string. + ValueError: If the input `s` is an empty string. + +Example: + >>> vowel_counter("Deadline") + 4 +""" + + +def count_vowels(s) -> int: + """ + Counts the number of vowels in the given string. + + Parameters: + s (str): The string in which to count vowels. + + The vowels are "a,e,i,o,u,A,E,I,O,U" + + Returns: + int: The number of vowels in the string. + + Example: + >>> count_vowels("hello") + 2 + >>> count_vowels("Nelsona") + 3 + >>> count_vowels("This is amazing.") + 5 + """ + # Defensive assertion: Ensure the input is a string + if not isinstance(s, str): + raise TypeError("Input must be a string") + + # Defensive assertion: Ensure the string is not empty + if not s: + raise ValueError("Input string cannot be empty") + + vowels = "aeiouAEIOU" # Define vowels (both lowercase and uppercase) + return sum(1 for char in s if char in vowels) diff --git a/solutions/fizz_buzz.py b/solutions/fizz_buzz.py new file mode 100644 index 000000000..36daead22 --- /dev/null +++ b/solutions/fizz_buzz.py @@ -0,0 +1,61 @@ +""" +This module provides a function that generates a list of numbers from 1 to n +with specific rules for multiples of 3 and 5. + +For each number in the range: +- For multiples of 3, "Fizz" is added instead of the number. +- For multiples of 5, "Buzz" is added instead of the number. +- For multiples of both 3 and 5, "FizzBuzz" is added instead of the number. + +Features: +- Input validation to ensure that the input is a positive integer. +- Customizable output format (e.g., changing the words "Fizz" and "Buzz" + to user-defined strings). +- Ability to generate results as a string instead of a list. + +Example: +>>> fizz_buzz(15) +[1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, + 14, 'FizzBuzz'] +""" + + +def fizz_buzz(n: int) -> list: + """ + Generates a list of numbers from 1 to n with the following rules: + - For multiples of 3, "Fizz" is added instead of the number. + - For multiples of 5, "Buzz" is added instead of the number. + - For multiples of both 3 and 5, "FizzBuzz" is added instead of the number. + + Parameters: + n (int): The upper limit of the range (inclusive) to generate. + + Returns: + list: A list containing the numbers and/or string representations according + to the rules. + + Raises: + TypeError: If the input is not an integer. + ValueError: If the input is less than 1. + + Example: + >>> fizz_buzz(10) + [1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz'] + + """ + # Defensive assertions + if not isinstance(n, int): + raise TypeError("Input must be an integer.") + if n < 1: + raise ValueError("Input must be greater than or equal to 1.") + results = [] # Initialize an empty list to store the results + for i in range(1, n + 1): + if i % 3 == 0 and i % 5 == 0: + results.append("FizzBuzz") # Append "FizzBuzz" for multiples of both 3 and 5 + elif i % 3 == 0: + results.append("Fizz") # Append "Fizz" for multiples of 3 + elif i % 5 == 0: + results.append("Buzz") # Append "Buzz" for multiples of 5 + else: + results.append(i) # Append the number itself if not a multiple of 3 or 5 + return results # Return the list of results diff --git a/solutions/reverse_string.py b/solutions/reverse_string.py new file mode 100644 index 000000000..cc8a98ae8 --- /dev/null +++ b/solutions/reverse_string.py @@ -0,0 +1,43 @@ +""" +This module provides a function to reverse an inputed string. + +Function: + reverse_string(s: str) -> str: + Reverses the input string and returns the reversed one. + +Features: +- Simple and efficient string reversal. +- Built-in error handling for invalid inputs. + +Raises: + TypeError: If the input `s` is not a string. + ValueError: If the input `s` is an empty string. +Example: + >>> reverse_string("Deadline") + enildaeD +""" + + +def reverse_string(s: str) -> str: + """ + Reverses the given string. + + Parameters: + s (str): The string to be reversed. + + Returns: + str: The reversed string. + + Example: + >>> reverse_string("hello") + 'olleh' + >>> reverse_string("12345") + '54321' + """ + # Defensive assertion: Ensure the input is a string + if not isinstance(s, str): + raise TypeError("Input must be a string") + # Defensive assertion: Ensure the string is not empty + if not s: + raise ValueError("Input string cannot be empty") + return s[::-1] # Return the reversed string using slicing diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py new file mode 100644 index 000000000..8e488792f --- /dev/null +++ b/solutions/tests/test_count_vowels.py @@ -0,0 +1,75 @@ +""" +This module contains unit tests for the count_vowels module. +It includes test cases for the following function: +- count_vowels: Test the function that counts vowels in a string. + +Tests cover various cases including normal strings, empty strings, and case insensitivity. + +Usage: + Run tests using unittest framework: + >>> python -m unittest test_vowel_counter.py +""" + +import unittest + +from solutions.count_vowels import count_vowels # Import the count_vowels function + + +class TestCountVowels(unittest.TestCase): + """Test cases for the count_vowels function. + + This class contains unit tests for the count_vowels function to ensure + that it accurately counts the number of vowels in various input strings. + """ + + def test_count_vowels_normal(self): + """Test counting vowels in a normal string. + + This test checks that the function correctly counts the vowels in a + typical string with mixed characters. + """ + self.assertEqual(count_vowels("Nagham"), 2) + + def test_count_vowels_no_vowels(self): + """Test counting vowels in a string with no vowels. + + This test checks that the function returns 0 when there are no vowels + in the input string. + """ + self.assertEqual(count_vowels("bcdfghjklmnpqrstvwxyz"), 0) + + def test_count_vowels_case_insensitive(self): + """Test counting vowels in a case-insensitive manner. + + This test verifies that the function counts both uppercase and lowercase + vowels correctly. + """ + self.assertEqual(count_vowels("AbEcIdOfUg"), 5) + + def test_count_vowels_with_spaces(self): + """Test counting vowels in a string with spaces. + + This test checks that the function correctly counts vowels in a string + that contains spaces and punctuation. + """ + self.assertEqual(count_vowels("Hello World!"), 3) + + # Defensive assertion tests + def test_invalid_input_type_integer(self): + """Test that the function raises a TypeError for non-string input (integer).""" + with self.assertRaises(TypeError): + count_vowels(12345) + + def test_invalid_input_type_list(self): + """Test that the function raises a TypeError for non-string input (list).""" + with self.assertRaises(TypeError): + count_vowels(["a", "b", "c"]) + + def test_empty_string(self): + """Test that the function raises a ValueError for an empty string.""" + with self.assertRaises(ValueError): + count_vowels("") + + +if __name__ == "__main__": + unittest.main() diff --git a/solutions/tests/test_fizz_buzz.py b/solutions/tests/test_fizz_buzz.py new file mode 100644 index 000000000..ab526fdaf --- /dev/null +++ b/solutions/tests/test_fizz_buzz.py @@ -0,0 +1,77 @@ +""" +Unit tests for the fizz_buzz function from the solutions.fizz_buzz module. + +This class uses the unittest framework to validate the behavior of the fizz_buzz function +across various input values, ensuring it produces the correct output lists. Tests include +cases for n = 1, 3, 5, 15, and additional edge cases to comprehensively test the function. +""" + +import unittest +from solutions.fizz_buzz import fizz_buzz + + +class TestFizzBuzz(unittest.TestCase): + """Test cases for the fizz_buzz function. + + This class contains unit tests for the fizz_buzz function to ensure + that it produces the expected output for various input values. + """ + + def test_fizzbuzz_15(self): + """Test FizzBuzz for n = 15.""" + expected = [ + 1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", + "Buzz", 11, "Fizz", 13, 14, "FizzBuzz" + ] + self.assertEqual(fizz_buzz(15), expected) + + def test_fizzbuzz_3(self): + """Test FizzBuzz for n = 3.""" + expected = [1, 2, "Fizz"] + self.assertEqual(fizz_buzz(3), expected) + + def test_fizzbuzz_5(self): + """Test FizzBuzz for n = 5.""" + expected = [1, 2, "Fizz", 4, "Buzz"] + self.assertEqual(fizz_buzz(5), expected) + + def test_fizzbuzz_1(self): + """Test FizzBuzz for n = 1.""" + expected = [1] + self.assertEqual(fizz_buzz(1), expected) + + def test_fizzbuzz_zero(self): + """Test FizzBuzz for n = 0.""" + with self.assertRaises(ValueError): + fizz_buzz(0) + + def test_fizzbuzz_negative(self): + """Test FizzBuzz for negative n.""" + with self.assertRaises(ValueError): + fizz_buzz(-5) + + def test_fizzbuzz_non_integer(self): + """Test FizzBuzz for non-integer n.""" + non_integers = [3.5, "string", None, [], {}, (), 2.0] + for value in non_integers: + with self.assertRaises(TypeError): + fizz_buzz(value) + + def test_fizzbuzz_large_number(self): + """Test FizzBuzz for a larger number n = 30.""" + expected = [ + 1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", + "Buzz", 11, "Fizz", 13, 14, "FizzBuzz", 16, + 17, "Fizz", 19, "Buzz", "Fizz", 22, 23, "Fizz", + "Buzz", 26, "Fizz", 28, 29, "FizzBuzz" + ] + self.assertEqual(fizz_buzz(30), expected) + + def test_fizzbuzz_edge_case(self): + """Test FizzBuzz for n = 2.""" + expected = [1, 2] + self.assertEqual(fizz_buzz(2), expected) + + +if __name__ == "__main__": + unittest.main() diff --git a/solutions/tests/test_reverse_string.py b/solutions/tests/test_reverse_string.py new file mode 100644 index 000000000..09e038f18 --- /dev/null +++ b/solutions/tests/test_reverse_string.py @@ -0,0 +1,78 @@ +""" +Unit tests for the `reverse_string` function. + +This module tests the `reverse_string` function, which reverses an input string. +It includes various test cases to ensure that the function handles: +- Normal strings +- Strings containing numbers +- Strings with special characters +- Single characters +- Palindromes +- Strings with spaces +- Extremely long strings +It also checks that a ValueError is raised for empty strings and that a TypeError is raised for non-string inputs. +""" + +import unittest +from solutions.reverse_string import reverse_string + + +class TestReverseString(unittest.TestCase): + """Test cases for the reverse_string function. + + This class contains unit tests for the reverse_string function to ensure + that it correctly reverses strings under various scenarios. + """ + + def test_reverse_normal(self): + """Test reversing a normal string.""" + self.assertEqual(reverse_string("hello"), "olleh") + + def test_reverse_single_character(self): + """Test reversing a single character string.""" + self.assertEqual(reverse_string("a"), "a") + + def test_reverse_palindrome(self): + """Test reversing a palindrome.""" + self.assertEqual(reverse_string("madam"), "madam") + + def test_reverse_spaces(self): + """Test reversing a string with spaces.""" + self.assertEqual(reverse_string("hello world"), "dlrow olleh") + + def test_numbers_in_string(self): + """Test reversing a string containing numbers.""" + self.assertEqual(reverse_string("12345"), "54321") + + def test_special_characters(self): + """Test reversing a string with special characters.""" + self.assertEqual(reverse_string("!@#$"), "$#@!") + + def test_long_string(self): + """Test reversing an extremely long string.""" + long_string = "a" * 10000 + self.assertEqual(reverse_string(long_string), long_string[::-1]) + + def test_reverse_empty(self): + """Test that an empty string raises a ValueError.""" + with self.assertRaises(ValueError): + reverse_string("") # This input should raise a ValueError + + def test_integer_input(self): + """Test that an integer input raises a TypeError.""" + with self.assertRaises(TypeError): + reverse_string(12345) # Non-string input: integer + + def test_none_input(self): + """Test that a None input raises a TypeError.""" + with self.assertRaises(TypeError): + reverse_string(None) # Non-string input: NoneType + + def test_list_input(self): + """Test that a list input raises a TypeError.""" + with self.assertRaises(TypeError): + reverse_string(["a", "b", "c"]) # Non-string input: list + + +if __name__ == "__main__": + unittest.main()