From c729245acfbe72c237c7fdff14bfd2053a4f7166 Mon Sep 17 00:00:00 2001 From: ziadahanass Date: Sat, 11 Jan 2025 09:43:20 -0800 Subject: [PATCH] solution_summary --- CONTRIBUTING.md | 218 +++++++++++++------- collaboration/communication.md | 6 +- collaboration/learning_goals.md | 8 +- notes/README.md | 26 +++ solutions/README.md | 7 + solutions/check_prime_number.py | 45 ++++ solutions/direction_to_degree.py | 72 +++++++ solutions/greatest_number.py | 6 +- solutions/miles_to_kilometers.py | 42 ++++ solutions/multiplication.py | 32 +++ solutions/password_strength.py | 29 ++- solutions/tests/test_check_prime_number.py | 106 ++++++++++ solutions/tests/test_direction_to_degree.py | 69 +++++++ solutions/tests/test_miles_to_kilometers.py | 43 ++++ solutions/tests/test_multiplication.py | 49 +++++ solutions/tests/test_password_strength.py | 5 - solutions/tests/test_volts_to_amperes.py | 86 ++++++++ solutions/volts_to_amperes.py | 55 +++++ 18 files changed, 807 insertions(+), 97 deletions(-) create mode 100644 solutions/check_prime_number.py create mode 100644 solutions/direction_to_degree.py create mode 100644 solutions/miles_to_kilometers.py create mode 100644 solutions/multiplication.py create mode 100644 solutions/tests/test_check_prime_number.py create mode 100644 solutions/tests/test_direction_to_degree.py create mode 100644 solutions/tests/test_miles_to_kilometers.py create mode 100644 solutions/tests/test_multiplication.py create mode 100644 solutions/tests/test_volts_to_amperes.py create mode 100644 solutions/volts_to_amperes.py diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 35abbf33b..92eaefda1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -127,22 +127,38 @@ git clone https://github.com/username/repository.git 1. Create or modify a file in your repository 2. Stage your changes: - ```bash +**For single file change:** + +```bash +git add +``` + +**For all changes in severals files:** + + ```bash git add . ``` -3. Commit your changes: +1. Commit your changes: ```bash git commit -m "Initial commit: Add project setup files" ``` -4. Push to the main branch: +2. Push to the main branch: + +For the main branch: ```bash git push origin main ``` +For certain branch: + +```bash +git push origin +``` + #### Troubleshooting Common Setup Issues - If you encounter permission denied errors, verify your SSH key is properly @@ -252,48 +268,80 @@ Spot the "Compare & pull request" button? Give it a click to start the magic. - Changes: 20+ files - Lines of Code: 1000+ lines - Feature Focus: Multiple features mixed + + --- + +## ⚠️ Merge Conflict + +If you encounter merge conflicts while merging a PR: + +1. **Checkout Your Branch** + + ```bash + git checkout your-branch + ``` + +2. **Pull Latest Changes from Main** + + ```bash + git pull origin main + ``` + +3. **Resolve Conflicts** + + Open the conflicting files in your code editor (e.g., VS Code) and manually + resolve the conflicts. + +4. **Stage the Changes** -## Merge Conflicts + ```bash + git add . + ``` -If You Get Merge Conflicts +5. **Commit the Resolution** -- Checkout your branch: git checkout your-branch -- Pull the latest changes from main: git pull origin main -- Resolve conflicts: Open the conflicting files in your code editor (e.g., - VS Code) and manually resolve the conflicts -- Stage the changes: git add . -- Commit the resolution: git commit -m "Resolve merge conflicts with main" -- Push the resolved changes: git push + ```bash + git commit -m "Resolve merge conflicts with main" + ``` + +6. **Push the Resolved Changes** + + ```bash + git push + ``` + +After pushing, GitHub will automatically update the PR with the resolved conflicts. ## Best Practices for Collaboration 🤝 -Collaboration is key to successful teamwork, and following best practices helps -keep everything running smoothly. Below are some important practices to follow, +Collaboration is key to successful teamwork, and following best practice helps +heep everything running smoothly. Below are some important practices to follow, complete with examples to ensure effective collaboration: ### Write Commit Messages 📝 -Commit messages should clearly describe what changes have been made and why. -A well-written commit message helps other developers understand the purpose of -the change and makes it easier to navigate the project's history. +Commit messages should clearly describe what changes +have been made and why. A well-written commit message helps other developers +understand the purpose of the change and make it easier to navigate +the project's history. -**Best Practice for Commit Messages:** ✏️ + **Best Practice for Commit Messages:** ✏️ - **Be clear and concise:** Briefly describe what was changed and why. - **Follow a consistent format:** This makes it easier to read and understand. -- **Use the imperative mood:** Write messages as commands (e.g., "Fix bug" - instead of "Fixed bug"). +- **Use the imperative mood:** Write messages as commands (e.g "Fix bug" + instead of "Fixed bug"). -**Examples:** + **Examples:** - **Good Commit Message:** ```bash -git commit -m "Fix bug in user login validation" + git commit -m "Fix bug in user login validation" ``` -**Explanation:** This message clearly explains that a bug in the validation -has been fixed, which helps others understand the purpose of the change. + **Explanation:** This message clearly explains that a bug in the +validation has been fixed, which helps others understand the purpose of the change. - **Bad Commit Message:** @@ -301,27 +349,26 @@ has been fixed, which helps others understand the purpose of the change. git commit -m "Fixed login" ``` -**Explanation:** This message is vague and doesn't explain what part of the + **Explanation:** This message is vague and doesn't explain what part of the login process was fixed or why. - -**Why this is important:** Clear commit messages make it easier for your team -to understand changes without needing to dive into the code, and they make -reviewing and tracking changes much easier. + **Why this important:** Clear commit messages make it easier for your team to +understand changes without needing to dive into the code, and they make reviewing +and tracking changes much easier. --- ### Use Proper Branching Strategies 🌱 -Use a structured branching strategy to ensure the team works in an organized -manner. Each new task should be worked on in its own branch, which keeps the -main codebase clean and makes collaboration easier. - +Use a structured branching strategy ensures the team works in an organized manner. +Each new task should be worked on in its won branch, which keeps the main +codebase clean and makes collaboration easier. **Best Practices for Branching:** - **Create a branch for each task:** Each feature, bug fix, or improvement - should have its own branch. -- **Name branches descriptively:** Use branch names that reflect the task - you're working on. +should have its own branch. + +- **Name branches descriptively:** Use branch names that reflect the task you're +working on. **Examples:** @@ -332,16 +379,15 @@ git checkout -b feature/login-page ``` **Explanation:** You're creating a branch specifically to work on the login -page feature. +page feature -- **Bug Fix Branch:** +- **Bug Fixe Branch:** ```bash -git checkout -b bugfix/fix-header-alignment +git checkout -b bugfix/fic-header-alignment ``` -**Explanation:** This branch is dedicated to fixing an issue with the header -alignment. +**Explanation:** This branch is dedicated to fixing an issue with the header alignment. - **Hotfix Branch:** @@ -349,80 +395,103 @@ alignment. git checkout -b hotfix/fix-crash-on-startup ``` -**Explanation:** A hotfix branch is used to fix a critical issue, such as a -crash when starting the application. +**Explanation:** A hotfix branch is used to add a critical issue, such as a +when starting the application. -**Why this is important:** By creating separate branches for each task and -naming them descriptively, the team can work on multiple tasks at once without -interfering with each other's work. It also makes it easy to track what each -branch is working on. +**Why this is important:** By creating separate branches for each task and naming +them descriptively, the team can work on multiple tasks at once without interfering +with each other's work. It also makes it easy to track what each branch is +working on. --- ## **Resolving Merge Conflicts 🔧** -Merge conflicts occur when two or more team members make changes to the same -part of a file. You need to resolve these conflicts manually to make sure that -all changes are merged correctly. +Merge conflicts occur when two or more team members changes to the same part of +a file. You need to resolve these conflicts manually to make sure that all +changes are merged correctly. **Steps for Resolving Merge Conflicts:** -**Understanding Merge Conflicts** When there's a conflict, Git will mark the -conflicting areas in the file. These markers indicate the changes made by -both you and the other developer. + **Understanding Merge Conflicts** When there's a conflict, +Git will mark the conflicting areas in the file. These markers indicate the +changes made by both you and the other developer. -Imagine two developers are working on the Markdown file `README.md` or Python -file `Calculation.py`. For example, in a Markdown file: +Imagine two developers are working on the Markdown file ```README.md``` or +python file ```Calculation.py``` for example, in Markdown file: -```markdown +```Markdown +<<<<<<< HEAD # How to Contribute This guide will help you contributing effectively. +======= +# How to Contribute + +This document explains the best practices for contributing to the project. +>>>>>>> fearuer/section-1 ``` -In this case, the conflict is in the header (`# How to contribute`), and +In this case, the conflict is in the header(```# How to contribute```), and both versions contain different text following the heading. Similarly, in a **Python file**, a conflict could look like this: ```python +<<<<<<< HEAD def greeting(): print("Welcome to the project!") +======= +def greeting(): + print("Hello, thanks for contributing!") +>>>>>>> fearuer/greeting ``` ### **How to Resolve Merge Conflicts** 🔧 -**Steps for resolving conflicts in Markdown or Python files:** + **Steps for resolving conflicts in Markdown or Python files:** - **Step 1: Identify the Conflict** 🕵️‍♂️ - - Look for the conflict markers. You will see: - - `<<<<<<< HEAD`: The changes you made - - `=======`: The division between your changes and the incoming changes - - `>>>>>>> branch-name`: The changes made by someone else (in the - specified branch) +- Look for the conflict markers. You will see: + - ```<<<<<<< HEAD```: The changes you made. + - ```=======```: The division between your changes and the incoming changes. + + - ```>>>>>>> branch-name```: the changes made by someone else (in the +specified branch) **Example (Markdown conflict):** ```markdown + +<<<<<<< HEAD + # How to Contribute This guide will help you contribute effectively +======= + +# How to Contribute + +This document explains the best practices for contributing to the project. +>>>>>>> feature/section-1 + ``` - **Step 2: Decide which changes to keep** ⚖️ - - You need to decide if you want to keep your changes, the other person's - changes, or merge both sets of changes. + + - You need to decide if you want to keep your changes, the other person’s +changes, or merge both sets of changes. **In the Markdown file**, you might want to combine both sentences: ```markdown # How to Contribute -This guide will help you contribute effectively and explains the best -practices for contributing to the project. +This guide will help you contribute effectively and explains the best practices +for contributing to the project. ``` -**In the Python file**, you could keep both greetings or choose one: +**In the Python file,** you could keep both greetings or choose one: ```python def greeting(): @@ -432,17 +501,22 @@ def greeting(): ``` - **Step 3: Remove Conflict Markers** 🧹 - - After deciding, delete the conflict markers (`<<<<<<`, `======`, and - `>>>>>>`). For instance, in Markdown: + + - **After deciding, delete the conflict marker(```<<<<<<```, +```======```, and ```>>>>>>```). For instance, in Markdown:** ```markdown + # How to Contribute -This guide will help you contribute effectively and explains the best -practices for contributing to the project. +This guide will help you contribute effectively and explains the best practices +for contributing to the project. ``` --- +By following these steps, you'll resolve conflicts easily, whether you'er working +on a **Markdown** file or a **Python file**. The key is to understand the +changes, merge them carefully, and test everything before committing your changes. We are excited to have your contribution to improve the repository and help us build better software together! 💪 diff --git a/collaboration/communication.md b/collaboration/communication.md index cccb50ba9..57dfb64cf 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -29,10 +29,10 @@ How often we will get in touch on each channel, and what we will discuss there: | Clement| 6-8 PM | 6-8 PM | 6-8 PM | 6-8 PM | 6-8 PM | 6-8 PM | 6-8 PM | | Fahed | 6-8 PM | 7-9 PM | 6-8 PM | 5-7 PM | 8-9 PM | 8-9 PM | 6-8 PM | | Faisal | $TIME$ | $TIME$ | $TIME$ | $TIME$ | $TIME$ | $TIME$ | $TIME$ | -| Majd | $TIME$ | $TIME$ | $TIME$ | $TIME$ | $TIME$ | $TIME$ | $TIME$ | +| Majd |6-8 PM | 6-8 PM | 5-6 PM | 4-7 PM | 4-7 PM | 4-7 PM | 7-9 PM | | Mohamed| 6-9 PM | 6-9 PM | 6-9 PM | 6-10 PM | 2-9 PM | 6-9 PM | 6-9 PM | | Obey | $TIME$ | $TIME$ | $TIME$ | $TIME$ | $TIME$ | $TIME$ | $TIME$ | -| Özgür | $TIME$ | $TIME$ | $TIME$ | $TIME$ | $TIME$ | $TIME$ | $TIME$ | +| Özgür | 5-7 PM | 5-7 PM | 5-7 PM | 5-7 PM | 5-7 PM | 5-7 PM | 5-7 PM | | Razan | 7-9 PM | 9-10 PM | 7-9 PM | 7-9 PM | 7-9 PM | 7-9 PM | 7-9 PM | ### How many hours everyone reserves for Code review per day @@ -44,7 +44,7 @@ How often we will get in touch on each channel, and what we will discuss there: - Majd: $HOURS$ - Mohamed: 2 hours - Obey: $HOURS$ -- Özgür: $HOURS$ +- Özgür: 2 hours - Razan: An hour ## Asking for Help diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 01f29d7c5..e53b3d958 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -85,6 +85,8 @@ environment that provides support and help to every member in need. - Enhance communication and collaborative skills for a more effective work environment. - ### **Özgür** - - - + + - learning team work. + - Write clean python code. + - Improve communication skills with team members. + - Using unit test. diff --git a/notes/README.md b/notes/README.md index 17e0f0ded..558db9254 100644 --- a/notes/README.md +++ b/notes/README.md @@ -1 +1,27 @@ # Notes + +Welcome to the **Notes** directory! 🎉 + +This is our little corner of the project where we share all the gems we pick up +along the way. 🧠✨ + +Here’s what you’ll find (and what you’re welcome to add): + +- 🖋️ **What We're Learning:** Got a cool trick in Git? Learned a new design +pattern? Found a clever way to squash bugs? Share it here! +- 😂 **Funny Moments:** Code reviews aren’t always serious — if something made +you laugh (or cry), jot it down! Laughter is the best debugging tool. +- 📚 **Resources:** Found a great article, video, or book that helped you level +up? Share it with the team! +- ❤️ **Personal Reflections:** How’s the journey been for you? Whether it’s +growth, challenges, or proud moments, we’d love to hear about it. +- 🤝 **Collaboration Stories:** Cool ways we’ve helped each other shine or +overcame hurdles as a team. +- 🎨 **Creative Additions:** Doodles, memes, or anything that adds color to our +shared experience! + +This space is all about **connection** and **growth**. Use it freely to document +your learning, share your quirks, or just have fun. Let’s make this a treasure +trove of memories and insights! 🚀 + +Happy noting, team! 📝🌟 diff --git a/solutions/README.md b/solutions/README.md index 8452aeeb4..02e66ff8d 100644 --- a/solutions/README.md +++ b/solutions/README.md @@ -24,10 +24,17 @@ while corresponding test files are maintained in the `tests` folder. | `calculate_average.py`| Calculates the average of a list of numbers | Clement | | `spiral_traverse.py` | Traverses a 2D matrix in spiral order | Fahed | | `euler_totient.py` | Computes Euler's totient function (ϕ(n))| Fahed | +| `direction_to_degree.py` | Convert a cardinal direction to degree | Obay | | `check_odd_or_even.py` | Checks if a number is odd or even | Clement | | `grading_system.py`| Assigning letter grade to a numeric score. | Razan | | `kronecker_product.py` | Computes the Kronecker ⊗ product of 2 matrices | Fahed| | `feet_to_meters.py` | Converting feet to meters| Obay | +| `volts_to_amperes.py` | Converting volts to amperes| Obay | +| `miles_to_kilometers.py` | Converting miles to kilometers| Obay | +| `greatest_number.py` | Finding greatest number in a list| Razan | +| `check_prime_number.py` | Given a positive int if it is a prime number| Özgür | +| `password_strength.py` | Converts decimal number its binary equivalent | Anas | +| `decimal_to_binary.py` | Evaluates the strength of a password | Anas | --- diff --git a/solutions/check_prime_number.py b/solutions/check_prime_number.py new file mode 100644 index 000000000..59e7ba521 --- /dev/null +++ b/solutions/check_prime_number.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +""" +This function check number for prime or not. + +Author: Özgür ÖZBEK +Date: 11th January 2025 +Group: ET6-foundations-group-16 +""" + + +def check_prime_number(number: int) -> bool: + """Checks if a number is prime. + + A prime number is a number greater than 1 that has no divisors other than 1 and itself. + This function checks if the given number is prime by testing divisibility for all numbers + from 2 to the square root of the number. + + Parameters: + number: int, the number to check for prime. Must be greater than 1. + + Returns: + bool: True if the number is prime, False otherwise. + + Raises: + AssertionError: If the number is less than or equal to 1. + + Examples: + >>> check_prime_number(2) + True + >>> check_prime_number(3) + True + >>> check_prime_number(4) + False + >>> check_prime_number(13) + True + >>> check_prime_number(1) # doctest: +ELLIPSIS + Traceback (most recent call last): + ... + AssertionError: Number must be greater than 1 + """ + assert number > 1, "Number must be greater than 1" + for i in range(2, int(number**0.5) + 1): + if number % i == 0: + return False + return True diff --git a/solutions/direction_to_degree.py b/solutions/direction_to_degree.py new file mode 100644 index 000000000..f563914d3 --- /dev/null +++ b/solutions/direction_to_degree.py @@ -0,0 +1,72 @@ +""" +direction_to_degree.py + +This module contains a function to convert a cardinal or intercardinal direction +to a corresponding degree, measured clockwise from North (0 degrees). + +Author: Obay Salih +Date: Tues 7 Jan 2025 +Group: ET6-foundations-group-16 + +Functions: +- direction_to_degree(direction): Converts a cardinal or intercardinal direction to a degree. +""" + + +def direction_to_degree(direction: str) -> int: + """ + Converts a cardinal or intercardinal direction to a degree measured clockwise from North. + + Args: + direction (str): A cardinal or intercardinal direction (e.g., "N", "NE", "SW", etc.). + + Returns: + int: The corresponding degree, or 'Invalid direction' if the direction is not recognized. + + Raises: + ValueError: If the input is not a string. + + Assumptions: + - The direction must be a string. + - The direction must be one of the recognized cardinal or intercardinal directions. + + Examples: + >>> direction_to_degree("N") + 0 + >>> direction_to_degree("NE") + 45 + >>> direction_to_degree("SW") + 225 + >>> direction_to_degree("INVALID") + 'Invalid direction' + """ + + # Defensive check: If the input is not a string, raise a ValueError. + if not isinstance(direction, str): + raise ValueError("The direction must be a string.") + + # Define the mapping of directions to degrees + directions = { + "N": 0, + "NNE": 22, + "NE": 45, + "ENE": 67, + "E": 90, + "ESE": 112, + "SE": 135, + "SSE": 157, + "S": 180, + "SSW": 202, + "SW": 225, + "WSW": 247, + "W": 270, + "WNW": 292, + "NW": 315, + "NNW": 337, + } + + # Convert the input direction to uppercase and check if it is valid + direction = direction.upper() + + # Return the degree for valid directions, or 'Invalid direction' if not found + return directions.get(direction, "Invalid direction") diff --git a/solutions/greatest_number.py b/solutions/greatest_number.py index 932ddc6c5..05968813a 100644 --- a/solutions/greatest_number.py +++ b/solutions/greatest_number.py @@ -16,19 +16,19 @@ def greatest_number(data: list) -> float | int: """ This function receives a list of values and returns the greatest numeric value within the list. The list may contain integers and floats. If the list contains - valid numeric values, the greatest value is returned. If the list is empty, the - function returns None. + valid numeric values, the greatest value is returned. Parameters: data: list, a list of values that can include integers, floats, and non-numeric elements. Returns-> float, the greatest numeric value is a list, which will represent either integer or float, - depending on the input. Returns None if the list is empty.add() + depending on the input. Raises: AssertionError: if the list don't contain either integer or float value AssertionError: if the input is not a list. + AssertionError: if the input is an empty list. >>> greatest_number ([10, -5, 3.2, 99, 0]) 99 diff --git a/solutions/miles_to_kilometers.py b/solutions/miles_to_kilometers.py new file mode 100644 index 000000000..88cfc5045 --- /dev/null +++ b/solutions/miles_to_kilometers.py @@ -0,0 +1,42 @@ +""" +miles_to_kilometers.py + +This module provides a function to convert miles to kilometers. + +Author: Obay Salih +Date: Fri 10/1/2025 +Group: ET6-foundations-group-16 (Matrix) + +Functions: +- miles_to_kilometers(miles): Converts miles to kilometers and returns the result. +""" + + +def miles_to_kilometers(miles: float) -> float: + """ + Convert miles to kilometers. + + Parameters: + - miles (int or float): The distance in miles to be converted. + + Returns: + - float: The converted distance in kilometers. + + Example: + >>> miles_to_kilometers(1) + 1.609344 + >>> miles_to_kilometers(10) + 16.09344 + """ + if not isinstance(miles, (int, float)): + raise ValueError("Input must be a number.") + if miles < 0: + raise ValueError("Distance cannot be negative.") + + # Conversion factor from miles to kilometers + return miles * 1.609344 + + +if __name__ == "__main__": + # Example usage + print("Example: miles_to_kilometers(5) =", miles_to_kilometers(5)) diff --git a/solutions/multiplication.py b/solutions/multiplication.py new file mode 100644 index 000000000..6a0e549ec --- /dev/null +++ b/solutions/multiplication.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 +# -- coding: utf-8 -- +""" +A module for multiplying two numbers. +Module contents: + - multiply_numbers: Multiplies two numbers and returns the product. +""" + + +def multiply_numbers(num1, num2): + """Returns the product of two numbers. + Takes two numbers (integers or floats) and returns their product. + The output type will match the input types (i.e., if both inputs are integers, + the output will be an integer; if both are floats, the output will be a float). + If the inputs are not both integers or floats, an AssertionError is raised. + Parameters: + num1: int or float, the first number to multiply + num2: int or float, the second number to multiply + Returns -> int or float: the product of num1 and num2 + Raises: + AssertionError: if inputs are not both int or float + Examples: + >>> multiply_numbers(5, 3) + 15 + >>> multiply_numbers(4.5, 2.0) + 9.0 + >>> multiply_numbers(-7, 6) + -42 + """ + assert isinstance(num1, (int, float)), "num1 must be an int or float" + assert isinstance(num2, (int, float)), "num2 must be an int or float" + return num1 * num2 diff --git a/solutions/password_strength.py b/solutions/password_strength.py index 1ba41cf94..06bdba576 100644 --- a/solutions/password_strength.py +++ b/solutions/password_strength.py @@ -14,7 +14,7 @@ def password_strength(password: str) -> str: - """Checks the strength of a given password. + """Checks the strength of a given password with detailed feedback. The password strength is determined by the following rules: - Minimum length of 8 characters. @@ -27,32 +27,39 @@ def password_strength(password: str) -> str: password: str, the password to check. Returns: - str: A message indicating whether the password is strong or weak. + str: A message indicating the missing requirement or 'Strong password'. + + Raises: + AssertionError: If the input is not a string. Examples: >>> password_strength("StrongP@ssw0rd") 'Strong password' >>> password_strength("weakpass") - 'Weak password' + 'Missing uppercase letter' >>> password_strength("Short1!") - 'Weak password' - >>> password_strength("NoSpecial123") - 'Weak password' + 'Password too short' """ + # Make sure password is a string + if not isinstance(password, str): + raise AssertionError("Password must be a string") + # Handle password strength rules + # Sequentially validate the password against different strength criteria if len(password) < 8: - return "Weak password" + return "Password too short" if not re.search(r"[A-Z]", password): - return "Weak password" + return "Missing uppercase letter" if not re.search(r"[a-z]", password): - return "Weak password" + return "Missing lowercase letter" if not re.search(r"[0-9]", password): - return "Weak password" + return "Missing digit" if not re.search(r"[@$!%*?&]", password): - return "Weak password" + return "Missing special character" + # If all checks pass, the password is considered strong return "Strong password" diff --git a/solutions/tests/test_check_prime_number.py b/solutions/tests/test_check_prime_number.py new file mode 100644 index 000000000..82caf8859 --- /dev/null +++ b/solutions/tests/test_check_prime_number.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Unit Test for check_prime_number Function + +This script contains a unit test for the `check_prime_number` function, +which checks whether a given number +is prime or not. +A prime number is a number greater than 1 that has no divisors other than 1 and itself. + +The test class `TestIsPrime` includes various test cases to verify that the function works correctly +for different types of inputs: +- Prime numbers +- Non-prime numbers +- Edge cases (such as 0, 1, and negative numbers) +- Larger prime numbers + +Test cases include: +- Testing prime numbers like 2, 3, 5, 7, 13. +- Testing non-prime numbers like 1, 4, 6, 8, 9, 10, 14. +- Checking edge cases such as 0 and negative numbers. + +To run the tests, use the Python `unittest` framework. +The tests will provide feedback on the correctness +of the `check_prime_number` function. + +Author: Özgür ÖZBEK +Date: 11th January 2025 +Group: ET6-foundations-group-16 + +""" + +import unittest +from ..check_prime_number import check_prime_number + + +class TestCheckPrimeNumber(unittest.TestCase): + """Test case for the check_prime_number function.""" + + def test_prime(self): + """Test prime number 2.""" + self.assertTrue(check_prime_number(2)) + + def test_prime_3(self): + """Test prime number 3.""" + self.assertTrue(check_prime_number(3)) + + def test_prime_5(self): + """Test prime number 5.""" + self.assertTrue(check_prime_number(5)) + + def test_prime_7(self): + """Test prime number 7.""" + self.assertTrue(check_prime_number(7)) + + def test_prime_13(self): + """Test prime number 13.""" + self.assertTrue(check_prime_number(13)) + + def test_non_prime_4(self): + """Test non-prime number 4.""" + self.assertFalse(check_prime_number(4)) + + def test_non_prime_6(self): + """Test non-prime number 6.""" + self.assertFalse(check_prime_number(6)) + + def test_non_prime_8(self): + """Test non-prime number 8.""" + self.assertFalse(check_prime_number(8)) + + def test_non_prime_9(self): + """Test non-prime number 9.""" + self.assertFalse(check_prime_number(9)) + + def test_non_prime_10(self): + """Test non-prime number 10.""" + self.assertFalse(check_prime_number(10)) + + def test_non_prime_14(self): + """Test non-prime number 14.""" + self.assertFalse(check_prime_number(14)) + + def test_edge_case_0(self): + """Test edge case 0.""" + with self.assertRaises(AssertionError): + check_prime_number(0) + + def test_edge_case_negative(self): + """Test edge case negative number.""" + with self.assertRaises(AssertionError): + check_prime_number(-1) + + def test_non_prime_1(self): + """Test non-prime number 1.""" + with self.assertRaises(AssertionError): + check_prime_number(1) + + def test_edge_case_large_prime(self): + """Test edge case with large prime.""" + self.assertTrue(check_prime_number(97)) + + +if __name__ == "__main__": + unittest.main() diff --git a/solutions/tests/test_direction_to_degree.py b/solutions/tests/test_direction_to_degree.py new file mode 100644 index 000000000..c0c6b3289 --- /dev/null +++ b/solutions/tests/test_direction_to_degree.py @@ -0,0 +1,69 @@ +""" +This module contains unit tests for the `direction_to_degree` function. + +The tests verify that the `direction_to_degree` function works as expected for a variety of +valid and invalid inputs, including boundary cases and case insensitivity. + +Tests include: +- Valid direction inputs ("N", "NE", "SW", etc.) +- Invalid direction inputs (e.g., "INVALID") +- Non-string inputs (e.g., integers) +- Case insensitivity of the function + +The tests ensure that the function returns the correct degree or an "Invalid direction" string, +and that it raises a `ValueError` when given a non-string input. +""" + +import unittest + +from solutions.direction_to_degree import direction_to_degree + + +class TestDirectionToDegree(unittest.TestCase): + """Test the behavior of the direction_to_degree function.""" + + def test_valid_directions(self): + """Test valid direction inputs.""" + # Check cardinal directions + self.assertEqual(direction_to_degree("N"), 0) + self.assertEqual(direction_to_degree("E"), 90) + self.assertEqual(direction_to_degree("S"), 180) + self.assertEqual(direction_to_degree("W"), 270) + + # Check intercardinal directions + self.assertEqual(direction_to_degree("NE"), 45) + self.assertEqual(direction_to_degree("SE"), 135) + self.assertEqual(direction_to_degree("SW"), 225) + self.assertEqual(direction_to_degree("NW"), 315) + + # Check other intercardinal directions + self.assertEqual(direction_to_degree("NNE"), 22) + self.assertEqual(direction_to_degree("ENE"), 67) + self.assertEqual(direction_to_degree("ESE"), 112) + self.assertEqual(direction_to_degree("SSW"), 202) + self.assertEqual(direction_to_degree("WSW"), 247) + self.assertEqual(direction_to_degree("WNW"), 292) + self.assertEqual(direction_to_degree("NNW"), 337) + + def test_invalid_direction(self): + """Test invalid direction input.""" + self.assertEqual(direction_to_degree("INVALID"), "Invalid direction") + + def test_case_insensitivity(self): + """Test case insensitivity.""" + self.assertEqual(direction_to_degree("n"), 0) + self.assertEqual(direction_to_degree("se"), 135) + self.assertEqual(direction_to_degree("ESE"), 112) + + def test_non_string_input(self): + """Test non-string input.""" + with self.assertRaises(ValueError): + direction_to_degree(123) # Should raise ValueError + + def test_empty_string(self): + """Test empty string input.""" + self.assertEqual(direction_to_degree(""), "Invalid direction") + + +if __name__ == "__main__": + unittest.main() diff --git a/solutions/tests/test_miles_to_kilometers.py b/solutions/tests/test_miles_to_kilometers.py new file mode 100644 index 000000000..973ef640d --- /dev/null +++ b/solutions/tests/test_miles_to_kilometers.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +""" +Test module for the miles_to_kilometers function. + +Test categories: + - Standard cases: Positive numbers and zero. + - Defensive tests: Non-numeric inputs and negative values. +""" + +import unittest +from ..miles_to_kilometers import miles_to_kilometers + + +class TestMilesToKilometers(unittest.TestCase): + """Test suite for the miles_to_kilometers function.""" + + # Standard test cases + def test_positive_miles(self): + """Test case for positive miles.""" + self.assertEqual(miles_to_kilometers(1), 1.609344) + + def test_zero_miles(self): + """Test case for zero miles.""" + self.assertEqual(miles_to_kilometers(0), 0.0) + + def test_large_miles(self): + """Test case for a large value of miles.""" + self.assertEqual(miles_to_kilometers(100), 160.9344) + + # Defensive tests + def test_negative_miles(self): + """Test case for negative miles.""" + with self.assertRaises(ValueError): + miles_to_kilometers(-5) + + def test_non_numeric_input(self): + """Test case for non-numeric input.""" + with self.assertRaises(ValueError): + miles_to_kilometers("ten") + + +if __name__ == "__main__": + unittest.main() diff --git a/solutions/tests/test_multiplication.py b/solutions/tests/test_multiplication.py new file mode 100644 index 000000000..1c8966931 --- /dev/null +++ b/solutions/tests/test_multiplication.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Test module for multiply_numbers function. + +Test categories: + - Standard cases: typical numbers + - Edge cases: zero, negative numbers + - Defensive tests: wrong input types, assertions + +""" + +import unittest + +from solutions.multiplication import multiply_numbers + + +class TestMultiplyNumbers(unittest.TestCase): + """Test suite for the multiply_numbers function.""" + + # Standard test cases + def test_positive_integers(self): + """It should return the product of two positive integers""" + self.assertEqual(multiply_numbers(5, 3), 15) + + def test_floats(self): + """It should return the product of two floats""" + self.assertEqual(multiply_numbers(4.5, 2.0), 9.0) + + def test_mixed_signs(self): + """It should return the product of one negative integer and one positive integer""" + self.assertEqual(multiply_numbers(-7, 6), -42) + + # Edge cases + def test_zero(self): + """It should return the product when multiplying by zero""" + self.assertEqual(multiply_numbers(0, 12), 0) + + def test_negative_integers(self): + """It should return the product of two negative integers""" + self.assertEqual(multiply_numbers(-3, -4), 12) + + def test_float_and_integer(self): + """It should return the product of a float and an integer""" + self.assertEqual(multiply_numbers(2.5, 4), 10.0) + + +if __name__ == "__main__": # noqa: F821 + unittest.main() diff --git a/solutions/tests/test_password_strength.py b/solutions/tests/test_password_strength.py index c80c38a84..f85213273 100644 --- a/solutions/tests/test_password_strength.py +++ b/solutions/tests/test_password_strength.py @@ -11,14 +11,9 @@ """ import unittest -import os from solutions.password_strength import password_strength -# Debugging: Print current working directory to ensure proper location -print("Current working directory:", os.getcwd()) - - class TestPasswordStrength(unittest.TestCase): """Unit tests for the password_strength function.""" diff --git a/solutions/tests/test_volts_to_amperes.py b/solutions/tests/test_volts_to_amperes.py new file mode 100644 index 000000000..e02fdeca2 --- /dev/null +++ b/solutions/tests/test_volts_to_amperes.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +""" +Test module for the volts_to_amperes function. + +Test categories: + - Standard cases: Positive numbers and zero for voltage and resistance. + - Edge cases: Negative voltage values. + - Defensive tests: Non-numeric inputs and invalid resistance (zero/negative). +""" + +import unittest +from ..volts_to_amperes import volts_to_amperes + + +class TestVoltsToAmperes(unittest.TestCase): + """Test suite for the volts_to_amperes function. + + This test suite ensures that the volts_to_amperes function behaves correctly for a variety + of input values, including positive, negative, and zero values for both voltage and + resistance, as well as checks for invalid inputs. + """ + + # Standard test cases + def test_positive_voltage(self): + """Test case for a positive voltage and valid resistance. + + This test verifies that the function returns the correct amperes when a positive + voltage and valid resistance are provided. + """ + self.assertEqual(volts_to_amperes(10, 2), 5.0) + + def test_large_positive_voltage(self): + """Test case for a large positive voltage. + + This test verifies that the function returns the correct amperes for a larger + positive voltage. + """ + self.assertEqual(volts_to_amperes(100, 2), 50.0) + + def test_zero_voltage(self): + """Test case for zero voltage. + + This test verifies that the function correctly returns 0 amperes when the voltage + is zero. + """ + self.assertEqual(volts_to_amperes(0, 10), 0.0) + + # Edge cases + def test_negative_voltage(self): + """Test case for a negative voltage value. + + This test verifies that the function handles negative voltage inputs correctly. + """ + self.assertEqual(volts_to_amperes(-10, 2), -5.0) + + # Defensive tests + def test_non_numeric_voltage(self): + """Test case for a non-numeric voltage input. + + This test ensures that the function raises a ValueError when the voltage is a + non-numeric value. + """ + with self.assertRaises(ValueError): + volts_to_amperes("10", 2) + + def test_zero_resistance(self): + """Test case for zero resistance value. + + This test ensures that the function raises a ValueError when the resistance is + zero, as dividing by zero is not allowed in this context. + """ + with self.assertRaises(ValueError): + volts_to_amperes(10, 0) + + def test_negative_resistance(self): + """Test case for negative resistance value. + + This test ensures that the function raises a ValueError when the resistance is + negative, as negative resistance is not valid in this context. + """ + with self.assertRaises(ValueError): + volts_to_amperes(10, -2) + + +if __name__ == "__main__": + unittest.main() diff --git a/solutions/volts_to_amperes.py b/solutions/volts_to_amperes.py new file mode 100644 index 000000000..059a4b615 --- /dev/null +++ b/solutions/volts_to_amperes.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +""" +This module contains a function to convert voltage to amperes using Ohm's law. +The formula used is: I = V / R + + +Created on Fri 10/1/2024 +@author: Obay Salih +Group: ET foundations group 16 (Matrix) +Module contents: + +Where: +- V is the voltage in volts +- R is the resistance in ohms +- I is the current in amperes + +Function: +volts_to_amperes(volts, resistance) -> float + +Arguments: +volts (float): The voltage in volts (V) +resistance (float): The resistance in ohms (Ω) + +Returns: +float: The current in amperes (A) + +Raises: +ValueError: If the resistance is zero or negative, or if the input values are not numeric +""" + + +def volts_to_amperes(volts: float, resistance: float) -> float: + """ + Convert voltage (V) to amperes (A) using Ohm's law. + + Parameters: + volts (float): The voltage in volts. + resistance (float): The resistance in ohms. + + Returns: + float: The current in amperes. + + Raises: + ValueError: If resistance is zero or negative. + """ + + if not isinstance(volts, (int, float)) or not isinstance(resistance, (int, float)): + raise ValueError("Both voltage and resistance must be numeric values.") + + if resistance <= 0: + raise ValueError("Resistance must be a positive number.") + + # Ohm's law: I = V / R + current = volts / resistance + return current