From 4345127bd0b11753424a760c89f1cbab8e8d5ca0 Mon Sep 17 00:00:00 2001 From: AmmarIbrahim <3mmar2001@gmail.com> Date: Wed, 25 Dec 2024 22:01:57 +0300 Subject: [PATCH 001/117] Added the group constriants to collaboration folder --- collaboration/constraints.md | 65 +++++++++++++++++------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 24079505c..fa7e71238 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -1,34 +1,31 @@ - - -# Constraints - -Some boundaries around our project. - -## External - - - -## Internal: Involuntary - - - -## Internal: Voluntary - - +# Group 21 Constraints + +## External Constraints + +- **Time Zone Differences:** + ~ Solarahamza, Nouranaia, Omerdafaalla +- **Family Responsibilities:** + ~ Nouranaia, Fikre-Mamo, Omerdafaalla, Collins Ochieng +- **Work Obligations:** + ~ Solarahamza, Fikre-Mamo, Omerdafaalla, Ammar +- **Studying for Exams:** + ~ Solarahamza, Omerdafaalla, Collins Ochieng, Ammar +- **Limited Internet Access:** + ~ Nouranaia, Fikre-Mamo, Collins Ochieng +- **Device Issues (Computer Complications):** + ~ Collins Ochieng + +## Involuntary Internal Constraints + +- **Stress Balancing Multiple Responsibilities:** + ~ Nouranaia +- **Likes to Take Responsibility and Lead:** + ~ Ammar + *(May be annoying sometimes, so notify me if it feels like I'm taking + over too much.)* +- **No Past Experience in Coding:** + ~ Ammar + +## Voluntary Internal Constraints + +- **None at the moment** From 7a9b819302b3e7dec3d46d9cdfaff964971e0e5d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Dec 2024 17:48:01 +0300 Subject: [PATCH 002/117] Added Collaboration README --- collaboration/README.md | 84 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/collaboration/README.md b/collaboration/README.md index 20889b951..8cb8efa67 100644 --- a/collaboration/README.md +++ b/collaboration/README.md @@ -3,3 +3,87 @@ +--- + +## Group Norms Summary + +Our team values trust through transparency, empathy, and reliable commitments. + +We prioritize respect, cultural sensitivity, constructive feedback,to ensure collaboration. + +### Group Norms and Guidelines + +#### **Building and Maintaining Cognitive and Affective Trust** + +- **Cognitive Trust:** + - Deliver work on time and follow through on commitments. + - Be transparent about progress, challenges, and potential delays. + - Share expertise and assist others when needed. +- **Affective Trust:** + - Show empathy and understanding for teammates' situations. + - Celebrate successes and acknowledge efforts. + - Foster open, non-judgmental communication to create a safe environment. + +#### **Repairing Trust When Damaged** + +- Address issues promptly, directly, and respectfully. +- Take responsibility where necessary and acknowledge mistakes. +- Collaboratively discuss solutions and agree on actionable steps to rebuild trust. +- Commit to regular check-ins to ensure progress and prevent future misunderstandings. + +#### **Balancing Discussion and Debate** + +- **When to Use Discussion:** + - For brainstorming, sharing ideas, and building consensus. + - During early stages of problem-solving or creative exploration. +- **When to Use Debate:** + - To analyze and decide between conflicting options. + - For critical decisions requiring logical reasoning and evidence-based arguments. +- **Guidelines:** + - Maintain respect and focus on the problem, not the person. + - Be clear about the purpose of each conversation: exploration or decision-making. + +#### **Meeting Times and Agendas** + +- Schedule meetings at regular intervals using polls to determine optimal times. +- Share agendas at least 24 hours in advance to ensure preparation. +- Keep meetings short and focused (e.g., under 30 minutes). +- Assign a timekeeper to keep the meeting on track. +- Conclude with a summary of action items and deadlines. + +#### **Communication Channels** + +;- **Daily Updates:** Use Slack for regular team communications. + +- **Meetings:** Conduct on Microsoft Teams. +- **Task Tracking:** Use GitHub Issues or GitHub Projects for project-specific updates. +- **Formal Communication:** Use email or formal documentation for external communication. +- **Best Practices:** +- Tag relevant teammates and categorize messages to avoid confusion. + +#### **Fostering Respect** + +- **Respectful Actions:** + - Actively listen and value everyone's input. + - Give credit for individual contributions. + - Offer constructive feedback instead of criticism. +- **Disrespectful Actions:** + - Ignore input or dominate conversations. + - Miss deadlines without explanation. + - Make personal or unkind remarks. + +#### **Additional Considerations** + +- **Work-Life Balance:** + - Define clear working hours and respect boundaries during weekends or off-hours. + - Support one another during high-stress periods to prevent burnout. +- **Feedback Culture:** + - Create a safe space for giving and receiving constructive feedback. + - Focus feedback on improvement, not fault-finding. +- **Inclusivity:** + - Ensure everyone has an equal chance to contribute, especially during discussions. + - Rotate responsibilities like meeting facilitation to distribute ownership. +- **Cultural Sensitivity:** + - Be aware of and respect cultural differences, fostering an inclusive environment. +- **Celebrating Milestones:** + - Acknowledge and celebrate project wins, big or small, to foster a sense of achievement. From 79ecafd747f168ccb33ad04c275ad38120b8864c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Dec 2024 18:37:43 +0300 Subject: [PATCH 003/117] fixing --- collaboration/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collaboration/README.md b/collaboration/README.md index 8cb8efa67..83ca8b399 100644 --- a/collaboration/README.md +++ b/collaboration/README.md @@ -86,4 +86,4 @@ We prioritize respect, cultural sensitivity, constructive feedback,to ensure col - **Cultural Sensitivity:** - Be aware of and respect cultural differences, fostering an inclusive environment. - **Celebrating Milestones:** - - Acknowledge and celebrate project wins, big or small, to foster a sense of achievement. + - Acknowledge and celebrate project wins to foster sense of achievement. From f239795aebd734a71d848167496ecebbacf678f4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Dec 2024 18:54:10 +0300 Subject: [PATCH 004/117] other md fixes --- collaboration/README.md | 2 +- collaboration/guide/0_repository_setup.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/collaboration/README.md b/collaboration/README.md index 83ca8b399..a1dba20da 100644 --- a/collaboration/README.md +++ b/collaboration/README.md @@ -80,7 +80,7 @@ We prioritize respect, cultural sensitivity, constructive feedback,to ensure col - **Feedback Culture:** - Create a safe space for giving and receiving constructive feedback. - Focus feedback on improvement, not fault-finding. -- **Inclusivity:** +- **Being Inclusive:** - Ensure everyone has an equal chance to contribute, especially during discussions. - Rotate responsibilities like meeting facilitation to distribute ownership. - **Cultural Sensitivity:** diff --git a/collaboration/guide/0_repository_setup.md b/collaboration/guide/0_repository_setup.md index 1e5e1aca7..cd5fea6f9 100644 --- a/collaboration/guide/0_repository_setup.md +++ b/collaboration/guide/0_repository_setup.md @@ -14,7 +14,8 @@ repository and configure it for collaboration: - Change your [repository description](https://stackoverflow.com/questions/7757751/how-do-you-change-a-repository-description-on-github) - Add or remove topics from your repository - - Update your main README with your group name and an initial overview of your project. (You can change this as much as you want.) + - Update your main README with your group name and an initial overview of project. + (You can change this as much as you want.) - Under settings in your repository select: - _Issues_ - _Projects_ From c7b01fda11a3336215767ca068c95a299c18fbc2 Mon Sep 17 00:00:00 2001 From: nourana819 <62513481+nourana819@users.noreply.github.com> Date: Fri, 27 Dec 2024 03:29:25 +0300 Subject: [PATCH 005/117] Describe what you changed --- README.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/README.md b/README.md index e69de29bb..5f705d251 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,46 @@ +# 🌟 Rising Data Stars + +**Welcome to the Rising Data Stars repository!** + +This is more than a project—it's a journey of growth, collaboration, +and discovery. Our team is united by a shared passion for learning and +problem-solving, regardless of individual experience levels. Whether you're + taking your first steps in data or have some prior knowledge, this space is + for you. + +## 🎯 Project Goals + +By participating in this project, each teammate will: + +1. **Solve 2 problems** — Hone your skills by tackling data challenges. +2. **Assist with 2 problems** — Collaborate by helping others overcome their + obstacles. + +Together, we'll learn from our mistakes, celebrate our progress, +and build a supportive community. + +## 🌱 Our Mission + +We believe in the power of collaboration and growth through practice. +This repository is designed to help us: + +- Develop technical skills in a hands-on environment. +- Build confidence through real-world problem-solving. +- Learn the value of teamwork in achieving shared goals. + +## 💡 Who We Are + +- **A Diverse Team:** We are a group of individuals with varying levels of +- experience—some of us are complete beginners, while others have some knowledge +- **Curious Learners:** What unites us is our eagerness to learn and improve. +- **Future Data Stars:** By the end of this journey, we’ll no longer be beginners. +- We’re here to grow and shine in the world of data. + +## 🚀 Next Steps + +1. **Jump in!** Review repository's guidelines and start solving first problem. +2. **Collaborate!** Look for issues others are working on and offer insights. +3. **Share progress!** Celebrate small wins and reflect on challenges—it’s +4. all part of the process. + +Let’s learn, grow, and become the data stars we aspire to be! From 59d311058b488156c999504a23dddb630288d42b Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Fri, 27 Dec 2024 06:57:54 -0800 Subject: [PATCH 006/117] Update 0_repository_setup.md --- collaboration/guide/0_repository_setup.md | 38 ++++++++++++----------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/collaboration/guide/0_repository_setup.md b/collaboration/guide/0_repository_setup.md index 1e5e1aca7..dc45850d7 100644 --- a/collaboration/guide/0_repository_setup.md +++ b/collaboration/guide/0_repository_setup.md @@ -1,30 +1,31 @@ # Repository Setup -Before diving into your project make sure your team has all the practical things -in place. This step isn't very hard but everything will go more smoothly if you -take the time to do this correctly at the beginning. +Before diving into your project, make sure your team has all the practical +things in place. This step isn't very hard, but everything will go more +smoothly if you take the time to do this correctly at the beginning. ## Setup and Share a Repository -As a team you will choose the name for your team and select -someone from your team to be the repo owner. This person will fork this -repository and configure it for collaboration: +As a team, you will choose the name for your team and select someone from your +team to be the repo owner. This person will fork this repository and configure +it for collaboration: -- Public face of your repository - - Change your +- Public face of your repository: + - Change your [repository description](https://stackoverflow.com/questions/7757751/how-do-you-change-a-repository-description-on-github) - - Add or remove topics from your repository - - Update your main README with your group name and an initial overview of your project. (You can change this as much as you want.) -- Under settings in your repository select: + - Add or remove topics from your repository. + - Update your main README with your group name and an initial overview of + your project. (You can change this as much as you want.) +- Under settings in your repository, select: - _Issues_ - _Projects_ - _Always suggest updating pull request branches_ -- Collaboration Settings - - Require a code review for PRs to `main`/`master` - ([owanateamachree](https://owanateamachree.medium.com/how-to-protect-the-master-branch-on-github-ab85e9b6b03), - [github docs](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews)) - - You will need to type `master` into the _Branch name pattern_ input box. - (or type `main` if you have changed your default branch) +- Collaboration Settings: + - Require a code review for PRs to `main`/`master` + ([owanateamachree](https://owanateamachree.medium.com/how-to-protect-the-master-branch-on-github-ab85e9b6b03), + [GitHub docs](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews)) + - You will need to type `master` into the _Branch name pattern_ input box + (or type `main` if you have changed your default branch). - Select these settings to protect matching branches: - _Require approvals_ - _Dismiss stale pull request approvals when new commits are pushed_ @@ -34,5 +35,6 @@ repository and configure it for collaboration: ## README -Write the [main README](../../README.md) for your repository! You can always +Write the [main README](../../README.md) for your repository! You can always update it as you learn more about code review and collaboration on GitHub. + From 2ce302ccfb061586b76e4280d04f37ee75ca4d58 Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Fri, 27 Dec 2024 07:04:10 -0800 Subject: [PATCH 007/117] Update 0_repository_setup.md --- collaboration/guide/0_repository_setup.md | 38 +++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/collaboration/guide/0_repository_setup.md b/collaboration/guide/0_repository_setup.md index cd5fea6f9..6c89e0c90 100644 --- a/collaboration/guide/0_repository_setup.md +++ b/collaboration/guide/0_repository_setup.md @@ -1,31 +1,31 @@ # Repository Setup -Before diving into your project make sure your team has all the practical things -in place. This step isn't very hard but everything will go more smoothly if you -take the time to do this correctly at the beginning. +Before diving into your project, make sure your team has all the practical +things in place. This step isn't very hard, but everything will go more +smoothly if you take the time to do this correctly at the beginning. ## Setup and Share a Repository -As a team you will choose the name for your team and select -someone from your team to be the repo owner. This person will fork this -repository and configure it for collaboration: +As a team, you will choose the name for your team and select someone from your +team to be the repo owner. This person will fork this repository and configure +it for collaboration: -- Public face of your repository - - Change your +- Public face of your repository: + - Change your [repository description](https://stackoverflow.com/questions/7757751/how-do-you-change-a-repository-description-on-github) - - Add or remove topics from your repository - - Update your main README with your group name and an initial overview of project. - (You can change this as much as you want.) -- Under settings in your repository select: + - Add or remove topics from your repository. + - Update your main README with your group name and an initial overview of + your project. (You can change this as much as you want.) +- Under settings in your repository, select: - _Issues_ - _Projects_ - _Always suggest updating pull request branches_ -- Collaboration Settings - - Require a code review for PRs to `main`/`master` - ([owanateamachree](https://owanateamachree.medium.com/how-to-protect-the-master-branch-on-github-ab85e9b6b03), - [github docs](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews)) - - You will need to type `master` into the _Branch name pattern_ input box. - (or type `main` if you have changed your default branch) +- Collaboration Settings: + - Require a code review for PRs to `main`/`master` + ([owanateamachree](https://owanateamachree.medium.com/how-to-protect-the-master-branch-on-github-ab85e9b6b03), + [GitHub docs](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews)) + - You will need to type `master` into the _Branch name pattern_ input box + (or type `main` if you have changed your default branch). - Select these settings to protect matching branches: - _Require approvals_ - _Dismiss stale pull request approvals when new commits are pushed_ @@ -35,5 +35,5 @@ repository and configure it for collaboration: ## README -Write the [main README](../../README.md) for your repository! You can always +Write the [main README](../../README.md) for your repository! You can always update it as you learn more about code review and collaboration on GitHub. From 3a1ef2d776d95582131b36318a37ff06a74417ef Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 28 Dec 2024 03:40:41 +0300 Subject: [PATCH 008/117] first commit learning objectives --- collaboration/learning_goals.md | 59 +++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 11c583d2b..d6671b04d 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -1,5 +1,60 @@ # Learning Goals -## Collective +-Complete our first project as a cohesive team while meeting quality standards. +-Enhance programming skills through teamwork, sharing knowledge, and solving -## Individual +## Collective Goals + +1. Define standards for communication, task distribution, and code quality. + +2. Collaborate to identify and resolve bugs effectively. + +3. Practice code reviews, pair programming, and collaborative problem-solving. + +4. Utilize GitHub issues, pull requests, and project boards for transparent tracking + +5. Develop a shared understanding of deadlines and milestones using GitHub Projects. + +6. Encourage participation, mutual support, and shared accountability. + +7. Ensure clarity, active listening, and regular updates to maintain alignment. + +8. Emphasize respectful communication to keep the team focused on goals and progress. + +## Individual Goals + +**Fikre's Goals:** + + -Focus on learning structured problem-solving techniques. + -Contribute actively to discussions during code reviews. + +**Kimacia's Goals:** + + -Commit to punctuality and active participation in group meetings + -Ensure timely completion of assigned tasks + -Maintain a readiness to seek or offer assistance to team members when needed. + -Develop proficiency in debugging + -Gain a deeper understanding of code implementation and strategy. + +**Solara's Goals:** + + -Build confidence in using GitHub, VS Code, and Python effectively. + -Foster strong relationships with group members and actively learn from them + -Develop proficiency as a code reviewer and debugger. + +**Omer's Goals:** + + -Master Python basics and explore advanced concepts to write better code. + -Develop debugging skills by systematically analyzing and resolving code + -Understand and use GitHub in projects with multiple programmers contributing. + +**Nour's Goals:** + + -Focus on developing expertise in Git and GitHub to enhance personal performance. + -Improve the ability to prioritize tasks and manage time for better productivity. + +**Taher's Goals:** + + -Gain proficiency in Git and GitHub functionalities, including advanced features + -Develop a disciplined workflow by adhering to deadlines for individual contributions. + -Respond constructively to feedback and use it to improve personal contributions. From bd70404060cc2ba5f851bdba9c8eda82bbefa32e Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 28 Dec 2024 03:48:24 +0300 Subject: [PATCH 009/117] fixing md linting --- collaboration/guide/0_repository_setup.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collaboration/guide/0_repository_setup.md b/collaboration/guide/0_repository_setup.md index 4044fe979..702e41be2 100644 --- a/collaboration/guide/0_repository_setup.md +++ b/collaboration/guide/0_repository_setup.md @@ -14,7 +14,8 @@ repository and configure it for collaboration: - Change your [repository description](https://stackoverflow.com/questions/7757751/how-do-you-change-a-repository-description-on-github) - Add or remove topics from your repository - - Update your main README with your group name and an initial overview of your project. (You can change this as much as you want.) + - Update your main README with your group name and an initial overview. +(You can change this as much as you want.) - Under settings in your repository select: - _Issues_ - _Discussions_ From 42f28cb6e7aba08c7f1323e8d25bc7105ec16b92 Mon Sep 17 00:00:00 2001 From: AmmarIbrahim <3mmar2001@gmail.com> Date: Sun, 29 Dec 2024 13:58:28 +0300 Subject: [PATCH 010/117] Edit file to meet line length rule and add Ammar's learning goals --- collaboration/learning_goals.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index d6671b04d..02ee2c365 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -15,12 +15,6 @@ 5. Develop a shared understanding of deadlines and milestones using GitHub Projects. -6. Encourage participation, mutual support, and shared accountability. - -7. Ensure clarity, active listening, and regular updates to maintain alignment. - -8. Emphasize respectful communication to keep the team focused on goals and progress. - ## Individual Goals **Fikre's Goals:** @@ -58,3 +52,10 @@ -Gain proficiency in Git and GitHub functionalities, including advanced features -Develop a disciplined workflow by adhering to deadlines for individual contributions. -Respond constructively to feedback and use it to improve personal contributions. + +**Ammar's Goals:** + + - Be able to write solution code that is well-structured and easily understood by all group members + - Practice documenting and testing skills while writing the solution code for problems. + - Learn from other members' code, documentation, and tests during the review process. + - Learn from other members' reviews of my code. From 47cd4e23c1b3c338887bd55f1e57557d42466220 Mon Sep 17 00:00:00 2001 From: AmmarIbrahim <3mmar2001@gmail.com> Date: Sun, 29 Dec 2024 14:11:27 +0300 Subject: [PATCH 011/117] Edited some lines that still break line length rule --- collaboration/learning_goals.md | 67 ++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 02ee2c365..43d39126a 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -1,7 +1,10 @@ # Learning Goals --Complete our first project as a cohesive team while meeting quality standards. --Enhance programming skills through teamwork, sharing knowledge, and solving +Complete our first project as a cohesive team while meeting quality standards. + +Enhance programming skills through teamwork, sharing knowledge, and solving + +--- ## Collective Goals @@ -15,47 +18,49 @@ 5. Develop a shared understanding of deadlines and milestones using GitHub Projects. +--- + ## Individual Goals -**Fikre's Goals:** +### **Fikre's Goals:** - -Focus on learning structured problem-solving techniques. - -Contribute actively to discussions during code reviews. +- Focus on learning structured problem-solving techniques. +- Contribute actively to discussions during code reviews. -**Kimacia's Goals:** +### **Kimacia's Goals:** - -Commit to punctuality and active participation in group meetings - -Ensure timely completion of assigned tasks - -Maintain a readiness to seek or offer assistance to team members when needed. - -Develop proficiency in debugging - -Gain a deeper understanding of code implementation and strategy. +- Commit to punctuality and active participation in group meetings +- Ensure timely completion of assigned tasks +- Maintain a readiness to seek or offer assistance to team members when needed. +- Develop proficiency in debugging +- Gain a deeper understanding of code implementation and strategy. -**Solara's Goals:** +### **Solara's Goals:** - -Build confidence in using GitHub, VS Code, and Python effectively. - -Foster strong relationships with group members and actively learn from them - -Develop proficiency as a code reviewer and debugger. +- Build confidence in using GitHub, VS Code, and Python effectively. +- Foster strong relationships with group members and actively learn from them +- Develop proficiency as a code reviewer and debugger. -**Omer's Goals:** +### **Omer's Goals:** - -Master Python basics and explore advanced concepts to write better code. - -Develop debugging skills by systematically analyzing and resolving code - -Understand and use GitHub in projects with multiple programmers contributing. +- Master Python basics and explore advanced concepts to write better code. +- Develop debugging skills by systematically analyzing and resolving code +- Understand and use GitHub in projects with multiple programmers contributing. -**Nour's Goals:** +### **Nour's Goals:** - -Focus on developing expertise in Git and GitHub to enhance personal performance. - -Improve the ability to prioritize tasks and manage time for better productivity. +- Focus on developing expertise in Git and GitHub to enhance personal performance. +- Improve the ability to prioritize tasks and manage time for better productivity. -**Taher's Goals:** +### **Taher's Goals:** - -Gain proficiency in Git and GitHub functionalities, including advanced features - -Develop a disciplined workflow by adhering to deadlines for individual contributions. - -Respond constructively to feedback and use it to improve personal contributions. +- Gain proficiency in Git and GitHub functionalities, including advanced features +- Develop a disciplined workflow by adhering to deadlines for individual contributions. +- Respond constructively to feedback and use it to improve personal contributions. -**Ammar's Goals:** +### **Ammar's Goals:** - - Be able to write solution code that is well-structured and easily understood by all group members - - Practice documenting and testing skills while writing the solution code for problems. - - Learn from other members' code, documentation, and tests during the review process. - - Learn from other members' reviews of my code. +- Be able to write solution code that is well-structured and easily understood by all group members +- Practice documenting and testing skills while writing the solution code for problems. +- Learn from other members' code, documentation, and tests during the review process. +- Learn from other members' reviews of my code. From e535c029f36aab8baf2859868767ac65c1d297fb Mon Sep 17 00:00:00 2001 From: AmmarIbrahim <3mmar2001@gmail.com> Date: Sun, 29 Dec 2024 14:16:24 +0300 Subject: [PATCH 012/117] edited line 63 in learning goals file --- collaboration/learning_goals.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 43d39126a..b70d2234b 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -60,7 +60,8 @@ Enhance programming skills through teamwork, sharing knowledge, and solving ### **Ammar's Goals:** -- Be able to write solution code that is well-structured and easily understood by all group members +- Be able to write solution code that is well-structured and easily +understood by all group members - Practice documenting and testing skills while writing the solution code for problems. - Learn from other members' code, documentation, and tests during the review process. - Learn from other members' reviews of my code. From 35ff7b8d2d2b07de2f381f798b5b7a5ac7521319 Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Tue, 31 Dec 2024 14:34:36 -0800 Subject: [PATCH 013/117] Update 0_repository_setup.md --- collaboration/guide/0_repository_setup.md | 29 +++++++++++------------ 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/collaboration/guide/0_repository_setup.md b/collaboration/guide/0_repository_setup.md index d2a6e6ee2..73af94841 100644 --- a/collaboration/guide/0_repository_setup.md +++ b/collaboration/guide/0_repository_setup.md @@ -1,31 +1,31 @@ # Repository Setup -Before diving into your project, make sure your team has all the practical -things in place. This step isn't very hard, but everything will go more +Before diving into your project, make sure your team has all the practical +things in place. This step isn't very hard, but everything will go more smoothly if you take the time to do this correctly at the beginning. ## Setup and Share a Repository -As a team, you will choose the name for your team and select someone from your -team to be the repo owner. This person will fork this repository and configure +As a team, you will choose the name for your team and select someone from your +team to be the repo owner. This person will fork this repository and configure it for collaboration: - Public face of your repository: - - Change your - [repository description](https://stackoverflow.com/questions/7757751/how-do-you-change-a-repository-description-on-github) -Setting-learning-objectives + - Change your + [repository description](https://stackoverflow.com/questions/7757751/how-do-you-change-a-repository-description-on-github) + Setting-learning-objectives - Add or remove topics from your repository - - Update your main README with your group name and an initial overview. -(You can change this as much as you want.) + - Update your main README with your group name and an initial overview. + (You can change this as much as you want.) - Under settings in your repository select: - _Issues_ - _Projects_ - _Always suggest updating pull request branches_ - Collaboration Settings: - - Require a code review for PRs to `main`/`master` - ([owanateamachree](https://owanateamachree.medium.com/how-to-protect-the-master-branch-on-github-ab85e9b6b03), - [GitHub docs](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews)) - - You will need to type `master` into the _Branch name pattern_ input box + - Require a code review for PRs to `main`/`master` + ([owanateamachree](https://owanateamachree.medium.com/how-to-protect-the-master-branch-on-github-ab85e9b6b03), + [GitHub docs](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews)) + - You will need to type `master` into the _Branch name pattern_ input box (or type `main` if you have changed your default branch). - Select these settings to protect matching branches: - _Require approvals_ @@ -36,6 +36,5 @@ Setting-learning-objectives ## README -Write the [main README](../../README.md) for your repository! You can always +Write the [main README](../../README.md) for your repository! You can always update it as you learn more about code review and collaboration on GitHub. - From ddcd030b4db667a51c3ee5d20fdc4bcdd2eb1065 Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Tue, 31 Dec 2024 14:37:18 -0800 Subject: [PATCH 014/117] Update 0_repository_setup.md From 9cab6d966f951f8041a8b9a99ee614e1ace09052 Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Tue, 31 Dec 2024 14:39:04 -0800 Subject: [PATCH 015/117] Update 0_repository_setup.md --- collaboration/guide/0_repository_setup.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/collaboration/guide/0_repository_setup.md b/collaboration/guide/0_repository_setup.md index 73af94841..d27f3f8ae 100644 --- a/collaboration/guide/0_repository_setup.md +++ b/collaboration/guide/0_repository_setup.md @@ -1,11 +1,9 @@ # Repository Setup - Before diving into your project, make sure your team has all the practical things in place. This step isn't very hard, but everything will go more smoothly if you take the time to do this correctly at the beginning. ## Setup and Share a Repository - As a team, you will choose the name for your team and select someone from your team to be the repo owner. This person will fork this repository and configure it for collaboration: @@ -35,6 +33,5 @@ it for collaboration: - _Do not allow bypassing the above settings_ ## README - Write the [main README](../../README.md) for your repository! You can always update it as you learn more about code review and collaboration on GitHub. From 8f2c6fe933a6923980460fe27b1724867a669312 Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Tue, 31 Dec 2024 14:41:19 -0800 Subject: [PATCH 016/117] Update 0_repository_setup.md --- collaboration/guide/0_repository_setup.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/collaboration/guide/0_repository_setup.md b/collaboration/guide/0_repository_setup.md index d27f3f8ae..73af94841 100644 --- a/collaboration/guide/0_repository_setup.md +++ b/collaboration/guide/0_repository_setup.md @@ -1,9 +1,11 @@ # Repository Setup + Before diving into your project, make sure your team has all the practical things in place. This step isn't very hard, but everything will go more smoothly if you take the time to do this correctly at the beginning. ## Setup and Share a Repository + As a team, you will choose the name for your team and select someone from your team to be the repo owner. This person will fork this repository and configure it for collaboration: @@ -33,5 +35,6 @@ it for collaboration: - _Do not allow bypassing the above settings_ ## README + Write the [main README](../../README.md) for your repository! You can always update it as you learn more about code review and collaboration on GitHub. From 68a46abe8eae77dd4d0adaa8460f3a6489e2aaab Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Tue, 31 Dec 2024 14:47:39 -0800 Subject: [PATCH 017/117] Update 0_repository_setup.md --- collaboration/guide/0_repository_setup.md | 54 +++++++++++------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/collaboration/guide/0_repository_setup.md b/collaboration/guide/0_repository_setup.md index 73af94841..379d40845 100644 --- a/collaboration/guide/0_repository_setup.md +++ b/collaboration/guide/0_repository_setup.md @@ -1,40 +1,40 @@ # Repository Setup -Before diving into your project, make sure your team has all the practical -things in place. This step isn't very hard, but everything will go more -smoothly if you take the time to do this correctly at the beginning. +Before diving into your project, make sure your team has all the practical things in place. This step isn't very hard, but everything will go more smoothly if you take the time to do this correctly at the beginning. ## Setup and Share a Repository -As a team, you will choose the name for your team and select someone from your -team to be the repo owner. This person will fork this repository and configure -it for collaboration: +As a team, you will choose the name for your team and select someone from your team to be the repo owner. This person will fork this repository and configure it for collaboration: - Public face of your repository: - - Change your - [repository description](https://stackoverflow.com/questions/7757751/how-do-you-change-a-repository-description-on-github) - Setting-learning-objectives - - Add or remove topics from your repository - - Update your main README with your group name and an initial overview. - (You can change this as much as you want.) + - Change your repository description + (https://stackoverflow.com/questions/7757751/how-do-you-change-a-repository-description-on-github) + - Add or remove topics from your repository + - Update your main README with your group name + and an initial overview. + (You can change this as much as you want.) - Under settings in your repository select: - - _Issues_ - - _Projects_ - - _Always suggest updating pull request branches_ + - Issues + - Projects + - Always suggest updating pull request branches - Collaboration Settings: - - Require a code review for PRs to `main`/`master` - ([owanateamachree](https://owanateamachree.medium.com/how-to-protect-the-master-branch-on-github-ab85e9b6b03), - [GitHub docs](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews)) - - You will need to type `master` into the _Branch name pattern_ input box - (or type `main` if you have changed your default branch). + - Require a code review for PRs to `main`/`master` + ([owanateamachree](https://owanateamachree.medium.com/how-to-protect-the-master-branch-on-github-ab85e9b6b03), + [GitHub docs](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews)) + - You will need to type `master` into the + Branch name pattern input box + (or type `main` if you have changed your default branch). - Select these settings to protect matching branches: - - _Require approvals_ - - _Dismiss stale pull request approvals when new commits are pushed_ - - _Require approval of the most recent reviewable push_ - - _Require conversation resolution before merging_ - - _Do not allow bypassing the above settings_ + - Require approvals + - Dismiss stale pull request approvals + when new commits are pushed + - Require approval of the most recent reviewable push + - Require conversation resolution before merging + - Do not allow bypassing the above settings ## README -Write the [main README](../../README.md) for your repository! You can always -update it as you learn more about code review and collaboration on GitHub. +Write the main README ([../../README.md](../../README.md)) +for your repository! +You can always update it as you learn more about code review +and collaboration on GitHub. From cb4911b40d4fd54b00dcc3107faaf9a2aec40364 Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Tue, 31 Dec 2024 14:49:39 -0800 Subject: [PATCH 018/117] Update 0_repository_setup.md --- collaboration/guide/0_repository_setup.md | 32 ++++++++--------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/collaboration/guide/0_repository_setup.md b/collaboration/guide/0_repository_setup.md index 379d40845..7624d3d4d 100644 --- a/collaboration/guide/0_repository_setup.md +++ b/collaboration/guide/0_repository_setup.md @@ -7,34 +7,24 @@ Before diving into your project, make sure your team has all the practical thing As a team, you will choose the name for your team and select someone from your team to be the repo owner. This person will fork this repository and configure it for collaboration: - Public face of your repository: - - Change your repository description - (https://stackoverflow.com/questions/7757751/how-do-you-change-a-repository-description-on-github) + - Change your repository description (https://stackoverflow.com/questions/7757751/how-do-you-change-a-repository-description-on-github) - Add or remove topics from your repository - - Update your main README with your group name - and an initial overview. + - Update your main README with your group name and an initial overview. (You can change this as much as you want.) - Under settings in your repository select: - Issues - Projects - Always suggest updating pull request branches - Collaboration Settings: - - Require a code review for PRs to `main`/`master` - ([owanateamachree](https://owanateamachree.medium.com/how-to-protect-the-master-branch-on-github-ab85e9b6b03), - [GitHub docs](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews)) - - You will need to type `master` into the - Branch name pattern input box - (or type `main` if you have changed your default branch). - - Select these settings to protect matching branches: - - Require approvals - - Dismiss stale pull request approvals - when new commits are pushed - - Require approval of the most recent reviewable push - - Require conversation resolution before merging - - Do not allow bypassing the above settings + - Require a code review for PRs to `main`/`master` ([owanateamachree](https://owanateamachree.medium.com/how-to-protect-the-master-branch-on-github-ab85e9b6b03), [GitHub docs](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews)) + - You will need to type `master` into the Branch name pattern input box (or type `main` if you have changed your default branch). + - Select these settings to protect matching branches: + - Require approvals + - Dismiss stale pull request approvals when new commits are pushed + - Require approval of the most recent reviewable push + - Require conversation resolution before merging + - Do not allow bypassing the above settings ## README -Write the main README ([../../README.md](../../README.md)) -for your repository! -You can always update it as you learn more about code review -and collaboration on GitHub. +Write the main README ([../../README.md](../../README.md)) for your repository! You can always update it as you learn more about code review and collaboration on GitHub. From 4af317694d078e8d68a02f152f78765c7b992ed3 Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Tue, 31 Dec 2024 14:51:38 -0800 Subject: [PATCH 019/117] Update 0_repository_setup.md --- collaboration/guide/0_repository_setup.md | 50 ++++++++++++++--------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/collaboration/guide/0_repository_setup.md b/collaboration/guide/0_repository_setup.md index 7624d3d4d..a8548b977 100644 --- a/collaboration/guide/0_repository_setup.md +++ b/collaboration/guide/0_repository_setup.md @@ -1,30 +1,40 @@ # Repository Setup -Before diving into your project, make sure your team has all the practical things in place. This step isn't very hard, but everything will go more smoothly if you take the time to do this correctly at the beginning. +Before diving into your project make sure your team has all the practical things +in place. This step isn't very hard but everything will go more smoothly if you +take the time to do this correctly at the beginning. ## Setup and Share a Repository -As a team, you will choose the name for your team and select someone from your team to be the repo owner. This person will fork this repository and configure it for collaboration: +As a team you will choose the name for your team and select someone from your +team to be the repo owner. This person will fork this repository and configure +it for collaboration: + +- Public face of your repository + - Change your + [repository description](https://stackoverflow.com/questions/7757751/how-do-you-change-a-repository-description-on-github) + - Add or remove topics from your repository + - Update your main README with your group name and an initial overview of your + project. (You can change this as much as you want.) -- Public face of your repository: - - Change your repository description (https://stackoverflow.com/questions/7757751/how-do-you-change-a-repository-description-on-github) - - Add or remove topics from your repository - - Update your main README with your group name and an initial overview. - (You can change this as much as you want.) - Under settings in your repository select: - - Issues - - Projects - - Always suggest updating pull request branches -- Collaboration Settings: - - Require a code review for PRs to `main`/`master` ([owanateamachree](https://owanateamachree.medium.com/how-to-protect-the-master-branch-on-github-ab85e9b6b03), [GitHub docs](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews)) - - You will need to type `master` into the Branch name pattern input box (or type `main` if you have changed your default branch). - - Select these settings to protect matching branches: - - Require approvals - - Dismiss stale pull request approvals when new commits are pushed - - Require approval of the most recent reviewable push - - Require conversation resolution before merging - - Do not allow bypassing the above settings + - _Issues_ + - _Projects_ + - _Always suggest updating pull request branches_ +- Collaboration Settings + - Require a code review for PRs to `main`/`master` + ([owanateamachree](https://owanateamachree.medium.com/how-to-protect-the-master-branch-on-github-ab85e9b6b03), + [github docs](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews)) + - You will need to type `master` into the _Branch name pattern_ input box. + (or type `main` if you have changed your default branch) + - Select these settings to protect matching branches: + - _Require approvals_ + - _Dismiss stale pull request approvals when new commits are pushed_ + - _Require approval of the most recent reviewable push_ + - _Require conversation resolution before merging_ + - _Do not allow bypassing the above settings_ ## README -Write the main README ([../../README.md](../../README.md)) for your repository! You can always update it as you learn more about code review and collaboration on GitHub. +Write the [main README](../../README.md) for your repository! You can always +update it as you learn more about code review and collaboration on GitHub. From 54aecc9bb0da1a680ea0914ba0ddea97608cae2a Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Tue, 31 Dec 2024 16:05:51 -0800 Subject: [PATCH 020/117] update and fix the ci and markdown errors --- .github/ISSUE_TEMPLATE/help_wanted.md | 8 ++--- .github/ISSUE_TEMPLATE/meeting_agenda.md | 3 +- .github/ISSUE_TEMPLATE/new_challenge.md | 8 ++--- .github/ISSUE_TEMPLATE/question.md | 2 +- .github/PULL_REQUEST_TEMPLATE.md | 4 +-- .github/workflows/ci-checks.yml | 17 ++++++++++ collaboration/guide/0_repository_setup.md | 38 +++++++++++------------ 7 files changed, 49 insertions(+), 31 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/help_wanted.md b/.github/ISSUE_TEMPLATE/help_wanted.md index 2ee010f2e..75dbb65f7 100644 --- a/.github/ISSUE_TEMPLATE/help_wanted.md +++ b/.github/ISSUE_TEMPLATE/help_wanted.md @@ -1,10 +1,10 @@ --- name: help wanted -about: > +about: > A template issue for when you're blocked on certain lines of code. - This template has many sections to get you thinking about your problem, you don't need to fill all of them. + This template has many sections to get you thinking about your problem, + you don't need to fill all of them. labels: "help wanted" - --- -## The Code +# The Code diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index cefe7ca45..2fb0558eb 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -1,6 +1,6 @@ --- name: question -about: > +about: > A template issue for topics you'd like to discuss or learn more about. specific topics, general knowledge, it does not even need to be about code. There are no bad questions! diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 330a04cbc..7d9ab3bef 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -12,9 +12,9 @@ about: A template PR for code review with a checklist -## Behavior +# Behavior -### Files +## Files - [ ] The file name describes the function's behavior - [ ] There is a module docstring in the function file diff --git a/.github/workflows/ci-checks.yml b/.github/workflows/ci-checks.yml index d56775453..b3d7b0052 100644 --- a/.github/workflows/ci-checks.yml +++ b/.github/workflows/ci-checks.yml @@ -55,9 +55,26 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - name: python version run: python --version shell: bash + + - name: Check for test files + id: check_tests + run: | + test_files=$(find ./solutions/tests -type f -name "test_*.py") + if [ -n "$test_files" ]; then + echo "Found test files:" + echo "$test_files" + echo "has_tests=true" >> $GITHUB_OUTPUT + else + echo "No test files found matching pattern ./solutions/tests/test_*.py" + echo "has_tests=false" >> $GITHUB_OUTPUT + fi + shell: bash + - name: Python - Run Tests + if: steps.check_tests.outputs.has_tests == 'true' run: python -m unittest shell: bash diff --git a/collaboration/guide/0_repository_setup.md b/collaboration/guide/0_repository_setup.md index dc45850d7..a8548b977 100644 --- a/collaboration/guide/0_repository_setup.md +++ b/collaboration/guide/0_repository_setup.md @@ -1,31 +1,32 @@ # Repository Setup -Before diving into your project, make sure your team has all the practical -things in place. This step isn't very hard, but everything will go more -smoothly if you take the time to do this correctly at the beginning. +Before diving into your project make sure your team has all the practical things +in place. This step isn't very hard but everything will go more smoothly if you +take the time to do this correctly at the beginning. ## Setup and Share a Repository -As a team, you will choose the name for your team and select someone from your -team to be the repo owner. This person will fork this repository and configure +As a team you will choose the name for your team and select someone from your +team to be the repo owner. This person will fork this repository and configure it for collaboration: -- Public face of your repository: - - Change your +- Public face of your repository + - Change your [repository description](https://stackoverflow.com/questions/7757751/how-do-you-change-a-repository-description-on-github) - - Add or remove topics from your repository. - - Update your main README with your group name and an initial overview of - your project. (You can change this as much as you want.) -- Under settings in your repository, select: + - Add or remove topics from your repository + - Update your main README with your group name and an initial overview of your + project. (You can change this as much as you want.) + +- Under settings in your repository select: - _Issues_ - _Projects_ - _Always suggest updating pull request branches_ -- Collaboration Settings: - - Require a code review for PRs to `main`/`master` - ([owanateamachree](https://owanateamachree.medium.com/how-to-protect-the-master-branch-on-github-ab85e9b6b03), - [GitHub docs](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews)) - - You will need to type `master` into the _Branch name pattern_ input box - (or type `main` if you have changed your default branch). +- Collaboration Settings + - Require a code review for PRs to `main`/`master` + ([owanateamachree](https://owanateamachree.medium.com/how-to-protect-the-master-branch-on-github-ab85e9b6b03), + [github docs](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews)) + - You will need to type `master` into the _Branch name pattern_ input box. + (or type `main` if you have changed your default branch) - Select these settings to protect matching branches: - _Require approvals_ - _Dismiss stale pull request approvals when new commits are pushed_ @@ -35,6 +36,5 @@ it for collaboration: ## README -Write the [main README](../../README.md) for your repository! You can always +Write the [main README](../../README.md) for your repository! You can always update it as you learn more about code review and collaboration on GitHub. - From e4aa4b6ec2608abce84ac33ed1e64f12241c307b Mon Sep 17 00:00:00 2001 From: AmmarIbrahim <3mmar2001@gmail.com> Date: Wed, 1 Jan 2025 17:25:16 +0300 Subject: [PATCH 021/117] resolve_conflicts --- .github/ISSUE_TEMPLATE/help_wanted.md | 6 +++--- .github/ISSUE_TEMPLATE/meeting_agenda.md | 3 ++- .github/ISSUE_TEMPLATE/new_challenge.md | 5 ++--- .github/ISSUE_TEMPLATE/question.md | 2 +- .github/PULL_REQUEST_TEMPLATE.md | 3 +++ .github/workflows/ci-checks.yml | 17 +++++++++++++++++ .vscode/settings.json | 11 ++++++++++- collaboration/guide/0_repository_setup.md | 9 +++++---- solutions/__init__.py | 1 + solutions/tests/__init__.py | 1 + 10 files changed, 45 insertions(+), 13 deletions(-) create mode 100644 solutions/__init__.py create mode 100644 solutions/tests/__init__.py diff --git a/.github/ISSUE_TEMPLATE/help_wanted.md b/.github/ISSUE_TEMPLATE/help_wanted.md index 2ee010f2e..939dbba0a 100644 --- a/.github/ISSUE_TEMPLATE/help_wanted.md +++ b/.github/ISSUE_TEMPLATE/help_wanted.md @@ -1,10 +1,10 @@ --- name: help wanted -about: > +about: > A template issue for when you're blocked on certain lines of code. - This template has many sections to get you thinking about your problem, you don't need to fill all of them. + This template has many sections to get you thinking about your problem, + you don't need to fill all of them. labels: "help wanted" - --- -## The Code +# The Code diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index cefe7ca45..2fb0558eb 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -1,6 +1,6 @@ --- name: question -about: > +about: > A template issue for topics you'd like to discuss or learn more about. specific topics, general knowledge, it does not even need to be about code. There are no bad questions! diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 330a04cbc..2a3c33d8f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -12,9 +12,9 @@ about: A template PR for code review with a checklist -## Behavior +# Behavior -### Files +## Files - [ ] The file name describes the function's behavior - [ ] There is a module docstring in the function file @@ -55,6 +55,7 @@ about: A template PR for code review with a checklist - [ ] The function's name describes it's behavior - [ ] The function's name matches the file name - [ ] The function has correct type annotations +- [ ] The function is not called in the function file ## Strategy @@ -82,5 +83,7 @@ about: A template PR for code review with a checklist - [ ] Variable names are clear and helpful - [ ] The code follows the strategy as simply as possible - [ ] The implementation is as simple as possible given the strategy +- [ ] There are no commented lines of code +- [ ] There are no `print` statements anywhere - [ ] The code includes defensive assertions - [ ] Defensive assertions include as little logic as possible From 88ee518d14afb4d465dde0ed76fa7c588877b4b2 Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Sun, 5 Jan 2025 02:43:48 +0300 Subject: [PATCH 039/117] Update atm_test.py I have added Fikre's info into atm_test --- solutions/tests/atm_test.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/solutions/tests/atm_test.py b/solutions/tests/atm_test.py index 0871e37ef..99e8e38bf 100644 --- a/solutions/tests/atm_test.py +++ b/solutions/tests/atm_test.py @@ -1,4 +1,8 @@ -"""Unit test for the ATM""" +""" +Unit test for the ATM +Created on: 2025/01/02 +By: Fikremichael Mamo +""" import unittest from atm import show_balance, deposit, withdraw From fd7905242ba4647f2e2ff428511cd4db633ffc25 Mon Sep 17 00:00:00 2001 From: AmmarIbrahim <3mmar2001@gmail.com> Date: Sun, 5 Jan 2025 09:52:08 +0300 Subject: [PATCH 040/117] created the empty function and test files --- solutions/fahrenheit_to_kelvin.py | 0 solutions/tests/test_fahrenheit_to_kelvin.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/fahrenheit_to_kelvin.py create mode 100644 solutions/tests/test_fahrenheit_to_kelvin.py diff --git a/solutions/fahrenheit_to_kelvin.py b/solutions/fahrenheit_to_kelvin.py new file mode 100644 index 000000000..e69de29bb diff --git a/solutions/tests/test_fahrenheit_to_kelvin.py b/solutions/tests/test_fahrenheit_to_kelvin.py new file mode 100644 index 000000000..e69de29bb From 632961627bf1b7395a16ce140d45b9caa11754d7 Mon Sep 17 00:00:00 2001 From: AmmarIbrahim <3mmar2001@gmail.com> Date: Sun, 5 Jan 2025 11:11:20 +0300 Subject: [PATCH 041/117] created a function that convartes fahrenheit to kelvin and 6 unittests for it --- solutions/fahrenheit_to_kelvin.py | 42 +++++++++++++++ solutions/tests/test_fahrenheit_to_kelvin.py | 54 ++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/solutions/fahrenheit_to_kelvin.py b/solutions/fahrenheit_to_kelvin.py index e69de29bb..cd6425176 100644 --- a/solutions/fahrenheit_to_kelvin.py +++ b/solutions/fahrenheit_to_kelvin.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for converting temperature from Fahrenheit to Kelvin. + +Module contents: + - fahrenheit_to_kelvin: converts a temperature from Fahrenheit to Kelvin. + +Created on 5 1 2025 +@author: Ammar Ibrahim +""" + + +def fahrenheit_to_kelvin(fahrenheit: float) -> float: + """Convert a temperature from Fahrenheit to Kelvin. + + Parameters: + fahrenheit: float, the entered temperature in Fahrenheit. + + Returns -> float: The returned temperature in Kelvin. + + Raises: + AssertionError: if the argument is not a number (float). + + >>> fahrenheit_to_kelvin(32) + 273.15 + >>> fahrenheit_to_kelvin(212) + 373.15 + >>> fahrenheit_to_kelvin(-40) + 233.15 + """ + assert isinstance(fahrenheit, (float, int)), "Input must be a number (float)." + + # Step 1: Convert Fahrenheit to Celsius + celsius = (fahrenheit - 32) * 5 / 9 + + # Step 2: Convert Celsius to Kelvin + kelvin_accurate = celsius + 273.15 + + kelvin_with_precision = round(kelvin_accurate, 2) + + return kelvin_with_precision diff --git a/solutions/tests/test_fahrenheit_to_kelvin.py b/solutions/tests/test_fahrenheit_to_kelvin.py index e69de29bb..21e0d666c 100644 --- a/solutions/tests/test_fahrenheit_to_kelvin.py +++ b/solutions/tests/test_fahrenheit_to_kelvin.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Unit test for fahrenheit_to_kelvin function. + +Module contents: + - TestFahrenheitToKelvin: Unit test class for the fahrenheit_to_kelvin function. + +Created on 5 1 2025 +@author: Ammar Ibrahim +""" + +import unittest + +from ..fahrenheit_to_kelvin import fahrenheit_to_kelvin + + +class TestFahrenheitToKelvin(unittest.TestCase): + """Unit tests for the fahrenheit_to_kelvin function.""" + + def test_freezing_point(self): + """Test for the freezing point of water.""" + actual = fahrenheit_to_kelvin(32) + expected = 273.15 + self.assertEqual(actual, 273.15, expected) + + def test_boiling_point(self): + """Test for the boiling point of water.""" + actual = fahrenheit_to_kelvin(212) + expeted = 373.15 + self.assertEqual(actual, expeted) + + def test_negative_temperature(self): + """Test for a negative Fahrenheit temperature.""" + actual = fahrenheit_to_kelvin(-40) + expected = 233.15 + self.assertEqual(actual, expected) + + def test_zero_temperature(self): + """Test for zero Fahrenheit.""" + actual = fahrenheit_to_kelvin(0) + expected = 255.37 + self.assertEqual(actual, expected) + + def test_float_input(self): + """Test for a float tempruture input.""" + actual = fahrenheit_to_kelvin(50.5) + expected = 283.43 + self.assertEqual(actual, expected) + + def test_invalid_input_string(self): + """Test for invalid input (string).""" + with self.assertRaises(AssertionError): + fahrenheit_to_kelvin("100") From 4f498c141629cfb8a9766a0072517f5ec9ee451f Mon Sep 17 00:00:00 2001 From: Taher Date: Sun, 5 Jan 2025 12:20:59 +0300 Subject: [PATCH 042/117] Added convert decimal to binary solution and the test --- solutions/Convert_Binary_To_Decimal.py | 44 ------------------- .../tests/Test_convert_binary_to_decimal.py | 28 ------------ 2 files changed, 72 deletions(-) delete mode 100644 solutions/Convert_Binary_To_Decimal.py delete mode 100644 solutions/tests/Test_convert_binary_to_decimal.py diff --git a/solutions/Convert_Binary_To_Decimal.py b/solutions/Convert_Binary_To_Decimal.py deleted file mode 100644 index 852d34229..000000000 --- a/solutions/Convert_Binary_To_Decimal.py +++ /dev/null @@ -1,44 +0,0 @@ -"""Summery -this code is part of group 21 homework assignment for MIT-Emerging-Talent -Created 01/01/2025 -Author : Taher Shaban -""" -def conv_bin_dec(bin:str)->int: - """this function convert binary numbers to decimal -Parameters: -bin [str] : this string contain 0's and 1's represent the binary number - -return: - -dec (str): a string represent the binary number as decimal - -Raises: AssertionError: - -if the figure contains characters other than '0' or '1' - ->>> conv_bin_dec("00000110") -6 ->>> conv_bin_dec("00001111") -15 ->>> conv_bin_dec("00010010") -18 ->>> conv_bin_dec("001r001") -AssertionError:"Argument is not a binary number." -""" - bin=bin.replace(" ", "") # remove spaces from the argument - assert all(char in "01" for char in bin), "argument is not a binary number." #an assertion error raises if the argument is not a binary numbers - rev_bin = bin[::-1] # reverse the binary number from left to right - - bin_list=list(map(int, rev_bin)) # convert the argue from a string to integer list - - i=len(bin_list) - - dec=0 - - for n in range(i): - - dec+=bin_list[n]*pow(2, n) - - return dec - -#print (conv_bin_dec("00000110")) diff --git a/solutions/tests/Test_convert_binary_to_decimal.py b/solutions/tests/Test_convert_binary_to_decimal.py deleted file mode 100644 index ca9bece6e..000000000 --- a/solutions/tests/Test_convert_binary_to_decimal.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -a Unittest for the Convert_Binary_to_Decimal code. -Created on 01/01/2025 - -@author: Taher Shaban -""" - -import unittest - -from Convert_Binary_To_Decimal import conv_bin_dec -class TestConvertBinaryToDecimal(unittest.TestCase): - """Test the conv_bin_dec function""" - def test_binary_num(self): - """It should evaluate 00000110 to 6""" - actual = conv_bin_dec("00000110") # call function with test arguments - expected = 6 # hand-write the expected return value - self.assertEqual(actual, expected) - - def test_non_binary_num(self): - """It should raise an assertion error if the argument is not a binary number""" - with self.assertRaises(AssertionError): - conv_bin_dec("001r001") - - def test_binary_num_with_space(self): - """It should evaluate 00 00 01 10 to 6""" - self.assertEqual( conv_bin_dec("00 00 01 10"), 6) From d384fd2c69fee1cd8a824d18929e85139303a01d Mon Sep 17 00:00:00 2001 From: nourana819 <62513481+nourana819@users.noreply.github.com> Date: Sun, 5 Jan 2025 20:43:11 +0300 Subject: [PATCH 043/117] convert to title case --- solutions/tests/test_title_case.py | 27 +++++++++++++++++++++++++++ solutions/title_case.py | 21 +++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 solutions/tests/test_title_case.py create mode 100644 solutions/title_case.py diff --git a/solutions/tests/test_title_case.py b/solutions/tests/test_title_case.py new file mode 100644 index 000000000..99fabee64 --- /dev/null +++ b/solutions/tests/test_title_case.py @@ -0,0 +1,27 @@ +import unittest +from title_case import title_case + +class TestStringToTitleCase(unittest.TestCase): + def test_regular_sentence(self): + self.assertEqual(title_case("hello world"), "Hello World") + self.assertEqual(title_case("python is awesome"), "Python Is Awesome") + + def test_empty_string(self): + self.assertEqual(title_case(""), "") + + def test_numeric_and_text(self): + self.assertEqual(title_case("123abc"), "123abc") + + def test_mixed_case(self): + self.assertEqual(title_case("HeLLo WoRLd"), "Hello World") + + def test_special_characters(self): + self.assertEqual(title_case("hello@world"), "Hello@World") + self.assertEqual(title_case("hello-world"), "Hello-World") + self.assertEqual(title_case("hello.world"), "Hello.World") + + def test_single_word(self): + self.assertEqual(title_case("python"), "Python") + +if __name__ == "__main__": + unittest.main() diff --git a/solutions/title_case.py b/solutions/title_case.py new file mode 100644 index 000000000..bf6f6daec --- /dev/null +++ b/solutions/title_case.py @@ -0,0 +1,21 @@ +def title_case(s: str) -> str: + """ + Converts a string to title case (capitalize the first letter of each word). + + Args: + s (str): The input string. + + Returns: + str: The string converted to title case. + + Examples: + >>> string_to_title_case("hello world") + 'Hello World' + >>> string_to_title_case("PYTHON is awesome") + 'Python Is Awesome' + >>> string_to_title_case("") + '' + >>> string_to_title_case("123abc") + '123abc' + """ + return s.title() \ No newline at end of file From d96cd65b8234a38425955a9608fa32d24a4da414 Mon Sep 17 00:00:00 2001 From: nourana819 <62513481+nourana819@users.noreply.github.com> Date: Sun, 5 Jan 2025 22:30:53 +0300 Subject: [PATCH 044/117] updated file to match the checklist --- solutions/tests/test_title_case.py | 44 ++++++++++++++++++------------ solutions/title_case.py | 25 +++++++++-------- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/solutions/tests/test_title_case.py b/solutions/tests/test_title_case.py index 99fabee64..2b7f88221 100644 --- a/solutions/tests/test_title_case.py +++ b/solutions/tests/test_title_case.py @@ -1,27 +1,35 @@ -import unittest -from title_case import title_case +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +"""Unit test for title_case function.git + +Module contents: + - TestStringToTitleCase: Unit test class for the title_case function. +""" +import unittest +from ..title_case import title_case class TestStringToTitleCase(unittest.TestCase): + """ Unit test for title case function.""" + def test_regular_sentence(self): - self.assertEqual(title_case("hello world"), "Hello World") + """ test for regular sentence""" self.assertEqual(title_case("python is awesome"), "Python Is Awesome") def test_empty_string(self): + """ test for empty string""" self.assertEqual(title_case(""), "") def test_numeric_and_text(self): - self.assertEqual(title_case("123abc"), "123abc") - - def test_mixed_case(self): - self.assertEqual(title_case("HeLLo WoRLd"), "Hello World") - - def test_special_characters(self): - self.assertEqual(title_case("hello@world"), "Hello@World") - self.assertEqual(title_case("hello-world"), "Hello-World") - self.assertEqual(title_case("hello.world"), "Hello.World") - - def test_single_word(self): - self.assertEqual(title_case("python"), "Python") - -if __name__ == "__main__": - unittest.main() + """ test for numeric and text""" + self.assertEqual(title_case("123abc"), "123Abc") + + def test_invalid_input_int(self): + """Test for invalid input (integer).""" + with self.assertRaises(AssertionError): + title_case(765) + def test_invalid_input_float(self): + """Test for invalid input (float).""" + with self.assertRaises(AssertionError): + title_case(7.98) + diff --git a/solutions/title_case.py b/solutions/title_case.py index bf6f6daec..e6319b6e8 100644 --- a/solutions/title_case.py +++ b/solutions/title_case.py @@ -1,4 +1,4 @@ -def title_case(s: str) -> str: +def title_case(sentence: str) -> str: """ Converts a string to title case (capitalize the first letter of each word). @@ -8,14 +8,17 @@ def title_case(s: str) -> str: Returns: str: The string converted to title case. - Examples: - >>> string_to_title_case("hello world") - 'Hello World' - >>> string_to_title_case("PYTHON is awesome") - 'Python Is Awesome' - >>> string_to_title_case("") - '' - >>> string_to_title_case("123abc") - '123abc' + Raises: + AssertionError: If the input is not a string. + + >>> title_case("hello world") + 'Hello World' + >>> title_case("PYTHON is awesome") + 'Python Is Awesome' + >>> title_case("") + '' + >>> title_case("123abc") + '123Abc' """ - return s.title() \ No newline at end of file + assert isinstance(sentence , (str)), "Input must be a (String)." + return sentence.title() \ No newline at end of file From b614bb3b6e2445eddf9ba3e5ddfd119fc5aa9346 Mon Sep 17 00:00:00 2001 From: nourana819 <62513481+nourana819@users.noreply.github.com> Date: Sun, 5 Jan 2025 22:51:05 +0300 Subject: [PATCH 045/117] update to pass py formating CI --- solutions/tests/test_title_case.py | 4 +++- solutions/title_case.py | 20 +++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/solutions/tests/test_title_case.py b/solutions/tests/test_title_case.py index 2b7f88221..29fee048b 100644 --- a/solutions/tests/test_title_case.py +++ b/solutions/tests/test_title_case.py @@ -1,4 +1,3 @@ - #!/usr/bin/env python3 # -*- coding: utf-8 -*- @@ -6,6 +5,9 @@ Module contents: - TestStringToTitleCase: Unit test class for the title_case function. + +Created on 5 1 2025 +@author: Nour Elhuda Haidar """ import unittest from ..title_case import title_case diff --git a/solutions/title_case.py b/solutions/title_case.py index e6319b6e8..5d0327da3 100644 --- a/solutions/title_case.py +++ b/solutions/title_case.py @@ -1,9 +1,19 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for converting Sentence to title. + +Module contents: + - title_case: converts a Sentence to title. + +Created on 5 1 2025 + @author: Nour Elhuda Haidar +""" def title_case(sentence: str) -> str: - """ - Converts a string to title case (capitalize the first letter of each word). + """Converts a string to title case (capitalize the first letter of each word). - Args: - s (str): The input string. + Parameters: + sentence (str): The input string. Returns: str: The string converted to title case. @@ -20,5 +30,5 @@ def title_case(sentence: str) -> str: >>> title_case("123abc") '123Abc' """ - assert isinstance(sentence , (str)), "Input must be a (String)." + assert isinstance(sentence, str), "Input must be a string." return sentence.title() \ No newline at end of file From 8cd3d4c460d05fdc407c2ca43e5aea802a7646e3 Mon Sep 17 00:00:00 2001 From: nourana819 <62513481+nourana819@users.noreply.github.com> Date: Sun, 5 Jan 2025 23:06:45 +0300 Subject: [PATCH 046/117] new update to pass py formating CI --- solutions/tests/test_title_case.py | 1 + solutions/title_case.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/solutions/tests/test_title_case.py b/solutions/tests/test_title_case.py index 29fee048b..5d65c0d38 100644 --- a/solutions/tests/test_title_case.py +++ b/solutions/tests/test_title_case.py @@ -9,6 +9,7 @@ Created on 5 1 2025 @author: Nour Elhuda Haidar """ + import unittest from ..title_case import title_case class TestStringToTitleCase(unittest.TestCase): diff --git a/solutions/title_case.py b/solutions/title_case.py index 5d0327da3..4f1950840 100644 --- a/solutions/title_case.py +++ b/solutions/title_case.py @@ -9,8 +9,10 @@ Created on 5 1 2025 @author: Nour Elhuda Haidar """ + def title_case(sentence: str) -> str: - """Converts a string to title case (capitalize the first letter of each word). + """Converts a string to title case + (capitalize the first letter of each word). Parameters: sentence (str): The input string. From 2c877ebce2def88b83116f8873070219ee98779e Mon Sep 17 00:00:00 2001 From: nourana819 <62513481+nourana819@users.noreply.github.com> Date: Mon, 6 Jan 2025 06:47:13 +0300 Subject: [PATCH 047/117] update to pass py formating CI --- solutions/tests/test_title_case.py | 20 +++++++++++--------- solutions/title_case.py | 5 +++-- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/solutions/tests/test_title_case.py b/solutions/tests/test_title_case.py index 5d65c0d38..07ba9640e 100644 --- a/solutions/tests/test_title_case.py +++ b/solutions/tests/test_title_case.py @@ -5,34 +5,36 @@ Module contents: - TestStringToTitleCase: Unit test class for the title_case function. - + Created on 5 1 2025 @author: Nour Elhuda Haidar """ import unittest -from ..title_case import title_case +from ..title_case import title_case + + class TestStringToTitleCase(unittest.TestCase): - """ Unit test for title case function.""" - + """Unit test for title case function.""" + def test_regular_sentence(self): - """ test for regular sentence""" + """test for regular sentence""" self.assertEqual(title_case("python is awesome"), "Python Is Awesome") def test_empty_string(self): - """ test for empty string""" + """test for empty string""" self.assertEqual(title_case(""), "") def test_numeric_and_text(self): - """ test for numeric and text""" + """test for numeric and text""" self.assertEqual(title_case("123abc"), "123Abc") - + def test_invalid_input_int(self): """Test for invalid input (integer).""" with self.assertRaises(AssertionError): title_case(765) + def test_invalid_input_float(self): """Test for invalid input (float).""" with self.assertRaises(AssertionError): title_case(7.98) - diff --git a/solutions/title_case.py b/solutions/title_case.py index 4f1950840..0ae1458c7 100644 --- a/solutions/title_case.py +++ b/solutions/title_case.py @@ -10,6 +10,7 @@ @author: Nour Elhuda Haidar """ + def title_case(sentence: str) -> str: """Converts a string to title case (capitalize the first letter of each word). @@ -22,7 +23,7 @@ def title_case(sentence: str) -> str: Raises: AssertionError: If the input is not a string. - + >>> title_case("hello world") 'Hello World' >>> title_case("PYTHON is awesome") @@ -33,4 +34,4 @@ def title_case(sentence: str) -> str: '123Abc' """ assert isinstance(sentence, str), "Input must be a string." - return sentence.title() \ No newline at end of file + return sentence.title() From 937e29674a34db1d067ecedfb6831bd6d19a3f50 Mon Sep 17 00:00:00 2001 From: KimaciaJr Date: Mon, 6 Jan 2025 19:15:04 +0300 Subject: [PATCH 048/117] Add merge_two_sorted_lists function and its Unittests --- solutions/merge_two_sorted_lists | 52 +++++++++++++++++++ solutions/tests/test_merge_two_sorted_lists | 55 +++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 solutions/merge_two_sorted_lists create mode 100644 solutions/tests/test_merge_two_sorted_lists diff --git a/solutions/merge_two_sorted_lists b/solutions/merge_two_sorted_lists new file mode 100644 index 000000000..7dda1f57e --- /dev/null +++ b/solutions/merge_two_sorted_lists @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 04/01/2025 +@author: Peter Ngugi +""" + + +def merge_two_sorted_lists(l1: list, l2: list) -> list: + """ + Merges two sorted Python lists and returns a single sorted list. + + Parameters: + l1 (list): The first sorted list. + l2 (list): The second sorted list. + + Returns: + list: A single sorted list merged from the two input lists. + + Examples: + >>> merge_two_sorted_lists([1, 3, 6], [4, 8, 9]) + [1, 3, 4, 6, 8, 9] + + >>> merge_two_sorted_lists([11, 34, 41], [33, 37, 65]) + [11, 33, 34, 37, 41, 65] + + >>> merge_two_sorted_lists([], [4, 77, 90]) + [4, 77, 90] + + >>> merge_two_sorted_lists([], []) + [] + """ + if not isinstance(l1, list) or not isinstance(l2, list): + raise TypeError("Both inputs must be lists.") + + i, j = 0, 0 + merged = [] + + # Merge while there are elements in both lists + while i < len(l1) and j < len(l2): + if l1[i] <= l2[j]: + merged.append(l1[i]) + i += 1 + else: + merged.append(l2[j]) + j += 1 + + # Append any remaining elements + merged.extend(l1[i:]) + merged.extend(l2[j:]) + + return merged diff --git a/solutions/tests/test_merge_two_sorted_lists b/solutions/tests/test_merge_two_sorted_lists new file mode 100644 index 000000000..2ca803e74 --- /dev/null +++ b/solutions/tests/test_merge_two_sorted_lists @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Created on 04/01/2025 +@author: Peter Ngugi +""" + +import unittest + +from solutions import merge_two_sorted_lists + + +class TestMergeTwoLists(unittest.TestCase): + """Tests for the merge_two_sorted_lists function""" + + def test_two_single_digit_lists(self): + """Should return a single sorted list merged from the two single-digit lists""" + actual = merge_two_sorted_lists([1, 3, 5], [2, 4, 6]) + expected = [1, 2, 3, 4, 5, 6] + self.assertEqual(actual, expected) + + def test_one_list_empty(self): + """Should return a list containing values of the single list provided""" + actual = merge_two_sorted_lists([], [1, 2, 3]) + expected = [1, 2, 3] + self.assertEqual(actual, expected) + + def test_both_lists_empty(self): + """Should return an empty list""" + actual = merge_two_sorted_lists([], []) + expected = [] + self.assertEqual(actual, expected) + + def test_lists_unequal_length(self): + """Should return a single sorted list""" + actual = merge_two_sorted_lists([1, 4], [2, 3, 5, 6]) + expected = [1, 2, 3, 4, 5, 6] + self.assertEqual(actual, expected) + + def test_equal_length_lists(self): + """Should return a single sorted list when both lists have the same length""" + actual = merge_two_sorted_lists([1, 3, 5], [2, 4, 6]) + expected = [1, 2, 3, 4, 5, 6] + self.assertEqual(actual, expected) + + def test_lists_with_negatives(self): + """Should return a single sorted list with negative numbers""" + actual = merge_two_sorted_lists([-5, -2, 0], [-4, 1, 3]) + expected = [-5, -4, -2, 0, 1, 3] + self.assertEqual(actual, expected) + + +if __name__ == "__main__": + unittest.main() From ec866a248a78795097a95b8de50a4aaca9776aaf Mon Sep 17 00:00:00 2001 From: KimaciaJr Date: Mon, 6 Jan 2025 19:29:25 +0300 Subject: [PATCH 049/117] Added convert_int_to_roman function and its Unittests --- solutions/convert_int_to_roman | 61 +++++++++++++++++++++++ solutions/tests/test_convert_int_to_roman | 56 +++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 solutions/convert_int_to_roman create mode 100644 solutions/tests/test_convert_int_to_roman diff --git a/solutions/convert_int_to_roman b/solutions/convert_int_to_roman new file mode 100644 index 000000000..1a46585d9 --- /dev/null +++ b/solutions/convert_int_to_roman @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 04/01/2025 +@author: Peter Ngugi +""" + + +def convert_int_to_roman(num: int) -> str: + """ + Converts an integer to its Roman numeral representation. + + Parameters: + num (int): A non-negative integer between 1 and 3999 inclusive. + + Returns: + str: A string representing the Roman numeral corresponding to the integer. + + Raises: + ValueError: If the input is not between 1 and 3999 inclusive. + + Examples: + >>> convert_int_to_roman(5) + "V" + + >>> convert_int_to_roman(100) + "C" + + >>> convert_int_to_roman(33) + "XXXIII" + + >>> convert_int_to_roman(1) + 'I' + """ + if not (1 <= num <= 3999): + raise ValueError("Input must be between 1 and 3999") + + romans = { + 1: "I", + 4: "IV", + 5: "V", + 9: "IX", + 10: "X", + 40: "XL", + 50: "L", + 90: "XC", + 100: "C", + 400: "CD", + 500: "D", + 900: "CM", + 1000: "M", + } + + r = "" + values = sorted(romans.keys(), reverse=True) + for n in values: + while n <= num: + r += romans[n] + num -= n + + return r diff --git a/solutions/tests/test_convert_int_to_roman b/solutions/tests/test_convert_int_to_roman new file mode 100644 index 000000000..b705a0851 --- /dev/null +++ b/solutions/tests/test_convert_int_to_roman @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 04/01/2025 +@author: Peter Ngugi +""" + +import unittest + +from solutions import convert_int_to_roman + + +class TestConvertIntToRoman(unittest.TestCase): + """Test the Convert_int_to_roman function""" + + def test_single_digit_int(self): + """ "Should return a roman numeral + representation for a single digit integer""" + actual = convert_int_to_roman(7) + expected = "VII" + self.assertEqual(actual, expected) + + def test_double_digit_int(self): + """Should return a roman numeral + representation for a double-digit integer""" + actual = convert_int_to_roman(42) + expected = "XLII" + self.assertEqual(actual, expected) + + def test_triple_digit_int(self): + """Should return a roman numeral + representation for a triple-digit integer""" + actual = convert_int_to_roman(387) + expected = "CCCLXXXVII" + self.assertEqual(actual, expected) + + def test_boundary_value(self): + """Should return a roman numeral + representation for the maximum input of 3999""" + actual = convert_int_to_roman(3999) + expected = "MMMCMXCIX" + self.assertEqual(actual, expected) + + def test_invalid_input_zero(self): + """Should raise a ValueError for input less than 1""" + with self.assertRaises(ValueError): + convert_int_to_roman(0) + + def test_invalid_input_large(self): + """Should raise a ValueError for input greater than 3999""" + with self.assertRaises(ValueError): + convert_int_to_roman(4000) + + +if __name__ == "__main__": + unittest.main() From dd16e784420560d2c3cb52cf0e54569c0d3ed25b Mon Sep 17 00:00:00 2001 From: fikre Date: Mon, 6 Jan 2025 22:34:56 +0300 Subject: [PATCH 050/117] Update the atm and test_atm --- solutions/atm.py | 111 ++++++++++++++++++++++++++++++++++++ solutions/tests/atm_test.py | 60 ------------------- solutions/tests/test_atm.py | 48 ++++++++++++++++ 3 files changed, 159 insertions(+), 60 deletions(-) create mode 100644 solutions/atm.py delete mode 100644 solutions/tests/atm_test.py create mode 100644 solutions/tests/test_atm.py diff --git a/solutions/atm.py b/solutions/atm.py new file mode 100644 index 000000000..93349c618 --- /dev/null +++ b/solutions/atm.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Welcome to WIT International Bank. +This program operates the ATM system, allowing users to perform various banking transactions, +including checking their balance, depositing cash, and withdrawing money securely. + +Thank you for choosing WIT International Bank. Your satisfaction is our priority. +Created on: 2025/01/02 +By: Fikremichael Mamo +""" + + +def show_balance(balance): + """ + Display the user's current account balance. + + Parameters: + balance (float): The current balance in the user's account. + + Returns: + str: A formatted string showing the balance. + """ + return f"Your Balance is ${balance:.2f}" + + +def deposit(balance, amount): + """ + Deposit a specified amount into the user's account. + + Parameters: + balance (float): The current balance in the user's account. + amount (float): The amount to deposit. + + Returns: + float: The updated balance after the deposit. + str: An error message if the amount is invalid. + """ + if not isinstance(amount, (float, int)) or amount <= 0: + return balance, "Invalid amount! Please enter a positive number." + return balance + amount, "Deposit successful." + + +def withdraw(balance, amount): + """ + Withdraw a specified amount from the user's account. + + Parameters: + balance (float): The current balance in the user's account. + amount (float): The amount to withdraw. + + Returns: + float: The updated balance after withdrawal. + str: An error message if the operation is invalid. + """ + if amount > balance: + return balance, "Insufficient balance." + elif amount <= 0: + return balance, "Amount must be greater than 0." + return balance - amount, "Withdrawal successful." + + +def main(): + """ + Main function to operate the ATM system. + + Allows the user to perform actions such as checking balance, depositing funds, + withdrawing funds, or exiting the system. Repeats until the user chooses to exit. + """ + balance = 0.0 + + while True: + print("\nWIT ATM MENU!") + print("1. Show Balance") + print("2. Deposit") + print("3. Withdraw") + print("4. Exit") + + try: + choice = int(input("\nEnter your choice: ")) + + if choice == 1: + print(show_balance(balance)) + elif choice == 2: + try: + amount = float(input("Enter an amount to deposit: ")) + balance, message = deposit(balance, amount) + print(message) + except ValueError: + print("Invalid input! Please enter a numerical value.") + elif choice == 3: + try: + amount = float(input("Enter an amount to withdraw: ")) + balance, message = withdraw(balance, amount) + print(message) + except ValueError: + print("Invalid input! Please enter a numerical value.") + elif choice == 4: + print( + "Thank you for choosing WIT International Bank.\nThe Bank that you can always rely on." + ) + break + else: + print("That is not a valid choice.") + + except ValueError: + print("Invalid input! Please enter a number between 1 and 4.") + + +if __name__ == "__main__": + main() diff --git a/solutions/tests/atm_test.py b/solutions/tests/atm_test.py deleted file mode 100644 index 99e8e38bf..000000000 --- a/solutions/tests/atm_test.py +++ /dev/null @@ -1,60 +0,0 @@ -""" -Unit test for the ATM -Created on: 2025/01/02 -By: Fikremichael Mamo -""" - -import unittest -from atm import show_balance, deposit, withdraw - - -class TestATM(unittest.TestCase): - """ - Unit test class for ATM functions. - - Contains test cases to validate the functionality of the deposit, withdraw, - and show_balance functions under various conditions. - """ - - def test_show_balance(self): - """ - Test the show_balance function to ensure it executes without raising exceptions. - """ - try: - show_balance(100.50) - except Exception as e: - self.fail(f"show_balance raised an exception: {e}") - - def test_deposit_valid_amount(self): - """ - Test the deposit function with a valid amount to ensure the balance is updated correctly. - """ - self.assertEqual(deposit(100, 50), 150) - - def test_deposit_invalid_amount(self): - """ - Test the deposit function with an invalid (negative) amount to ensure the balance remains unchanged. - """ - self.assertEqual(deposit(100, -20), 100) - - def test_withdraw_valid_amount(self): - """ - Test the withdraw function with a valid amount to ensure the balance is updated correctly. - """ - self.assertEqual(withdraw(100, 50), 50) - - def test_withdraw_insufficient_balance(self): - """ - Test the withdraw function with an amount greater than the balance to ensure the balance remains unchanged. - """ - self.assertEqual(withdraw(100, 150), 100) - - def test_withdraw_negative_amount(self): - """ - Test the withdraw function with a negative amount to ensure the balance remains unchanged. - """ - self.assertEqual(withdraw(100, -20), 100) - - -if __name__ == "__main__": - unittest.main() diff --git a/solutions/tests/test_atm.py b/solutions/tests/test_atm.py new file mode 100644 index 000000000..29c2f1e5e --- /dev/null +++ b/solutions/tests/test_atm.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Unit test for the ATM +Created on: 2025/01/02 +By: Fikremichael Mamo +""" + +import unittest +from ..atm import show_balance, deposit, withdraw + +""" + Unit tests for ATM functions: show_balance, deposit, and withdraw. +""" + + +class TestATMFunctions(unittest.TestCase): + def test_show_balance(self): + """ + Test that show_balance correctly formats and returns the account balance. + """ + self.assertEqual(show_balance(100.50), "Your Balance is $100.50") + self.assertEqual(show_balance(0), "Your Balance is $0.00") + + def test_deposit(self): + """ + Test that deposit correctly updates the balance and handles invalid inputs. + """ + self.assertEqual(deposit(100, 50), (150, "Deposit successful.")) + self.assertEqual( + deposit(100, -10), (100, "Invalid amount! Please enter a positive number.") + ) + self.assertEqual( + deposit(100, 0), (100, "Invalid amount! Please enter a positive number.") + ) + + def test_withdraw(self): + """ + Test that withdraw correctly updates the balance and handles invalid and insufficient funds. + """ + self.assertEqual(withdraw(100, 50), (50, "Withdrawal successful.")) + self.assertEqual(withdraw(100, 150), (100, "Insufficient balance.")) + self.assertEqual(withdraw(100, -10), (100, "Amount must be greater than 0.")) + self.assertEqual(withdraw(100, 0), (100, "Amount must be greater than 0.")) + + +if __name__ == "__main__": + unittest.main() From 7f23ddd7dedd5e33ddc92e94c37d7d7659a17a2f Mon Sep 17 00:00:00 2001 From: Taher Date: Mon, 6 Jan 2025 23:30:39 +0300 Subject: [PATCH 051/117] Fix formatting issues --- solutions/Convert_Decimal_To_Binary.py | 55 ++++++++++--------- .../tests/Test_convert_decimal_to_binary.py | 6 +- 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/solutions/Convert_Decimal_To_Binary.py b/solutions/Convert_Decimal_To_Binary.py index 5d3fcd0be..dbc9baf5c 100644 --- a/solutions/Convert_Decimal_To_Binary.py +++ b/solutions/Convert_Decimal_To_Binary.py @@ -3,38 +3,41 @@ Created 01/01/2025 Author : Taher Shaban """ -def conv_dec_bin(dec:float)->int: + + +def conv_dec_bin(dec: float) -> int: """this function convert decimal numbers to binary -Parameters: -dec [int] : this string contain 0's and 1's represent the binary number + Parameters: + dec [int] : this string contain 0's and 1's represent the binary number -return: + return: -bin (int): an integral represent the binary number as decimal + bin (int): an integral represent the binary number as decimal -Raises: AssertionError: + Raises: AssertionError: -if the figure is not an integral. + if the figure is not an integral. ->>> conv_dec_int(6) -110 ->>> conv_dec_int(15) -1111 ->>> conv_dec_int(18) -"10" ->>> conv_dec_int("new") -AssertionError:"Argument is not a integral number." -""" - assert isinstance(dec,int),"argument is not a decimal number." - bin=[] - while dec>0: - bin .append(int(dec%2)) - if dec % 2 == 0 : - dec=dec/2 + >>> conv_dec_int(6) + 110 + >>> conv_dec_int(15) + 1111 + >>> conv_dec_int(18) + "10" + >>> conv_dec_int("new") + AssertionError:"Argument is not a integral number." + """ + assert isinstance(dec, int), "argument is not a decimal number." + bin = [] + while dec > 0: + bin.append(int(dec % 2)) + if dec % 2 == 0: + dec = dec / 2 else: - dec=(dec-1)/2 - bin_str="".join(map(str, bin)) - bin_str=bin_str[::-1] + dec = (dec - 1) / 2 + bin_str = "".join(map(str, bin)) + bin_str = bin_str[::-1] return bin_str -#print (conv_dec_bin(18)) + +# print (conv_dec_bin(18)) diff --git a/solutions/tests/Test_convert_decimal_to_binary.py b/solutions/tests/Test_convert_decimal_to_binary.py index 59b257dd9..483927756 100644 --- a/solutions/tests/Test_convert_decimal_to_binary.py +++ b/solutions/tests/Test_convert_decimal_to_binary.py @@ -10,11 +10,15 @@ import unittest from Convert_Decimal_To_Binary import conv_dec_bin + + class TestConvertDecimalToBinary(unittest.TestCase): """Test the conv_dec_bin function""" + def test_Decimal_num(self): """It should evaluate 6 to 110""" - self.assertEqual(conv_dec_bin(6),"110") + self.assertEqual(conv_dec_bin(6), "110") + def test_non_Decimal_num(self): """It should raise an assertion error if the argument is not a decimal number""" with self.assertRaises(AssertionError): From 25d1579859c3ac81212efbe90151cbb153e892bc Mon Sep 17 00:00:00 2001 From: fikre Date: Tue, 7 Jan 2025 01:17:27 +0300 Subject: [PATCH 052/117] fixing py_test Error --- solutions/number_guessing.py | 67 ++++++++++++++++++++ solutions/tests/atm_test.py | 60 ------------------ solutions/tests/test_number_guessing.py | 83 +++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 60 deletions(-) create mode 100644 solutions/number_guessing.py delete mode 100644 solutions/tests/atm_test.py create mode 100644 solutions/tests/test_number_guessing.py diff --git a/solutions/number_guessing.py b/solutions/number_guessing.py new file mode 100644 index 000000000..ff224221a --- /dev/null +++ b/solutions/number_guessing.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +This is a guessing random number game where you guess a number between 1 and 100. + +Created on: 2025/01/06 +@author Fikremichael Mamo +""" + +import random + + +def play_game(target_number=None, simulated_guesses=None): + """ + Play a number guessing game. + + Args: + target_number (int, optional): The target number to guess. If None, a random number between 1 and 100 is used. + simulated_guesses (list of int, optional): A list of simulated guesses to replace user input for testing purposes. + + Returns: + int: The number of attempts it took to guess the target number correctly. + """ + if target_number is None: + target_number = random.randint(1, 100) + + attempts = 0 + previous_guess_diff = None + guess_index = 0 + + # Use simulated guesses if provided, no input from user + while True: + if simulated_guesses is not None and guess_index < len(simulated_guesses): + guess = simulated_guesses[guess_index] + guess_index += 1 + else: + # If no simulated guesses are given, the game will not proceed + print("No more simulated guesses.") + break + + # Check if the guess is within the allowed range + if guess < 1 or guess > 100: + print("Please guess a number between 1 and 100.") + continue + + attempts += 1 + guess_diff = abs(guess - target_number) + + if guess < target_number: + print("Too low!") + elif guess > target_number: + print("Too high!") + else: + print(f"Congratulations! You guessed the number in {attempts} attempts.") + break + + if previous_guess_diff is not None: + if guess_diff < previous_guess_diff: + print("You're getting warmer!") + elif guess_diff > previous_guess_diff: + print("You're getting colder!") + else: + print("Start guessing!") + + previous_guess_diff = guess_diff + + return attempts # Return the number of attempts to facilitate testing diff --git a/solutions/tests/atm_test.py b/solutions/tests/atm_test.py deleted file mode 100644 index 99e8e38bf..000000000 --- a/solutions/tests/atm_test.py +++ /dev/null @@ -1,60 +0,0 @@ -""" -Unit test for the ATM -Created on: 2025/01/02 -By: Fikremichael Mamo -""" - -import unittest -from atm import show_balance, deposit, withdraw - - -class TestATM(unittest.TestCase): - """ - Unit test class for ATM functions. - - Contains test cases to validate the functionality of the deposit, withdraw, - and show_balance functions under various conditions. - """ - - def test_show_balance(self): - """ - Test the show_balance function to ensure it executes without raising exceptions. - """ - try: - show_balance(100.50) - except Exception as e: - self.fail(f"show_balance raised an exception: {e}") - - def test_deposit_valid_amount(self): - """ - Test the deposit function with a valid amount to ensure the balance is updated correctly. - """ - self.assertEqual(deposit(100, 50), 150) - - def test_deposit_invalid_amount(self): - """ - Test the deposit function with an invalid (negative) amount to ensure the balance remains unchanged. - """ - self.assertEqual(deposit(100, -20), 100) - - def test_withdraw_valid_amount(self): - """ - Test the withdraw function with a valid amount to ensure the balance is updated correctly. - """ - self.assertEqual(withdraw(100, 50), 50) - - def test_withdraw_insufficient_balance(self): - """ - Test the withdraw function with an amount greater than the balance to ensure the balance remains unchanged. - """ - self.assertEqual(withdraw(100, 150), 100) - - def test_withdraw_negative_amount(self): - """ - Test the withdraw function with a negative amount to ensure the balance remains unchanged. - """ - self.assertEqual(withdraw(100, -20), 100) - - -if __name__ == "__main__": - unittest.main() diff --git a/solutions/tests/test_number_guessing.py b/solutions/tests/test_number_guessing.py new file mode 100644 index 000000000..cb68aca8c --- /dev/null +++ b/solutions/tests/test_number_guessing.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +This is a guessing random number game where you guess a number between 1 and 100. + +Created on: 2025/01/06 +@author Fikremichael Mamo +""" + +import unittest +from ..number_guessing import ( + play_game, +) # Ensure the correct path to the `play_game` function. + + +class TestPlayGame(unittest.TestCase): + """ + Unit tests for the play_game function. + """ + + def test_correct_guess_in_one_attempt(self): + """ + Test if the game returns 1 attempt when the player guesses correctly on the first try. + """ + result = play_game(target_number=50, simulated_guesses=[50]) + self.assertEqual( + result, + 1, + "Should return 1 attempt when guessed correctly on the first try.", + ) + + def test_multiple_attempts_with_correct_guess(self): + """ + Test if the game counts the correct number of attempts when multiple guesses are required. + """ + result = play_game(target_number=30, simulated_guesses=[10, 20, 30]) + self.assertEqual( + result, + 3, + "Should return the correct number of attempts when multiple guesses are made.", + ) + + def test_all_guesses_too_low(self): + """ + Test if the game handles the case where all guesses are lower than the target number. + """ + result = play_game(target_number=50, simulated_guesses=[10, 20, 30, 40]) + self.assertEqual( + result, + 4, # Expecting 5 attempts: 4 low guesses + 1 correct guess + "Should take 5 attempts when all guesses are too low.", + ) + + def test_invalid_guesses(self): + """ + Test if the game ignores invalid guesses (e.g., less than 1 or greater than 100) + and only counts valid attempts. + """ + result = play_game(target_number=25, simulated_guesses=[-1, 101, 25]) + self.assertEqual( + result, + 1, + "Should ignore invalid guesses and return correct attempts, counting only valid guesses.", + ) + + def test_warmer_and_colder_logic(self): + """ + Test if the game provides 'warmer' and 'colder' feedback correctly based on guesses. + """ + # In this test, we expect the game to give 'warmer' feedback as the guess gets closer to 50. + result = play_game(target_number=50, simulated_guesses=[30, 40, 50]) + self.assertEqual( + result, + 3, + "Should return correct attempts including 'warmer' and 'colder' feedback.", + ) + + +if __name__ == "__main__": + """ + Entry point for running the unittests. + """ + unittest.main() From e2b0cabd43f84997c9624859f519a3a44ebd5213 Mon Sep 17 00:00:00 2001 From: omerdafaalla Date: Tue, 7 Jan 2025 01:28:23 +0300 Subject: [PATCH 053/117] Add budget calculation --- solutions/budget_calc.py | 53 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 solutions/budget_calc.py diff --git a/solutions/budget_calc.py b/solutions/budget_calc.py new file mode 100644 index 000000000..508cc279d --- /dev/null +++ b/solutions/budget_calc.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +A module for calculating + the budget distribution. + +Module contents: + calculate_budget: Calculates budget + distribution based on a total budget. + +Created on 5 1 2025 +@author: omer dafaalla +""" + + +def calculate_budget(total_budget: float) -> list: + """ + Calculates the budget distribution + for categories based on a given total budget. + + Parameters: + total_budget (float): The total + available budget, which must be + greater than 0 and less than or equal to 3000. + + Returns: + list: A list of strings containing + category names and the allocated budget amounts. + + Raises: + ValueError: If the total_budget + is not within the allowed range + (greater than 0 and less than or equal to 3000). + """ + # Defensive assertion to check if the total_budget is within the valid range + assert ( + 0 < total_budget <= 3000 + ), "Total budget must be greater than 0 and less than or equal to 3000." + + # Define the categories and corresponding percentage allocations + categories = ["Rent", "Groceries", "Savings", "Others"] + percentages = [0.4, 0.3, 0.2, 0.1] + + # List to store the results + budget_distribution = [] + + # Calculate the budget allocation for each category + for i in range(len(categories)): + allocated_budget = round(total_budget * percentages[i], 2) + budget_distribution.append(f"{categories[i]}: {allocated_budget}") + + return budget_distribution From 6bb8c6506fa7871152d37db8b6d06426c92e687a Mon Sep 17 00:00:00 2001 From: omerdafaalla Date: Tue, 7 Jan 2025 01:41:34 +0300 Subject: [PATCH 054/117] Add test cases for budget calculation --- solutions/tests/test_budget_calc.py | 62 +++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 solutions/tests/test_budget_calc.py diff --git a/solutions/tests/test_budget_calc.py b/solutions/tests/test_budget_calc.py new file mode 100644 index 000000000..f4da6728c --- /dev/null +++ b/solutions/tests/test_budget_calc.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 5 1 2025 + +@author: omer dafaalla +""" + +import unittest + +from budget_calc import calculate_budget + + +class TestCalculateBudget(unittest.TestCase): + """ + Unit test class for the calculate_budget function. + """ + + def test_valid_budget(self): + """ + Test with valid budget values. + """ + self.assertEqual( + calculate_budget(3000), + ["Rent: 1200.0", "Groceries: 900.0", "Savings: 600.0", "Others: 300.0"], + ) + self.assertEqual( + calculate_budget(1500), + ["Rent: 600.0", "Groceries: 450.0", "Savings: 300.0", "Others: 150.0"], + ) + + def test_boundary_budget(self): + """ + Test with a boundary value (e.g., + maximum allowed 3000). + """ + self.assertEqual( + calculate_budget(3000), + ["Rent: 1200.0", "Groceries: 900.0", "Savings: 600.0", "Others: 300.0"], + ) + + def test_invalid_budget_negative(self): + """ + Test with a negative budget value. + """ + with self.assertRaises(AssertionError): + calculate_budget(-500) + + def test_invalid_budget_exceeds_limit(self): + """ + Test with a budget exceeding + the upper limit. + """ + with self.assertRaises(AssertionError): + calculate_budget(3500) + + def test_invalid_budget_type(self): + """ + Test with a non-numeric type as input. + """ + with self.assertRaises(AssertionError): + calculate_budget("Not a number") From fe1fe68f9e2fd7051dd08d121879eaf3caa65352 Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Mon, 6 Jan 2025 14:50:49 -0800 Subject: [PATCH 055/117] Update test_atm.py Remove unnecessary assertion --- solutions/tests/test_atm.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/solutions/tests/test_atm.py b/solutions/tests/test_atm.py index 29c2f1e5e..2c120570a 100644 --- a/solutions/tests/test_atm.py +++ b/solutions/tests/test_atm.py @@ -20,28 +20,18 @@ def test_show_balance(self): Test that show_balance correctly formats and returns the account balance. """ self.assertEqual(show_balance(100.50), "Your Balance is $100.50") - self.assertEqual(show_balance(0), "Your Balance is $0.00") def test_deposit(self): """ Test that deposit correctly updates the balance and handles invalid inputs. """ self.assertEqual(deposit(100, 50), (150, "Deposit successful.")) - self.assertEqual( - deposit(100, -10), (100, "Invalid amount! Please enter a positive number.") - ) - self.assertEqual( - deposit(100, 0), (100, "Invalid amount! Please enter a positive number.") - ) def test_withdraw(self): """ Test that withdraw correctly updates the balance and handles invalid and insufficient funds. """ self.assertEqual(withdraw(100, 50), (50, "Withdrawal successful.")) - self.assertEqual(withdraw(100, 150), (100, "Insufficient balance.")) - self.assertEqual(withdraw(100, -10), (100, "Amount must be greater than 0.")) - self.assertEqual(withdraw(100, 0), (100, "Amount must be greater than 0.")) if __name__ == "__main__": From 6401bacc163bfb993c8bf391ee5c075a35492f4a Mon Sep 17 00:00:00 2001 From: omerdafaalla Date: Tue, 7 Jan 2025 04:17:53 +0300 Subject: [PATCH 056/117] Fix error --- solutions/budget_calc.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/solutions/budget_calc.py b/solutions/budget_calc.py index 508cc279d..58ad33537 100644 --- a/solutions/budget_calc.py +++ b/solutions/budget_calc.py @@ -21,24 +21,27 @@ def calculate_budget(total_budget: float) -> list: Parameters: total_budget (float): The total - available budget, which must be - greater than 0 and less than or equal to 3000. + available budget, which must + be greater than 0 and less than or equal to 3000. Returns: list: A list of strings containing - category names and the allocated budget amounts. + category names and the + allocated budget amounts. Raises: ValueError: If the total_budget is not within the allowed range (greater than 0 and less than or equal to 3000). """ - # Defensive assertion to check if the total_budget is within the valid range - assert ( - 0 < total_budget <= 3000 - ), "Total budget must be greater than 0 and less than or equal to 3000." - # Define the categories and corresponding percentage allocations + # Defensive check to ensure the budget is within the valid range + if not (0 < total_budget <= 3000): + raise ValueError( + "Total budget must be greater than 0 and less than or equal to 3000." + ) + + # Define the categories and their corresponding percentages categories = ["Rent", "Groceries", "Savings", "Others"] percentages = [0.4, 0.3, 0.2, 0.1] @@ -47,7 +50,7 @@ def calculate_budget(total_budget: float) -> list: # Calculate the budget allocation for each category for i in range(len(categories)): - allocated_budget = round(total_budget * percentages[i], 2) - budget_distribution.append(f"{categories[i]}: {allocated_budget}") + allocated_budget = total_budget * percentages[i] + budget_distribution.append(f"{categories[i]}: {allocated_budget:.2f}") return budget_distribution From 5f22c23a507c947235807e78ffbeb03b2dce47b3 Mon Sep 17 00:00:00 2001 From: omerdafaalla Date: Tue, 7 Jan 2025 04:20:29 +0300 Subject: [PATCH 057/117] update tests --- solutions/tests/test_budget_calc.py | 87 +++++++++++++---------------- 1 file changed, 40 insertions(+), 47 deletions(-) diff --git a/solutions/tests/test_budget_calc.py b/solutions/tests/test_budget_calc.py index f4da6728c..c13cc1acc 100644 --- a/solutions/tests/test_budget_calc.py +++ b/solutions/tests/test_budget_calc.py @@ -1,62 +1,55 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -""" -Created on 5 1 2025 +""" " + created on 5 1 2025 @author: omer dafaalla """ import unittest -from budget_calc import calculate_budget +from solutions.budget_calc import ( + calculate_budget, +) # Import the function from the budget module -class TestCalculateBudget(unittest.TestCase): +class TestBudgetCalculation(unittest.TestCase): """ - Unit test class for the calculate_budget function. + Unit tests for the `calculate_budget` function. """ - def test_valid_budget(self): - """ - Test with valid budget values. - """ - self.assertEqual( - calculate_budget(3000), - ["Rent: 1200.0", "Groceries: 900.0", "Savings: 600.0", "Others: 300.0"], - ) - self.assertEqual( - calculate_budget(1500), - ["Rent: 600.0", "Groceries: 450.0", "Savings: 300.0", "Others: 150.0"], - ) - - def test_boundary_budget(self): - """ - Test with a boundary value (e.g., - maximum allowed 3000). - """ - self.assertEqual( - calculate_budget(3000), - ["Rent: 1200.0", "Groceries: 900.0", "Savings: 600.0", "Others: 300.0"], - ) - - def test_invalid_budget_negative(self): - """ - Test with a negative budget value. - """ - with self.assertRaises(AssertionError): - calculate_budget(-500) - - def test_invalid_budget_exceeds_limit(self): - """ - Test with a budget exceeding - the upper limit. - """ - with self.assertRaises(AssertionError): + def test_budget_3000(self): + result = calculate_budget(3000) + expected = [ + "Rent: 1200.00", + "Groceries: 900.00", + "Savings: 600.00", + "Others: 300.00", + ] + self.assertEqual(result, expected) + + def test_budget_1500(self): + result = calculate_budget(1500) + expected = [ + "Rent: 600.00", + "Groceries: 450.00", + "Savings: 300.00", + "Others: 150.00", + ] + self.assertEqual(result, expected) + + def test_budget_0(self): + with self.assertRaises(ValueError): + calculate_budget(0) + + def test_budget_3500(self): + with self.assertRaises(ValueError): calculate_budget(3500) - def test_invalid_budget_type(self): - """ - Test with a non-numeric type as input. - """ - with self.assertRaises(AssertionError): - calculate_budget("Not a number") + def test_budget_negative(self): + with self.assertRaises(ValueError): + calculate_budget(-1000) + + +if __name__ == "__main__": + unittest.main() From bf08713b91cf18595a3ad92b90429c693c481fa9 Mon Sep 17 00:00:00 2001 From: KimaciaJr Date: Tue, 7 Jan 2025 09:04:19 +0300 Subject: [PATCH 058/117] Deleted the second solution --- solutions/convert_int_to_roman | 61 ----------------------- solutions/tests/test_convert_int_to_roman | 56 --------------------- 2 files changed, 117 deletions(-) delete mode 100644 solutions/convert_int_to_roman delete mode 100644 solutions/tests/test_convert_int_to_roman diff --git a/solutions/convert_int_to_roman b/solutions/convert_int_to_roman deleted file mode 100644 index 1a46585d9..000000000 --- a/solutions/convert_int_to_roman +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Created on 04/01/2025 -@author: Peter Ngugi -""" - - -def convert_int_to_roman(num: int) -> str: - """ - Converts an integer to its Roman numeral representation. - - Parameters: - num (int): A non-negative integer between 1 and 3999 inclusive. - - Returns: - str: A string representing the Roman numeral corresponding to the integer. - - Raises: - ValueError: If the input is not between 1 and 3999 inclusive. - - Examples: - >>> convert_int_to_roman(5) - "V" - - >>> convert_int_to_roman(100) - "C" - - >>> convert_int_to_roman(33) - "XXXIII" - - >>> convert_int_to_roman(1) - 'I' - """ - if not (1 <= num <= 3999): - raise ValueError("Input must be between 1 and 3999") - - romans = { - 1: "I", - 4: "IV", - 5: "V", - 9: "IX", - 10: "X", - 40: "XL", - 50: "L", - 90: "XC", - 100: "C", - 400: "CD", - 500: "D", - 900: "CM", - 1000: "M", - } - - r = "" - values = sorted(romans.keys(), reverse=True) - for n in values: - while n <= num: - r += romans[n] - num -= n - - return r diff --git a/solutions/tests/test_convert_int_to_roman b/solutions/tests/test_convert_int_to_roman deleted file mode 100644 index b705a0851..000000000 --- a/solutions/tests/test_convert_int_to_roman +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Created on 04/01/2025 -@author: Peter Ngugi -""" - -import unittest - -from solutions import convert_int_to_roman - - -class TestConvertIntToRoman(unittest.TestCase): - """Test the Convert_int_to_roman function""" - - def test_single_digit_int(self): - """ "Should return a roman numeral - representation for a single digit integer""" - actual = convert_int_to_roman(7) - expected = "VII" - self.assertEqual(actual, expected) - - def test_double_digit_int(self): - """Should return a roman numeral - representation for a double-digit integer""" - actual = convert_int_to_roman(42) - expected = "XLII" - self.assertEqual(actual, expected) - - def test_triple_digit_int(self): - """Should return a roman numeral - representation for a triple-digit integer""" - actual = convert_int_to_roman(387) - expected = "CCCLXXXVII" - self.assertEqual(actual, expected) - - def test_boundary_value(self): - """Should return a roman numeral - representation for the maximum input of 3999""" - actual = convert_int_to_roman(3999) - expected = "MMMCMXCIX" - self.assertEqual(actual, expected) - - def test_invalid_input_zero(self): - """Should raise a ValueError for input less than 1""" - with self.assertRaises(ValueError): - convert_int_to_roman(0) - - def test_invalid_input_large(self): - """Should raise a ValueError for input greater than 3999""" - with self.assertRaises(ValueError): - convert_int_to_roman(4000) - - -if __name__ == "__main__": - unittest.main() From 1570e83e58292fe128b5ce4892710016a8354ccf Mon Sep 17 00:00:00 2001 From: Collins Date: Tue, 7 Jan 2025 16:52:36 +0300 Subject: [PATCH 059/117] calculates body mass index(bmi) --- solutions/calculate_bmi.py | 44 +++++++++++++++++++++ solutions/tests/test_calculate_bmi.py | 55 +++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 solutions/calculate_bmi.py create mode 100644 solutions/tests/test_calculate_bmi.py diff --git a/solutions/calculate_bmi.py b/solutions/calculate_bmi.py new file mode 100644 index 000000000..75b684fa4 --- /dev/null +++ b/solutions/calculate_bmi.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for calculating the body mass index (BMI). + +Module contents: + - calculate_bmi: calculates the BMI of a person. + +Created on 7 1 2025 +@author: Collins Ochieng +""" + + +def calculate_bmi(weight: float, height: float) -> float: + """Calculate the body mass index (BMI) of a person. + + Parameters: + weight: float, the weight of the person in kilograms. + height: float, the height of the person in meters. + + Returns -> float: The calculated BMI. + + Raises: + AssertionError: if the arguments are not numbers (float). + ValueError: if either weight or height is less or equal to 0 + + >>> calculate_bmi(63, 1.68) + 22.32 + >>> calculate_bmi(80, 1.75) + 26.12 + >>> calculate_bmi(50, 1.50) + 22.22 + >>> calculate_bmi(69, 1.49) + 31.08 + """ + + assert isinstance(weight, (float, int)), "Weight must be a number (float)." + assert isinstance(height, (float, int)), "Height must be a number (float)." + + if weight <= 0 or height <= 0: + raise ValueError("Weight and height must be positive numbers.") + + bmi = weight / (height**2) + return round(bmi, 2) diff --git a/solutions/tests/test_calculate_bmi.py b/solutions/tests/test_calculate_bmi.py new file mode 100644 index 000000000..63bb0a63b --- /dev/null +++ b/solutions/tests/test_calculate_bmi.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Unit test for calculate_bmi function. + +Module contents: + - TestCalculateBMI: Unit test class for the calculate_bmi function. + +Test categories: + - Standards cases: double weights, double heights + - Edge cases: negative numbers, 0 + - Defensive tests: wrong input types, assertions + +Created on 7 1 2025 +@author: Collins Ochieng +""" + +import unittest + +from ..calculate_bmi import calculate_bmi + + +class TestCalculateBMI(unittest.TestCase): + """Unit test class for the calculate_bmi function.""" + + def test_underweight(self): + """Test underweight case with a BMI of 16.82.""" + self.assertEqual(calculate_bmi(52.1, 1.76), 16.82) + + def test_healthy(self): + """Test healthy case with a BMI of 21.72.""" + self.assertEqual(calculate_bmi(65.0, 1.73), 21.72) + + def test_overweight(self): + """Test overweight case with a BMI of 26.12.""" + self.assertEqual(calculate_bmi(80.0, 1.75), 26.12) + + def test_zero_values(self): + """Test zero values which raises ValueError.""" + with self.assertRaises(ValueError): + calculate_bmi(0, 1.48) + + def test_negative_values(self): + """Test negative values which raises ValueError.""" + with self.assertRaises(ValueError): + calculate_bmi(-65.11, 1.48) + + def test_string_input(self): + """Test string input which raises AssertionError.""" + with self.assertRaises(AssertionError): + calculate_bmi("65.11", 1.48) + + +if __name__ == "__main__": + unittest.main() From 918c8bb2106c2c0674335ddeed1d5023114e8d9b Mon Sep 17 00:00:00 2001 From: collyns-linc Date: Tue, 7 Jan 2025 17:04:17 +0300 Subject: [PATCH 060/117] update user name --- solutions/calculate_bmi.py | 2 +- solutions/tests/test_calculate_bmi.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solutions/calculate_bmi.py b/solutions/calculate_bmi.py index 75b684fa4..eaac7b4ab 100644 --- a/solutions/calculate_bmi.py +++ b/solutions/calculate_bmi.py @@ -6,7 +6,7 @@ Module contents: - calculate_bmi: calculates the BMI of a person. -Created on 7 1 2025 +Created on 6 1 2025 @author: Collins Ochieng """ diff --git a/solutions/tests/test_calculate_bmi.py b/solutions/tests/test_calculate_bmi.py index 63bb0a63b..e07bca9bd 100644 --- a/solutions/tests/test_calculate_bmi.py +++ b/solutions/tests/test_calculate_bmi.py @@ -11,7 +11,7 @@ - Edge cases: negative numbers, 0 - Defensive tests: wrong input types, assertions -Created on 7 1 2025 +Created on 6 1 2025 @author: Collins Ochieng """ From 43d247a3c18e96f0edf6c8b473c5ca24f0620661 Mon Sep 17 00:00:00 2001 From: omerdafaalla Date: Tue, 7 Jan 2025 17:07:03 +0300 Subject: [PATCH 061/117] Add solutions/distance.py --- solutions/distance.py | 43 ++++++++++++++++++++++++++++++++ solutions/tests/test_distance.py | 29 +++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 solutions/distance.py create mode 100644 solutions/tests/test_distance.py diff --git a/solutions/distance.py b/solutions/distance.py new file mode 100644 index 000000000..a284ca89c --- /dev/null +++ b/solutions/distance.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +distance.py + +This module provides a function + to calculate the distance between + two points in a 2D space. + + Created on 6 1 2025 + +@author: omer dafaalla + +""" + + +def calculate_distance(x1: float, y1: float, x2: float, y2: float) -> float: + """ + Calculate the distance between + two points in a 2D space. + + Parameters: + x1 (float): x-coordinate of the first point. + y1 (float): y-coordinate of the first point. + x2 (float): x-coordinate of the second point. + y2 (float): y-coordinate of the second point. + + Returns: + float: The distance between the + two points rounded to 2 decimal places. + + Examples: + >>> calculate_distance(0, 0, 3, 4) + 5.0 + >>> calculate_distance(1, 1, 4, 5) + 5.0 + """ + dx = x2 - x1 + dy = y2 - y1 + distance_squared = dx**2 + dy**2 + distance = distance_squared**0.5 + return round(distance, 2) diff --git a/solutions/tests/test_distance.py b/solutions/tests/test_distance.py new file mode 100644 index 000000000..a31de3c49 --- /dev/null +++ b/solutions/tests/test_distance.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 6 1 2025 + +@author: omer dafaalla + +""" + +import unittest + +from solutions.distance import calculate_distance + + +class TestCalculateDistance(unittest.TestCase): + """Test cases for calculate_distance function.""" + + def test_positive_coordinates(self): + """Test with positive coordinates.""" + self.assertEqual(calculate_distance(0, 0, 3, 4), 5.0) + self.assertEqual(calculate_distance(1, 1, 4, 5), 5.0) + + def test_negative_coordinates(self): + """Test with negative coordinates.""" + self.assertEqual(calculate_distance(-1, -1, -4, -5), 5.0) + + def test_same_point(self): + """Test when the points are the same.""" + self.assertEqual(calculate_distance(2, 3, 2, 3), 0.0) From 3ccb6bbe98695a2b30ba8ebfae2f5f50e2f7713f Mon Sep 17 00:00:00 2001 From: collyns-linc Date: Tue, 7 Jan 2025 19:10:09 +0300 Subject: [PATCH 062/117] a program that count words in a text --- solutions/tests/test_word_counter.py | 39 ++++++++++++++++++++++++++++ solutions/word_counter.py | 37 ++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 solutions/tests/test_word_counter.py create mode 100644 solutions/word_counter.py diff --git a/solutions/tests/test_word_counter.py b/solutions/tests/test_word_counter.py new file mode 100644 index 000000000..e3d617634 --- /dev/null +++ b/solutions/tests/test_word_counter.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Unit test for word_counter function. +Test categories: + - Standard cases: typical words, sentences + - Edge cases: empty input, empty string + - Defensive tests: wrong input types, assertions +Created on 2025-01-07 +@author: Collins Ochieng +""" + +import unittest + +from ..word_counter import word_counter + + +class TestWordCounter(unittest.TestCase): + """Unit test for word_counter function.""" + + # Standard test cases + def test_regular_sentence(self): + """It should return the number of words in a regular sentence.""" + self.assertEqual(word_counter("Hello, World!"), 2) + self.assertEqual(word_counter("Python is awesome!"), 3) + self.assertEqual(word_counter("I love programming in Python."), 5) + + # Edge cases + def test_empty_input(self): + """It should return 0 for empty input.""" + self.assertEqual(word_counter(""), 0) + + # Defensive tests + def test_wrong_input(self): + """It should raise an AssertionError for wrong input types.""" + with self.assertRaises(AssertionError): + word_counter(123) + with self.assertRaises(AssertionError): + word_counter(7.98) diff --git a/solutions/word_counter.py b/solutions/word_counter.py new file mode 100644 index 000000000..f089d03e2 --- /dev/null +++ b/solutions/word_counter.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for counting the number of words in a given text. + +Module contents: + - count_words: counts the number of words in a given text. + - main: the main function of the module. + +Created on 7 1 2025 +@author: Collins Ochieng +""" + + +def word_counter(text: str) -> int: + """ + Count the number of words in a given text. + + Parameters: + text: str, the entered text. + + Returns -> int: The number of words in the text. + + Raises: + AssertionError: if the argument is not a string. + + >>> count_words("Hello, World!") + 2 + >>> count_words("Python is awesome!") + 3 + >>> count_words("I love programming in Python.") + 5 + """ + assert isinstance(text, str), "Input must be a string." + + words = text.split() + return len(words) From 3ac5eb82ac9da813903c123e14997d96eb4aa155 Mon Sep 17 00:00:00 2001 From: collyns-linc Date: Tue, 7 Jan 2025 19:18:10 +0300 Subject: [PATCH 063/117] fix failing doctests and unittest --- solutions/tests/test_word_counter.py | 15 +++++++++++---- solutions/word_counter.py | 6 +++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/solutions/tests/test_word_counter.py b/solutions/tests/test_word_counter.py index e3d617634..15636f5b9 100644 --- a/solutions/tests/test_word_counter.py +++ b/solutions/tests/test_word_counter.py @@ -21,9 +21,8 @@ class TestWordCounter(unittest.TestCase): # Standard test cases def test_regular_sentence(self): """It should return the number of words in a regular sentence.""" - self.assertEqual(word_counter("Hello, World!"), 2) + self.assertEqual(word_counter("MIT emerging talent"), 3) self.assertEqual(word_counter("Python is awesome!"), 3) - self.assertEqual(word_counter("I love programming in Python."), 5) # Edge cases def test_empty_input(self): @@ -31,9 +30,17 @@ def test_empty_input(self): self.assertEqual(word_counter(""), 0) # Defensive tests - def test_wrong_input(self): + def test_integer_input(self): """It should raise an AssertionError for wrong input types.""" with self.assertRaises(AssertionError): word_counter(123) + + def test_list_input(self): + """It should raise an AssertionError for wrong input types.""" + with self.assertRaises(AssertionError): + word_counter(["Collins", "Ochieng", "Python"]) + + def test_dict_input(self): + """It should raise an AssertionError for wrong input types.""" with self.assertRaises(AssertionError): - word_counter(7.98) + word_counter({"Name": "Collins", "Language": "Python"}) diff --git a/solutions/word_counter.py b/solutions/word_counter.py index f089d03e2..17cd77341 100644 --- a/solutions/word_counter.py +++ b/solutions/word_counter.py @@ -24,11 +24,11 @@ def word_counter(text: str) -> int: Raises: AssertionError: if the argument is not a string. - >>> count_words("Hello, World!") + >>> word_counter("Hello, World!") 2 - >>> count_words("Python is awesome!") + >>> word_counter("Python is awesome!") 3 - >>> count_words("I love programming in Python.") + >>> word_counter("I love programming in Python.") 5 """ assert isinstance(text, str), "Input must be a string." From 654f2926dc9e91cffb23b51f93d45e8e7606af52 Mon Sep 17 00:00:00 2001 From: collyns-linc Date: Tue, 7 Jan 2025 19:22:40 +0300 Subject: [PATCH 064/117] add documentation --- solutions/word_counter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/word_counter.py b/solutions/word_counter.py index 17cd77341..a61d03d97 100644 --- a/solutions/word_counter.py +++ b/solutions/word_counter.py @@ -7,7 +7,7 @@ - count_words: counts the number of words in a given text. - main: the main function of the module. -Created on 7 1 2025 +Created on 2025-01-07 @author: Collins Ochieng """ From ed26c4d39749168fbe71e06af24093b0e77befbe Mon Sep 17 00:00:00 2001 From: collyns-linc Date: Tue, 7 Jan 2025 19:43:32 +0300 Subject: [PATCH 065/117] add edge case tests --- solutions/tests/test_word_counter.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/solutions/tests/test_word_counter.py b/solutions/tests/test_word_counter.py index 15636f5b9..76ec12a39 100644 --- a/solutions/tests/test_word_counter.py +++ b/solutions/tests/test_word_counter.py @@ -29,6 +29,10 @@ def test_empty_input(self): """It should return 0 for empty input.""" self.assertEqual(word_counter(""), 0) + def test_extra_spaces(self): + """It should return 0 for empty input.""" + self.assertEqual(word_counter(" I love Programming in Python "), 5) + # Defensive tests def test_integer_input(self): """It should raise an AssertionError for wrong input types.""" From 5011185c5dc030dc88ed93a1853afa6b6e6d1ad9 Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Tue, 7 Jan 2025 08:57:25 -0800 Subject: [PATCH 066/117] Update number_guessing.py --- solutions/number_guessing.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/solutions/number_guessing.py b/solutions/number_guessing.py index ff224221a..2521b1fdf 100644 --- a/solutions/number_guessing.py +++ b/solutions/number_guessing.py @@ -10,7 +10,7 @@ import random -def play_game(target_number=None, simulated_guesses=None): +def number_guessing(target_number=None, simulated_guesses=None): """ Play a number guessing game. @@ -40,16 +40,15 @@ def play_game(target_number=None, simulated_guesses=None): # Check if the guess is within the allowed range if guess < 1 or guess > 100: - print("Please guess a number between 1 and 100.") - continue + print(f"Invalid guess: {guess}. Please guess a number between 1 and 100.") attempts += 1 guess_diff = abs(guess - target_number) if guess < target_number: - print("Too low!") + print(f"{guess} is too low! Try guessing higher.") elif guess > target_number: - print("Too high!") + print(f"{guess} is too high! Aim low") else: print(f"Congratulations! You guessed the number in {attempts} attempts.") break From e67b3aa2bfbc09c9861cd50e5f216dfbb9adc999 Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Tue, 7 Jan 2025 09:00:30 -0800 Subject: [PATCH 067/117] Update test_number_guessing.py update function name --- solutions/tests/test_number_guessing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_number_guessing.py b/solutions/tests/test_number_guessing.py index cb68aca8c..69339f23a 100644 --- a/solutions/tests/test_number_guessing.py +++ b/solutions/tests/test_number_guessing.py @@ -9,7 +9,7 @@ import unittest from ..number_guessing import ( - play_game, + number_guessing, ) # Ensure the correct path to the `play_game` function. From 9469ac20a062439a433e45a5680d061a920b4311 Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Tue, 7 Jan 2025 09:01:44 -0800 Subject: [PATCH 068/117] Update test_number_guessing.py --- solutions/tests/test_number_guessing.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/solutions/tests/test_number_guessing.py b/solutions/tests/test_number_guessing.py index 69339f23a..9eb6ec212 100644 --- a/solutions/tests/test_number_guessing.py +++ b/solutions/tests/test_number_guessing.py @@ -10,19 +10,19 @@ import unittest from ..number_guessing import ( number_guessing, -) # Ensure the correct path to the `play_game` function. +) # Ensure the correct path to the `number_guessing` function. class TestPlayGame(unittest.TestCase): """ - Unit tests for the play_game function. + Unit tests for the number_guessing function. """ def test_correct_guess_in_one_attempt(self): """ Test if the game returns 1 attempt when the player guesses correctly on the first try. """ - result = play_game(target_number=50, simulated_guesses=[50]) + result = number_guessing(target_number=50, simulated_guesses=[50]) self.assertEqual( result, 1, @@ -33,7 +33,7 @@ def test_multiple_attempts_with_correct_guess(self): """ Test if the game counts the correct number of attempts when multiple guesses are required. """ - result = play_game(target_number=30, simulated_guesses=[10, 20, 30]) + result = number_guessing(target_number=30, simulated_guesses=[10, 20, 30]) self.assertEqual( result, 3, @@ -44,7 +44,7 @@ def test_all_guesses_too_low(self): """ Test if the game handles the case where all guesses are lower than the target number. """ - result = play_game(target_number=50, simulated_guesses=[10, 20, 30, 40]) + result = number_guessing(target_number=50, simulated_guesses=[10, 20, 30, 40]) self.assertEqual( result, 4, # Expecting 5 attempts: 4 low guesses + 1 correct guess @@ -56,7 +56,7 @@ def test_invalid_guesses(self): Test if the game ignores invalid guesses (e.g., less than 1 or greater than 100) and only counts valid attempts. """ - result = play_game(target_number=25, simulated_guesses=[-1, 101, 25]) + result = number_guessing(target_number=25, simulated_guesses=[-1, 101, 25]) self.assertEqual( result, 1, @@ -68,7 +68,7 @@ def test_warmer_and_colder_logic(self): Test if the game provides 'warmer' and 'colder' feedback correctly based on guesses. """ # In this test, we expect the game to give 'warmer' feedback as the guess gets closer to 50. - result = play_game(target_number=50, simulated_guesses=[30, 40, 50]) + result = number_guessing(target_number=50, simulated_guesses=[30, 40, 50]) self.assertEqual( result, 3, From 06376b5d7666f3a1df618200a98250a9fc7020a4 Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Tue, 7 Jan 2025 09:04:30 -0800 Subject: [PATCH 069/117] Update test_number_guessing.py --- solutions/tests/test_number_guessing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_number_guessing.py b/solutions/tests/test_number_guessing.py index 9eb6ec212..e4f67da57 100644 --- a/solutions/tests/test_number_guessing.py +++ b/solutions/tests/test_number_guessing.py @@ -59,7 +59,7 @@ def test_invalid_guesses(self): result = number_guessing(target_number=25, simulated_guesses=[-1, 101, 25]) self.assertEqual( result, - 1, + 3, "Should ignore invalid guesses and return correct attempts, counting only valid guesses.", ) From f054dc9b50c907d3846109342f7207015a64bdf1 Mon Sep 17 00:00:00 2001 From: omerdafaalla Date: Wed, 8 Jan 2025 00:12:29 +0300 Subject: [PATCH 070/117] Add update solutions and docstring,defensive assertion to tests --- solutions/distance.py | 37 ++++++++++++------ solutions/tests/test_distance.py | 66 ++++++++++++++++++++++++++++---- 2 files changed, 83 insertions(+), 20 deletions(-) diff --git a/solutions/distance.py b/solutions/distance.py index a284ca89c..4aefc3317 100644 --- a/solutions/distance.py +++ b/solutions/distance.py @@ -6,7 +6,7 @@ This module provides a function to calculate the distance between - two points in a 2D space. + two points in a 2D point. Created on 6 1 2025 @@ -18,24 +18,37 @@ def calculate_distance(x1: float, y1: float, x2: float, y2: float) -> float: """ Calculate the distance between - two points in a 2D space. + two points in a 2D point. Parameters: - x1 (float): x-coordinate of the first point. - y1 (float): y-coordinate of the first point. - x2 (float): x-coordinate of the second point. - y2 (float): y-coordinate of the second point. + - x1 (float): x-coordinate of the first point. + - y1 (float): y-coordinate of the first point. + - x2 (float): x-coordinate of the second point. + - y2 (float): y-coordinate of the second point. Returns: - float: The distance between the - two points rounded to 2 decimal places. + - float: The distance between + the two points rounded to 2 decimal places. + + Raises: + - AssertionError: If any of + the inputs are not numeric. Examples: - >>> calculate_distance(0, 0, 3, 4) - 5.0 - >>> calculate_distance(1, 1, 4, 5) - 5.0 + >>> calculate_distance(0, 0, 3, 4) + 5.0 + >>> calculate_distance(-1, -1, -4, -5) + 5.0 + >>> calculate_distance(2, 3, 2, 3) + 0.0 """ + # Defensive assertions to check if inputs are valid numbers + assert isinstance(x1, (int, float)), "x1 must be a number." + assert isinstance(y1, (int, float)), "y1 must be a number." + assert isinstance(x2, (int, float)), "x2 must be a number." + assert isinstance(y2, (int, float)), "y2 must be a number." + + # Calculate the distance dx = x2 - x1 dy = y2 - y1 distance_squared = dx**2 + dy**2 diff --git a/solutions/tests/test_distance.py b/solutions/tests/test_distance.py index a31de3c49..03e0e726a 100644 --- a/solutions/tests/test_distance.py +++ b/solutions/tests/test_distance.py @@ -13,17 +13,67 @@ class TestCalculateDistance(unittest.TestCase): - """Test cases for calculate_distance function.""" + """ + Test cases for the `calculate_distance` function. + + This class contains unit tests + for the `calculate_distance` function, + testing various scenarios + including positive coordinates, negative coordinates, + and identical points. The tests + also include checks for invalid arguments + to ensure defensive handling of edge cases. + """ def test_positive_coordinates(self): - """Test with positive coordinates.""" - self.assertEqual(calculate_distance(0, 0, 3, 4), 5.0) - self.assertEqual(calculate_distance(1, 1, 4, 5), 5.0) + """Test the function with positive coordinates.""" + self.assertEqual( + calculate_distance(0, 0, 3, 4), + 5.0, + "Distance between (0, 0) and (3, 4) should be 5.0", + ) + self.assertEqual( + calculate_distance(1, 1, 4, 5), + 5.0, + "Distance between (1, 1) and (4, 5) should be 5.0", + ) def test_negative_coordinates(self): - """Test with negative coordinates.""" - self.assertEqual(calculate_distance(-1, -1, -4, -5), 5.0) + """Test the function with negative coordinates.""" + self.assertEqual( + calculate_distance(-1, -1, -4, -5), + 5.0, + "Distance between (-1, -1) and (-4, -5) should be 5.0", + ) + self.assertEqual( + calculate_distance(-2, -3, -2, -3), + 0.0, + "Distance between the same negative points should be 0.0", + ) def test_same_point(self): - """Test when the points are the same.""" - self.assertEqual(calculate_distance(2, 3, 2, 3), 0.0) + """Test when both points are the same.""" + self.assertEqual( + calculate_distance(2, 3, 2, 3), + 0.0, + "Distance between the same points (2, 3) should be 0.0", + ) + + def test_invalid_arguments(self): + """Test defensive assertions for invalid arguments.""" + with self.assertRaises( + AssertionError, msg="Should raise AssertionError for non-numeric inputs" + ): + calculate_distance("a", 0, 3, 4) + with self.assertRaises( + AssertionError, msg="Should raise AssertionError for None inputs" + ): + calculate_distance(None, 0, 3, 4) + with self.assertRaises( + TypeError, msg="Should raise TypeError for missing arguments" + ): + calculate_distance(0, 0, 3) + with self.assertRaises( + TypeError, msg="Should raise TypeError for too many inputs" + ): + calculate_distance(0, 0, 3, 4, 5) From 6ef16803ff855d3c628677166e1150bf13f00c46 Mon Sep 17 00:00:00 2001 From: nourana819 <62513481+nourana819@users.noreply.github.com> Date: Wed, 8 Jan 2025 03:21:36 +0300 Subject: [PATCH 071/117] Counts the number of vowels in a string. --- solutions/count_vowels.py | 35 ++++++++++++++++++++++++++++ solutions/tests/test_count_vowels.py | 0 2 files changed, 35 insertions(+) create mode 100644 solutions/count_vowels.py create mode 100644 solutions/tests/test_count_vowels.py diff --git a/solutions/count_vowels.py b/solutions/count_vowels.py new file mode 100644 index 000000000..52b5d9836 --- /dev/null +++ b/solutions/count_vowels.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for counting vowels in a string. +Module contents: + - count_vowels: Counts the number of vowels in a string. + +Created on 8 1 2025 + @author: Nour Elhuda Haidar +""" + +def count_vowels(text: str) -> int: + """Counts the number of vowels (a, e, i, o, u) in the input string. + + Parameters: + text (str): The input string. + + Returns: + int: The number of vowels in the string. + + Raises: + AssertionError: If the input is not a string. + + >>> count_vowels("hello world") + 3 + >>> count_vowels("Python is awesome") + 6 + >>> count_vowels("") + 0 + >>> count_vowels("123456") + 0 + """ + assert isinstance(text, str), "Input must be a string." + vowels = "aeiouAEIOU" + return sum(1 for char in text if char in vowels) diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py new file mode 100644 index 000000000..e69de29bb From a40909a13f38c8698912f1e20613f2c8cb53d3e3 Mon Sep 17 00:00:00 2001 From: nourana819 <62513481+nourana819@users.noreply.github.com> Date: Wed, 8 Jan 2025 03:45:15 +0300 Subject: [PATCH 072/117] test updated --- LICENSE | 2 +- solutions/tests/test_count_vowels.py | 42 ++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 6e628e40e..d04b03511 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -MIT License +# MIT License Copyright (c) 2024 MIT Emerging Talent diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index e69de29bb..244039dcd 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +"""Unit test for count_vowels function. + +Module contents: + - TestCountVowels: Unit test class for the count_vowels function. + +Created on 8 1 2025 +@author: Nour Elhuda Haidar +""" + +import unittest +from ..count_vowels import count_vowels + +class TestCountVowels(unittest.TestCase): + """Unit test for count_vowels function.""" + + def test_regular_sentence(self): + """Test for a regular sentence.""" + self.assertEqual(count_vowels("python is awesome"), 6) + + def test_empty_string(self): + """Test for an empty string.""" + self.assertEqual(count_vowels(""), 0) + + def test_no_vowels(self): + """Test for a string with no vowels.""" + self.assertEqual(count_vowels("bcdfghjklmnpqrstvwxyz"), 0) + + def test_only_vowels(self): + """Test for a string with only vowels.""" + self.assertEqual(count_vowels("aeiouAEIOU"), 10) + + def test_numeric_and_text(self): + """Test for numeric and text combination.""" + self.assertEqual(count_vowels("123abc"), 1) + + def test_invalid_input_int(self): + """Test for invalid input (integer).""" + with self.assertRaises(AssertionError): + count_vowels(123) \ No newline at end of file From d3181acfbb3f1227c41cad7d4ec7477b22623457 Mon Sep 17 00:00:00 2001 From: nourana819 <62513481+nourana819@users.noreply.github.com> Date: Wed, 8 Jan 2025 03:49:38 +0300 Subject: [PATCH 073/117] updated to pass CI checks --- solutions/count_vowels.py | 1 + solutions/tests/test_count_vowels.py | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/solutions/count_vowels.py b/solutions/count_vowels.py index 52b5d9836..7e143453b 100644 --- a/solutions/count_vowels.py +++ b/solutions/count_vowels.py @@ -9,6 +9,7 @@ @author: Nour Elhuda Haidar """ + def count_vowels(text: str) -> int: """Counts the number of vowels (a, e, i, o, u) in the input string. diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index 244039dcd..3aa28a4b3 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -11,7 +11,8 @@ """ import unittest -from ..count_vowels import count_vowels +from ..count_vowels import count_vowels + class TestCountVowels(unittest.TestCase): """Unit test for count_vowels function.""" @@ -39,4 +40,4 @@ def test_numeric_and_text(self): def test_invalid_input_int(self): """Test for invalid input (integer).""" with self.assertRaises(AssertionError): - count_vowels(123) \ No newline at end of file + count_vowels(123) From 51c302eeb393e20b2032774159e2d7ea38611a65 Mon Sep 17 00:00:00 2001 From: KimaciaJr Date: Wed, 8 Jan 2025 09:23:14 +0300 Subject: [PATCH 074/117] Corrected highlighted issues in the merge_two_sorted_lists function and its unittests --- solutions/merge_two_sorted_lists | 29 ++++++++------ solutions/tests/test_merge_two_sorted_lists | 44 +++++++++++++++++++-- 2 files changed, 59 insertions(+), 14 deletions(-) diff --git a/solutions/merge_two_sorted_lists b/solutions/merge_two_sorted_lists index 7dda1f57e..89067a93a 100644 --- a/solutions/merge_two_sorted_lists +++ b/solutions/merge_two_sorted_lists @@ -3,16 +3,21 @@ """ Created on 04/01/2025 @author: Peter Ngugi + +This module provides a function to merge two sorted lists into one while maintaining sorted order. + +Function: +- merge_two_sorted_lists(list1: list, list2: list) -> list: Combines two sorted lists efficiently. """ -def merge_two_sorted_lists(l1: list, l2: list) -> list: +def merge_two_sorted_lists(list1: list, list2: list) -> list: """ Merges two sorted Python lists and returns a single sorted list. Parameters: - l1 (list): The first sorted list. - l2 (list): The second sorted list. + list1 (list): The first sorted list. + list2 (list): The second sorted list. Returns: list: A single sorted list merged from the two input lists. @@ -30,23 +35,25 @@ def merge_two_sorted_lists(l1: list, l2: list) -> list: >>> merge_two_sorted_lists([], []) [] """ - if not isinstance(l1, list) or not isinstance(l2, list): - raise TypeError("Both inputs must be lists.") + if not isinstance(list1, list) or not isinstance(list2, list): + raise TypeError( + f"Both inputs must be lists, got {type(list1).__name__} and {type(list2).__name__}." + ) i, j = 0, 0 merged = [] # Merge while there are elements in both lists - while i < len(l1) and j < len(l2): - if l1[i] <= l2[j]: - merged.append(l1[i]) + while i < len(list1) and j < len(list2): + if list1[i] <= list2[j]: + merged.append(list1[i]) i += 1 else: - merged.append(l2[j]) + merged.append(list2[j]) j += 1 # Append any remaining elements - merged.extend(l1[i:]) - merged.extend(l2[j:]) + merged.extend(list1[i:]) + merged.extend(list2[j:]) return merged diff --git a/solutions/tests/test_merge_two_sorted_lists b/solutions/tests/test_merge_two_sorted_lists index 2ca803e74..e8d8da64c 100644 --- a/solutions/tests/test_merge_two_sorted_lists +++ b/solutions/tests/test_merge_two_sorted_lists @@ -4,6 +4,11 @@ """ Created on 04/01/2025 @author: Peter Ngugi + +Unit tests for the merge_two_sorted_lists function. These tests verify the function's +ability to merge two sorted lists, handle edge cases like empty lists, support lists +with integers, floating-point numbers, and raise errors for invalid inputs like non-list types. + """ import unittest @@ -20,19 +25,19 @@ class TestMergeTwoLists(unittest.TestCase): expected = [1, 2, 3, 4, 5, 6] self.assertEqual(actual, expected) - def test_one_list_empty(self): + def test_one_empty_list(self): """Should return a list containing values of the single list provided""" actual = merge_two_sorted_lists([], [1, 2, 3]) expected = [1, 2, 3] self.assertEqual(actual, expected) - def test_both_lists_empty(self): + def test_empty_lists(self): """Should return an empty list""" actual = merge_two_sorted_lists([], []) expected = [] self.assertEqual(actual, expected) - def test_lists_unequal_length(self): + def test_unequal_length_lists(self): """Should return a single sorted list""" actual = merge_two_sorted_lists([1, 4], [2, 3, 5, 6]) expected = [1, 2, 3, 4, 5, 6] @@ -50,6 +55,39 @@ class TestMergeTwoLists(unittest.TestCase): expected = [-5, -4, -2, 0, 1, 3] self.assertEqual(actual, expected) + def test_lists_with_floats(self): + """Should return a single sorted list with floating-point numbers""" + actual = merge_two_sorted_lists([1.1, 3.3, 5.5], [2.2, 4.4, 6.6]) + expected = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6] + self.assertEqual(actual, expected) + + def test_invalid_inputs(self): + """Should raise a TypeError when inputs are not lists""" + + # First input is not a list + with self.assertRaises(TypeError): + merge_two_sorted_lists("not a list", [1, 2, 3]) + + # Second input is not a list + with self.assertRaises(TypeError): + merge_two_sorted_lists([1, 2, 3], 123) + + # Both inputs are not lists + with self.assertRaises(TypeError): + merge_two_sorted_lists("string1", "string2") + + # Lists with mixed types + with self.assertRaises(TypeError): + merge_two_sorted_lists([1, "two", 3], [4, 5, "six"]) + + # One input is None + with self.assertRaises(TypeError): + merge_two_sorted_lists(None, [1, 2, 3]) + + # Both inputs are None + with self.assertRaises(TypeError): + merge_two_sorted_lists(None, None) + if __name__ == "__main__": unittest.main() From 9fda9a4887a00f259940e9d1fcf3be390dce4f35 Mon Sep 17 00:00:00 2001 From: KimaciaJr Date: Wed, 8 Jan 2025 14:17:12 +0300 Subject: [PATCH 075/117] Updated import statement --- solutions/tests/test_merge_two_sorted_lists | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_merge_two_sorted_lists b/solutions/tests/test_merge_two_sorted_lists index e8d8da64c..99f324301 100644 --- a/solutions/tests/test_merge_two_sorted_lists +++ b/solutions/tests/test_merge_two_sorted_lists @@ -13,7 +13,7 @@ with integers, floating-point numbers, and raise errors for invalid inputs like import unittest -from solutions import merge_two_sorted_lists +from solutions.merge_two_sorted_lists import merge_two_sorted_lists class TestMergeTwoLists(unittest.TestCase): From 97b46456ad1430ccf2e8e40a2e48226273df6720 Mon Sep 17 00:00:00 2001 From: omerdafaalla Date: Wed, 8 Jan 2025 22:23:54 +0300 Subject: [PATCH 076/117] Add prisoners_dilemma --- solutions/prisoners_dilemma.py | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 solutions/prisoners_dilemma.py diff --git a/solutions/prisoners_dilemma.py b/solutions/prisoners_dilemma.py new file mode 100644 index 000000000..8f9f04edc --- /dev/null +++ b/solutions/prisoners_dilemma.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for solving the Prisoner's Dilemma. +Module contents: + - prisoners_dilemma: Solves the game + theory problem of the Prisoner's Dilemma. +Created on 8 1 2025 +@author: omer dafaalla +""" + + +def prisoners_dilemma(choice1: str, choice2: str) -> tuple: + """Solves the Prisoner's Dilemma + and returns the outcomes for both players. + + Parameters: + choice1: str, the first + player's choice ('Cooperate' or 'Defect'). + choice2: str, the second + player's choice ('Cooperate' or 'Defect'). + + Returns -> tuple: + A tuple containing two integers: the + payoff for player 1 and player 2, respectively. + + Raises: + AssertionError: if any choice is + not 'Cooperate' or 'Defect'. + + >>> prisoners_dilemma + ('Cooperate', 'Cooperate') + (3, 3) + + >>> prisoners_dilemma('Defect', 'Cooperate') + (5, 0) + + >>> prisoners_dilemma('Cooperate', 'Defect') + (0, 5) + + >>> prisoners_dilemma('Defect', 'Defect') + (1, 1) + """ + + assert choice1 in ["Cooperate", "Defect"], "Choice must be 'Cooperate' or 'Defect'." + assert choice2 in ["Cooperate", "Defect"], "Choice must be 'Cooperate' or 'Defect'." + + # Payoff matrix based on the choices + if choice1 == "Cooperate" and choice2 == "Cooperate": + return (3, 3) + elif choice1 == "Defect" and choice2 == "Cooperate": + return (5, 0) + elif choice1 == "Cooperate" and choice2 == "Defect": + return (0, 5) + elif choice1 == "Defect" and choice2 == "Defect": + return (1, 1) From 163d0073cbc2e99f3c322b26ae52302448176fab Mon Sep 17 00:00:00 2001 From: omerdafaalla Date: Wed, 8 Jan 2025 22:28:32 +0300 Subject: [PATCH 077/117] Add test_prisoners_dilemma --- solutions/tests/test_prisoners_dilemma.py | 43 +++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 solutions/tests/test_prisoners_dilemma.py diff --git a/solutions/tests/test_prisoners_dilemma.py b/solutions/tests/test_prisoners_dilemma.py new file mode 100644 index 000000000..1c94f4541 --- /dev/null +++ b/solutions/tests/test_prisoners_dilemma.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Unit test for prisoners_dilemma function. +Module contents: + - TestPrisonersDilemma: Unit test class for the solve prisoners_dilemma function. +Test categories: + - Standard cases: both players cooperate, both players defect + - Defensive tests: invalid choices (not 'Cooperate' or 'Defect') +Created on 8 1 2025 +@author: omer dafaalla +""" + +import unittest +from ..prisoners_dilemma import prisoners_dilemma + + +class TestPrisonersDilemma(unittest.TestCase): + """Unit test class for the solve_prisoners_dilemma function.""" + + def test_cooperate_cooperate(self): + """Test when both players cooperate.""" + self.assertEqual(prisoners_dilemma("Cooperate", "Cooperate"), (3, 3)) + + def test_defect_cooperate(self): + """Test when player 1 defects and player 2 cooperates.""" + self.assertEqual(prisoners_dilemma("Defect", "Cooperate"), (5, 0)) + + def test_cooperate_defect(self): + """Test when player 1 cooperates and player 2 defects.""" + self.assertEqual(prisoners_dilemma("Cooperate", "Defect"), (0, 5)) + + def test_defect_defect(self): + """Test when both players defect.""" + self.assertEqual(prisoners_dilemma("Defect", "Defect"), (1, 1)) + + def test_invalid_choice(self): + """Test invalid choices that raise AssertionError.""" + with self.assertRaises(AssertionError): + prisoners_dilemma("Collaborate", "Cooperate") + + with self.assertRaises(AssertionError): + prisoners_dilemma("Defect", "Collaborate") From 5ee431d10923765a233a04465814a11f535703e4 Mon Sep 17 00:00:00 2001 From: collyns-linc Date: Tue, 7 Jan 2025 19:10:09 +0300 Subject: [PATCH 078/117] a program that count words in a text --- solutions/tests/test_word_counter.py | 39 ++++++++++++++++++++++++++++ solutions/word_counter.py | 37 ++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 solutions/tests/test_word_counter.py create mode 100644 solutions/word_counter.py diff --git a/solutions/tests/test_word_counter.py b/solutions/tests/test_word_counter.py new file mode 100644 index 000000000..e3d617634 --- /dev/null +++ b/solutions/tests/test_word_counter.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Unit test for word_counter function. +Test categories: + - Standard cases: typical words, sentences + - Edge cases: empty input, empty string + - Defensive tests: wrong input types, assertions +Created on 2025-01-07 +@author: Collins Ochieng +""" + +import unittest + +from ..word_counter import word_counter + + +class TestWordCounter(unittest.TestCase): + """Unit test for word_counter function.""" + + # Standard test cases + def test_regular_sentence(self): + """It should return the number of words in a regular sentence.""" + self.assertEqual(word_counter("Hello, World!"), 2) + self.assertEqual(word_counter("Python is awesome!"), 3) + self.assertEqual(word_counter("I love programming in Python."), 5) + + # Edge cases + def test_empty_input(self): + """It should return 0 for empty input.""" + self.assertEqual(word_counter(""), 0) + + # Defensive tests + def test_wrong_input(self): + """It should raise an AssertionError for wrong input types.""" + with self.assertRaises(AssertionError): + word_counter(123) + with self.assertRaises(AssertionError): + word_counter(7.98) diff --git a/solutions/word_counter.py b/solutions/word_counter.py new file mode 100644 index 000000000..f089d03e2 --- /dev/null +++ b/solutions/word_counter.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for counting the number of words in a given text. + +Module contents: + - count_words: counts the number of words in a given text. + - main: the main function of the module. + +Created on 7 1 2025 +@author: Collins Ochieng +""" + + +def word_counter(text: str) -> int: + """ + Count the number of words in a given text. + + Parameters: + text: str, the entered text. + + Returns -> int: The number of words in the text. + + Raises: + AssertionError: if the argument is not a string. + + >>> count_words("Hello, World!") + 2 + >>> count_words("Python is awesome!") + 3 + >>> count_words("I love programming in Python.") + 5 + """ + assert isinstance(text, str), "Input must be a string." + + words = text.split() + return len(words) From 94b949f03c94e516ed9e286d1c84954932a6051d Mon Sep 17 00:00:00 2001 From: collyns-linc Date: Tue, 7 Jan 2025 19:18:10 +0300 Subject: [PATCH 079/117] fix failing doctests and unittest --- solutions/tests/test_word_counter.py | 15 +++++++++++---- solutions/word_counter.py | 6 +++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/solutions/tests/test_word_counter.py b/solutions/tests/test_word_counter.py index e3d617634..15636f5b9 100644 --- a/solutions/tests/test_word_counter.py +++ b/solutions/tests/test_word_counter.py @@ -21,9 +21,8 @@ class TestWordCounter(unittest.TestCase): # Standard test cases def test_regular_sentence(self): """It should return the number of words in a regular sentence.""" - self.assertEqual(word_counter("Hello, World!"), 2) + self.assertEqual(word_counter("MIT emerging talent"), 3) self.assertEqual(word_counter("Python is awesome!"), 3) - self.assertEqual(word_counter("I love programming in Python."), 5) # Edge cases def test_empty_input(self): @@ -31,9 +30,17 @@ def test_empty_input(self): self.assertEqual(word_counter(""), 0) # Defensive tests - def test_wrong_input(self): + def test_integer_input(self): """It should raise an AssertionError for wrong input types.""" with self.assertRaises(AssertionError): word_counter(123) + + def test_list_input(self): + """It should raise an AssertionError for wrong input types.""" + with self.assertRaises(AssertionError): + word_counter(["Collins", "Ochieng", "Python"]) + + def test_dict_input(self): + """It should raise an AssertionError for wrong input types.""" with self.assertRaises(AssertionError): - word_counter(7.98) + word_counter({"Name": "Collins", "Language": "Python"}) diff --git a/solutions/word_counter.py b/solutions/word_counter.py index f089d03e2..17cd77341 100644 --- a/solutions/word_counter.py +++ b/solutions/word_counter.py @@ -24,11 +24,11 @@ def word_counter(text: str) -> int: Raises: AssertionError: if the argument is not a string. - >>> count_words("Hello, World!") + >>> word_counter("Hello, World!") 2 - >>> count_words("Python is awesome!") + >>> word_counter("Python is awesome!") 3 - >>> count_words("I love programming in Python.") + >>> word_counter("I love programming in Python.") 5 """ assert isinstance(text, str), "Input must be a string." From f85a248add1cd9dfbfef4403ec90d09a946d839a Mon Sep 17 00:00:00 2001 From: collyns-linc Date: Tue, 7 Jan 2025 19:22:40 +0300 Subject: [PATCH 080/117] add documentation --- solutions/word_counter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/word_counter.py b/solutions/word_counter.py index 17cd77341..a61d03d97 100644 --- a/solutions/word_counter.py +++ b/solutions/word_counter.py @@ -7,7 +7,7 @@ - count_words: counts the number of words in a given text. - main: the main function of the module. -Created on 7 1 2025 +Created on 2025-01-07 @author: Collins Ochieng """ From 6c754fdd4edf52e261557c6883ca657e90622abc Mon Sep 17 00:00:00 2001 From: collyns-linc Date: Tue, 7 Jan 2025 19:43:32 +0300 Subject: [PATCH 081/117] add edge case tests --- solutions/tests/test_word_counter.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/solutions/tests/test_word_counter.py b/solutions/tests/test_word_counter.py index 15636f5b9..76ec12a39 100644 --- a/solutions/tests/test_word_counter.py +++ b/solutions/tests/test_word_counter.py @@ -29,6 +29,10 @@ def test_empty_input(self): """It should return 0 for empty input.""" self.assertEqual(word_counter(""), 0) + def test_extra_spaces(self): + """It should return 0 for empty input.""" + self.assertEqual(word_counter(" I love Programming in Python "), 5) + # Defensive tests def test_integer_input(self): """It should raise an AssertionError for wrong input types.""" From bf03683605d56bedc30c8151a312b7b4cf09c588 Mon Sep 17 00:00:00 2001 From: omerdafaalla Date: Tue, 7 Jan 2025 01:28:23 +0300 Subject: [PATCH 082/117] Add budget calculation --- solutions/budget_calc.py | 53 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 solutions/budget_calc.py diff --git a/solutions/budget_calc.py b/solutions/budget_calc.py new file mode 100644 index 000000000..508cc279d --- /dev/null +++ b/solutions/budget_calc.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +A module for calculating + the budget distribution. + +Module contents: + calculate_budget: Calculates budget + distribution based on a total budget. + +Created on 5 1 2025 +@author: omer dafaalla +""" + + +def calculate_budget(total_budget: float) -> list: + """ + Calculates the budget distribution + for categories based on a given total budget. + + Parameters: + total_budget (float): The total + available budget, which must be + greater than 0 and less than or equal to 3000. + + Returns: + list: A list of strings containing + category names and the allocated budget amounts. + + Raises: + ValueError: If the total_budget + is not within the allowed range + (greater than 0 and less than or equal to 3000). + """ + # Defensive assertion to check if the total_budget is within the valid range + assert ( + 0 < total_budget <= 3000 + ), "Total budget must be greater than 0 and less than or equal to 3000." + + # Define the categories and corresponding percentage allocations + categories = ["Rent", "Groceries", "Savings", "Others"] + percentages = [0.4, 0.3, 0.2, 0.1] + + # List to store the results + budget_distribution = [] + + # Calculate the budget allocation for each category + for i in range(len(categories)): + allocated_budget = round(total_budget * percentages[i], 2) + budget_distribution.append(f"{categories[i]}: {allocated_budget}") + + return budget_distribution From 4b911e36225b22a8286d161d3832c839a105e3cb Mon Sep 17 00:00:00 2001 From: omerdafaalla Date: Tue, 7 Jan 2025 01:41:34 +0300 Subject: [PATCH 083/117] Add test cases for budget calculation --- solutions/tests/test_budget_calc.py | 62 +++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 solutions/tests/test_budget_calc.py diff --git a/solutions/tests/test_budget_calc.py b/solutions/tests/test_budget_calc.py new file mode 100644 index 000000000..f4da6728c --- /dev/null +++ b/solutions/tests/test_budget_calc.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 5 1 2025 + +@author: omer dafaalla +""" + +import unittest + +from budget_calc import calculate_budget + + +class TestCalculateBudget(unittest.TestCase): + """ + Unit test class for the calculate_budget function. + """ + + def test_valid_budget(self): + """ + Test with valid budget values. + """ + self.assertEqual( + calculate_budget(3000), + ["Rent: 1200.0", "Groceries: 900.0", "Savings: 600.0", "Others: 300.0"], + ) + self.assertEqual( + calculate_budget(1500), + ["Rent: 600.0", "Groceries: 450.0", "Savings: 300.0", "Others: 150.0"], + ) + + def test_boundary_budget(self): + """ + Test with a boundary value (e.g., + maximum allowed 3000). + """ + self.assertEqual( + calculate_budget(3000), + ["Rent: 1200.0", "Groceries: 900.0", "Savings: 600.0", "Others: 300.0"], + ) + + def test_invalid_budget_negative(self): + """ + Test with a negative budget value. + """ + with self.assertRaises(AssertionError): + calculate_budget(-500) + + def test_invalid_budget_exceeds_limit(self): + """ + Test with a budget exceeding + the upper limit. + """ + with self.assertRaises(AssertionError): + calculate_budget(3500) + + def test_invalid_budget_type(self): + """ + Test with a non-numeric type as input. + """ + with self.assertRaises(AssertionError): + calculate_budget("Not a number") From 18adbfb4b1c599fdb466b4bb6b8bd26b9358b74f Mon Sep 17 00:00:00 2001 From: omerdafaalla Date: Tue, 7 Jan 2025 04:17:53 +0300 Subject: [PATCH 084/117] Fix error --- solutions/budget_calc.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/solutions/budget_calc.py b/solutions/budget_calc.py index 508cc279d..58ad33537 100644 --- a/solutions/budget_calc.py +++ b/solutions/budget_calc.py @@ -21,24 +21,27 @@ def calculate_budget(total_budget: float) -> list: Parameters: total_budget (float): The total - available budget, which must be - greater than 0 and less than or equal to 3000. + available budget, which must + be greater than 0 and less than or equal to 3000. Returns: list: A list of strings containing - category names and the allocated budget amounts. + category names and the + allocated budget amounts. Raises: ValueError: If the total_budget is not within the allowed range (greater than 0 and less than or equal to 3000). """ - # Defensive assertion to check if the total_budget is within the valid range - assert ( - 0 < total_budget <= 3000 - ), "Total budget must be greater than 0 and less than or equal to 3000." - # Define the categories and corresponding percentage allocations + # Defensive check to ensure the budget is within the valid range + if not (0 < total_budget <= 3000): + raise ValueError( + "Total budget must be greater than 0 and less than or equal to 3000." + ) + + # Define the categories and their corresponding percentages categories = ["Rent", "Groceries", "Savings", "Others"] percentages = [0.4, 0.3, 0.2, 0.1] @@ -47,7 +50,7 @@ def calculate_budget(total_budget: float) -> list: # Calculate the budget allocation for each category for i in range(len(categories)): - allocated_budget = round(total_budget * percentages[i], 2) - budget_distribution.append(f"{categories[i]}: {allocated_budget}") + allocated_budget = total_budget * percentages[i] + budget_distribution.append(f"{categories[i]}: {allocated_budget:.2f}") return budget_distribution From 4d3f4e82a375993b15b2f1357baae339593b056e Mon Sep 17 00:00:00 2001 From: omerdafaalla Date: Tue, 7 Jan 2025 04:20:29 +0300 Subject: [PATCH 085/117] update tests --- solutions/tests/test_budget_calc.py | 87 +++++++++++++---------------- 1 file changed, 40 insertions(+), 47 deletions(-) diff --git a/solutions/tests/test_budget_calc.py b/solutions/tests/test_budget_calc.py index f4da6728c..c13cc1acc 100644 --- a/solutions/tests/test_budget_calc.py +++ b/solutions/tests/test_budget_calc.py @@ -1,62 +1,55 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -""" -Created on 5 1 2025 +""" " + created on 5 1 2025 @author: omer dafaalla """ import unittest -from budget_calc import calculate_budget +from solutions.budget_calc import ( + calculate_budget, +) # Import the function from the budget module -class TestCalculateBudget(unittest.TestCase): +class TestBudgetCalculation(unittest.TestCase): """ - Unit test class for the calculate_budget function. + Unit tests for the `calculate_budget` function. """ - def test_valid_budget(self): - """ - Test with valid budget values. - """ - self.assertEqual( - calculate_budget(3000), - ["Rent: 1200.0", "Groceries: 900.0", "Savings: 600.0", "Others: 300.0"], - ) - self.assertEqual( - calculate_budget(1500), - ["Rent: 600.0", "Groceries: 450.0", "Savings: 300.0", "Others: 150.0"], - ) - - def test_boundary_budget(self): - """ - Test with a boundary value (e.g., - maximum allowed 3000). - """ - self.assertEqual( - calculate_budget(3000), - ["Rent: 1200.0", "Groceries: 900.0", "Savings: 600.0", "Others: 300.0"], - ) - - def test_invalid_budget_negative(self): - """ - Test with a negative budget value. - """ - with self.assertRaises(AssertionError): - calculate_budget(-500) - - def test_invalid_budget_exceeds_limit(self): - """ - Test with a budget exceeding - the upper limit. - """ - with self.assertRaises(AssertionError): + def test_budget_3000(self): + result = calculate_budget(3000) + expected = [ + "Rent: 1200.00", + "Groceries: 900.00", + "Savings: 600.00", + "Others: 300.00", + ] + self.assertEqual(result, expected) + + def test_budget_1500(self): + result = calculate_budget(1500) + expected = [ + "Rent: 600.00", + "Groceries: 450.00", + "Savings: 300.00", + "Others: 150.00", + ] + self.assertEqual(result, expected) + + def test_budget_0(self): + with self.assertRaises(ValueError): + calculate_budget(0) + + def test_budget_3500(self): + with self.assertRaises(ValueError): calculate_budget(3500) - def test_invalid_budget_type(self): - """ - Test with a non-numeric type as input. - """ - with self.assertRaises(AssertionError): - calculate_budget("Not a number") + def test_budget_negative(self): + with self.assertRaises(ValueError): + calculate_budget(-1000) + + +if __name__ == "__main__": + unittest.main() From b37c78cfafb45a756e94911f495b3ca2c0158680 Mon Sep 17 00:00:00 2001 From: omerdafaalla Date: Tue, 7 Jan 2025 17:07:03 +0300 Subject: [PATCH 086/117] Add solutions/distance.py --- solutions/distance.py | 43 ++++++++++++++++++++++++++++++++ solutions/tests/test_distance.py | 29 +++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 solutions/distance.py create mode 100644 solutions/tests/test_distance.py diff --git a/solutions/distance.py b/solutions/distance.py new file mode 100644 index 000000000..a284ca89c --- /dev/null +++ b/solutions/distance.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +distance.py + +This module provides a function + to calculate the distance between + two points in a 2D space. + + Created on 6 1 2025 + +@author: omer dafaalla + +""" + + +def calculate_distance(x1: float, y1: float, x2: float, y2: float) -> float: + """ + Calculate the distance between + two points in a 2D space. + + Parameters: + x1 (float): x-coordinate of the first point. + y1 (float): y-coordinate of the first point. + x2 (float): x-coordinate of the second point. + y2 (float): y-coordinate of the second point. + + Returns: + float: The distance between the + two points rounded to 2 decimal places. + + Examples: + >>> calculate_distance(0, 0, 3, 4) + 5.0 + >>> calculate_distance(1, 1, 4, 5) + 5.0 + """ + dx = x2 - x1 + dy = y2 - y1 + distance_squared = dx**2 + dy**2 + distance = distance_squared**0.5 + return round(distance, 2) diff --git a/solutions/tests/test_distance.py b/solutions/tests/test_distance.py new file mode 100644 index 000000000..a31de3c49 --- /dev/null +++ b/solutions/tests/test_distance.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 6 1 2025 + +@author: omer dafaalla + +""" + +import unittest + +from solutions.distance import calculate_distance + + +class TestCalculateDistance(unittest.TestCase): + """Test cases for calculate_distance function.""" + + def test_positive_coordinates(self): + """Test with positive coordinates.""" + self.assertEqual(calculate_distance(0, 0, 3, 4), 5.0) + self.assertEqual(calculate_distance(1, 1, 4, 5), 5.0) + + def test_negative_coordinates(self): + """Test with negative coordinates.""" + self.assertEqual(calculate_distance(-1, -1, -4, -5), 5.0) + + def test_same_point(self): + """Test when the points are the same.""" + self.assertEqual(calculate_distance(2, 3, 2, 3), 0.0) From dd314c6d76e918a79218b87b94d49a50e4e07292 Mon Sep 17 00:00:00 2001 From: omerdafaalla Date: Wed, 8 Jan 2025 00:12:29 +0300 Subject: [PATCH 087/117] Add update solutions and docstring,defensive assertion to tests --- solutions/distance.py | 37 ++++++++++++------ solutions/tests/test_distance.py | 66 ++++++++++++++++++++++++++++---- 2 files changed, 83 insertions(+), 20 deletions(-) diff --git a/solutions/distance.py b/solutions/distance.py index a284ca89c..4aefc3317 100644 --- a/solutions/distance.py +++ b/solutions/distance.py @@ -6,7 +6,7 @@ This module provides a function to calculate the distance between - two points in a 2D space. + two points in a 2D point. Created on 6 1 2025 @@ -18,24 +18,37 @@ def calculate_distance(x1: float, y1: float, x2: float, y2: float) -> float: """ Calculate the distance between - two points in a 2D space. + two points in a 2D point. Parameters: - x1 (float): x-coordinate of the first point. - y1 (float): y-coordinate of the first point. - x2 (float): x-coordinate of the second point. - y2 (float): y-coordinate of the second point. + - x1 (float): x-coordinate of the first point. + - y1 (float): y-coordinate of the first point. + - x2 (float): x-coordinate of the second point. + - y2 (float): y-coordinate of the second point. Returns: - float: The distance between the - two points rounded to 2 decimal places. + - float: The distance between + the two points rounded to 2 decimal places. + + Raises: + - AssertionError: If any of + the inputs are not numeric. Examples: - >>> calculate_distance(0, 0, 3, 4) - 5.0 - >>> calculate_distance(1, 1, 4, 5) - 5.0 + >>> calculate_distance(0, 0, 3, 4) + 5.0 + >>> calculate_distance(-1, -1, -4, -5) + 5.0 + >>> calculate_distance(2, 3, 2, 3) + 0.0 """ + # Defensive assertions to check if inputs are valid numbers + assert isinstance(x1, (int, float)), "x1 must be a number." + assert isinstance(y1, (int, float)), "y1 must be a number." + assert isinstance(x2, (int, float)), "x2 must be a number." + assert isinstance(y2, (int, float)), "y2 must be a number." + + # Calculate the distance dx = x2 - x1 dy = y2 - y1 distance_squared = dx**2 + dy**2 diff --git a/solutions/tests/test_distance.py b/solutions/tests/test_distance.py index a31de3c49..03e0e726a 100644 --- a/solutions/tests/test_distance.py +++ b/solutions/tests/test_distance.py @@ -13,17 +13,67 @@ class TestCalculateDistance(unittest.TestCase): - """Test cases for calculate_distance function.""" + """ + Test cases for the `calculate_distance` function. + + This class contains unit tests + for the `calculate_distance` function, + testing various scenarios + including positive coordinates, negative coordinates, + and identical points. The tests + also include checks for invalid arguments + to ensure defensive handling of edge cases. + """ def test_positive_coordinates(self): - """Test with positive coordinates.""" - self.assertEqual(calculate_distance(0, 0, 3, 4), 5.0) - self.assertEqual(calculate_distance(1, 1, 4, 5), 5.0) + """Test the function with positive coordinates.""" + self.assertEqual( + calculate_distance(0, 0, 3, 4), + 5.0, + "Distance between (0, 0) and (3, 4) should be 5.0", + ) + self.assertEqual( + calculate_distance(1, 1, 4, 5), + 5.0, + "Distance between (1, 1) and (4, 5) should be 5.0", + ) def test_negative_coordinates(self): - """Test with negative coordinates.""" - self.assertEqual(calculate_distance(-1, -1, -4, -5), 5.0) + """Test the function with negative coordinates.""" + self.assertEqual( + calculate_distance(-1, -1, -4, -5), + 5.0, + "Distance between (-1, -1) and (-4, -5) should be 5.0", + ) + self.assertEqual( + calculate_distance(-2, -3, -2, -3), + 0.0, + "Distance between the same negative points should be 0.0", + ) def test_same_point(self): - """Test when the points are the same.""" - self.assertEqual(calculate_distance(2, 3, 2, 3), 0.0) + """Test when both points are the same.""" + self.assertEqual( + calculate_distance(2, 3, 2, 3), + 0.0, + "Distance between the same points (2, 3) should be 0.0", + ) + + def test_invalid_arguments(self): + """Test defensive assertions for invalid arguments.""" + with self.assertRaises( + AssertionError, msg="Should raise AssertionError for non-numeric inputs" + ): + calculate_distance("a", 0, 3, 4) + with self.assertRaises( + AssertionError, msg="Should raise AssertionError for None inputs" + ): + calculate_distance(None, 0, 3, 4) + with self.assertRaises( + TypeError, msg="Should raise TypeError for missing arguments" + ): + calculate_distance(0, 0, 3) + with self.assertRaises( + TypeError, msg="Should raise TypeError for too many inputs" + ): + calculate_distance(0, 0, 3, 4, 5) From db1000cb6b11fc882671386e51a46827ad7232e0 Mon Sep 17 00:00:00 2001 From: nourana819 <62513481+nourana819@users.noreply.github.com> Date: Wed, 8 Jan 2025 03:21:36 +0300 Subject: [PATCH 088/117] Counts the number of vowels in a string. --- solutions/count_vowels.py | 35 ++++++++++++++++++++++++++++ solutions/tests/test_count_vowels.py | 0 2 files changed, 35 insertions(+) create mode 100644 solutions/count_vowels.py create mode 100644 solutions/tests/test_count_vowels.py diff --git a/solutions/count_vowels.py b/solutions/count_vowels.py new file mode 100644 index 000000000..52b5d9836 --- /dev/null +++ b/solutions/count_vowels.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for counting vowels in a string. +Module contents: + - count_vowels: Counts the number of vowels in a string. + +Created on 8 1 2025 + @author: Nour Elhuda Haidar +""" + +def count_vowels(text: str) -> int: + """Counts the number of vowels (a, e, i, o, u) in the input string. + + Parameters: + text (str): The input string. + + Returns: + int: The number of vowels in the string. + + Raises: + AssertionError: If the input is not a string. + + >>> count_vowels("hello world") + 3 + >>> count_vowels("Python is awesome") + 6 + >>> count_vowels("") + 0 + >>> count_vowels("123456") + 0 + """ + assert isinstance(text, str), "Input must be a string." + vowels = "aeiouAEIOU" + return sum(1 for char in text if char in vowels) diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py new file mode 100644 index 000000000..e69de29bb From 3930118e080ce566645648268b82ff9125c3af39 Mon Sep 17 00:00:00 2001 From: nourana819 <62513481+nourana819@users.noreply.github.com> Date: Wed, 8 Jan 2025 03:45:15 +0300 Subject: [PATCH 089/117] test updated --- LICENSE | 2 +- solutions/tests/test_count_vowels.py | 42 ++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 6e628e40e..d04b03511 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -MIT License +# MIT License Copyright (c) 2024 MIT Emerging Talent diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index e69de29bb..244039dcd 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +"""Unit test for count_vowels function. + +Module contents: + - TestCountVowels: Unit test class for the count_vowels function. + +Created on 8 1 2025 +@author: Nour Elhuda Haidar +""" + +import unittest +from ..count_vowels import count_vowels + +class TestCountVowels(unittest.TestCase): + """Unit test for count_vowels function.""" + + def test_regular_sentence(self): + """Test for a regular sentence.""" + self.assertEqual(count_vowels("python is awesome"), 6) + + def test_empty_string(self): + """Test for an empty string.""" + self.assertEqual(count_vowels(""), 0) + + def test_no_vowels(self): + """Test for a string with no vowels.""" + self.assertEqual(count_vowels("bcdfghjklmnpqrstvwxyz"), 0) + + def test_only_vowels(self): + """Test for a string with only vowels.""" + self.assertEqual(count_vowels("aeiouAEIOU"), 10) + + def test_numeric_and_text(self): + """Test for numeric and text combination.""" + self.assertEqual(count_vowels("123abc"), 1) + + def test_invalid_input_int(self): + """Test for invalid input (integer).""" + with self.assertRaises(AssertionError): + count_vowels(123) \ No newline at end of file From ba47bd14df994a8fdc2cd303afec45b7830494e7 Mon Sep 17 00:00:00 2001 From: nourana819 <62513481+nourana819@users.noreply.github.com> Date: Wed, 8 Jan 2025 03:49:38 +0300 Subject: [PATCH 090/117] updated to pass CI checks --- solutions/count_vowels.py | 1 + solutions/tests/test_count_vowels.py | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/solutions/count_vowels.py b/solutions/count_vowels.py index 52b5d9836..7e143453b 100644 --- a/solutions/count_vowels.py +++ b/solutions/count_vowels.py @@ -9,6 +9,7 @@ @author: Nour Elhuda Haidar """ + def count_vowels(text: str) -> int: """Counts the number of vowels (a, e, i, o, u) in the input string. diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index 244039dcd..3aa28a4b3 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -11,7 +11,8 @@ """ import unittest -from ..count_vowels import count_vowels +from ..count_vowels import count_vowels + class TestCountVowels(unittest.TestCase): """Unit test for count_vowels function.""" @@ -39,4 +40,4 @@ def test_numeric_and_text(self): def test_invalid_input_int(self): """Test for invalid input (integer).""" with self.assertRaises(AssertionError): - count_vowels(123) \ No newline at end of file + count_vowels(123) From 908365159243b7b3c67a5692d1bfc6fab6a83858 Mon Sep 17 00:00:00 2001 From: KimaciaJr Date: Mon, 6 Jan 2025 19:15:04 +0300 Subject: [PATCH 091/117] Add merge_two_sorted_lists function and its Unittests --- solutions/merge_two_sorted_lists | 52 +++++++++++++++++++ solutions/tests/test_merge_two_sorted_lists | 55 +++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 solutions/merge_two_sorted_lists create mode 100644 solutions/tests/test_merge_two_sorted_lists diff --git a/solutions/merge_two_sorted_lists b/solutions/merge_two_sorted_lists new file mode 100644 index 000000000..7dda1f57e --- /dev/null +++ b/solutions/merge_two_sorted_lists @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 04/01/2025 +@author: Peter Ngugi +""" + + +def merge_two_sorted_lists(l1: list, l2: list) -> list: + """ + Merges two sorted Python lists and returns a single sorted list. + + Parameters: + l1 (list): The first sorted list. + l2 (list): The second sorted list. + + Returns: + list: A single sorted list merged from the two input lists. + + Examples: + >>> merge_two_sorted_lists([1, 3, 6], [4, 8, 9]) + [1, 3, 4, 6, 8, 9] + + >>> merge_two_sorted_lists([11, 34, 41], [33, 37, 65]) + [11, 33, 34, 37, 41, 65] + + >>> merge_two_sorted_lists([], [4, 77, 90]) + [4, 77, 90] + + >>> merge_two_sorted_lists([], []) + [] + """ + if not isinstance(l1, list) or not isinstance(l2, list): + raise TypeError("Both inputs must be lists.") + + i, j = 0, 0 + merged = [] + + # Merge while there are elements in both lists + while i < len(l1) and j < len(l2): + if l1[i] <= l2[j]: + merged.append(l1[i]) + i += 1 + else: + merged.append(l2[j]) + j += 1 + + # Append any remaining elements + merged.extend(l1[i:]) + merged.extend(l2[j:]) + + return merged diff --git a/solutions/tests/test_merge_two_sorted_lists b/solutions/tests/test_merge_two_sorted_lists new file mode 100644 index 000000000..2ca803e74 --- /dev/null +++ b/solutions/tests/test_merge_two_sorted_lists @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Created on 04/01/2025 +@author: Peter Ngugi +""" + +import unittest + +from solutions import merge_two_sorted_lists + + +class TestMergeTwoLists(unittest.TestCase): + """Tests for the merge_two_sorted_lists function""" + + def test_two_single_digit_lists(self): + """Should return a single sorted list merged from the two single-digit lists""" + actual = merge_two_sorted_lists([1, 3, 5], [2, 4, 6]) + expected = [1, 2, 3, 4, 5, 6] + self.assertEqual(actual, expected) + + def test_one_list_empty(self): + """Should return a list containing values of the single list provided""" + actual = merge_two_sorted_lists([], [1, 2, 3]) + expected = [1, 2, 3] + self.assertEqual(actual, expected) + + def test_both_lists_empty(self): + """Should return an empty list""" + actual = merge_two_sorted_lists([], []) + expected = [] + self.assertEqual(actual, expected) + + def test_lists_unequal_length(self): + """Should return a single sorted list""" + actual = merge_two_sorted_lists([1, 4], [2, 3, 5, 6]) + expected = [1, 2, 3, 4, 5, 6] + self.assertEqual(actual, expected) + + def test_equal_length_lists(self): + """Should return a single sorted list when both lists have the same length""" + actual = merge_two_sorted_lists([1, 3, 5], [2, 4, 6]) + expected = [1, 2, 3, 4, 5, 6] + self.assertEqual(actual, expected) + + def test_lists_with_negatives(self): + """Should return a single sorted list with negative numbers""" + actual = merge_two_sorted_lists([-5, -2, 0], [-4, 1, 3]) + expected = [-5, -4, -2, 0, 1, 3] + self.assertEqual(actual, expected) + + +if __name__ == "__main__": + unittest.main() From 067177b510993ea6c9d7475b7fc157bb5dc38b2c Mon Sep 17 00:00:00 2001 From: KimaciaJr Date: Mon, 6 Jan 2025 19:29:25 +0300 Subject: [PATCH 092/117] Added convert_int_to_roman function and its Unittests --- solutions/convert_int_to_roman | 61 +++++++++++++++++++++++ solutions/tests/test_convert_int_to_roman | 56 +++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 solutions/convert_int_to_roman create mode 100644 solutions/tests/test_convert_int_to_roman diff --git a/solutions/convert_int_to_roman b/solutions/convert_int_to_roman new file mode 100644 index 000000000..1a46585d9 --- /dev/null +++ b/solutions/convert_int_to_roman @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 04/01/2025 +@author: Peter Ngugi +""" + + +def convert_int_to_roman(num: int) -> str: + """ + Converts an integer to its Roman numeral representation. + + Parameters: + num (int): A non-negative integer between 1 and 3999 inclusive. + + Returns: + str: A string representing the Roman numeral corresponding to the integer. + + Raises: + ValueError: If the input is not between 1 and 3999 inclusive. + + Examples: + >>> convert_int_to_roman(5) + "V" + + >>> convert_int_to_roman(100) + "C" + + >>> convert_int_to_roman(33) + "XXXIII" + + >>> convert_int_to_roman(1) + 'I' + """ + if not (1 <= num <= 3999): + raise ValueError("Input must be between 1 and 3999") + + romans = { + 1: "I", + 4: "IV", + 5: "V", + 9: "IX", + 10: "X", + 40: "XL", + 50: "L", + 90: "XC", + 100: "C", + 400: "CD", + 500: "D", + 900: "CM", + 1000: "M", + } + + r = "" + values = sorted(romans.keys(), reverse=True) + for n in values: + while n <= num: + r += romans[n] + num -= n + + return r diff --git a/solutions/tests/test_convert_int_to_roman b/solutions/tests/test_convert_int_to_roman new file mode 100644 index 000000000..b705a0851 --- /dev/null +++ b/solutions/tests/test_convert_int_to_roman @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 04/01/2025 +@author: Peter Ngugi +""" + +import unittest + +from solutions import convert_int_to_roman + + +class TestConvertIntToRoman(unittest.TestCase): + """Test the Convert_int_to_roman function""" + + def test_single_digit_int(self): + """ "Should return a roman numeral + representation for a single digit integer""" + actual = convert_int_to_roman(7) + expected = "VII" + self.assertEqual(actual, expected) + + def test_double_digit_int(self): + """Should return a roman numeral + representation for a double-digit integer""" + actual = convert_int_to_roman(42) + expected = "XLII" + self.assertEqual(actual, expected) + + def test_triple_digit_int(self): + """Should return a roman numeral + representation for a triple-digit integer""" + actual = convert_int_to_roman(387) + expected = "CCCLXXXVII" + self.assertEqual(actual, expected) + + def test_boundary_value(self): + """Should return a roman numeral + representation for the maximum input of 3999""" + actual = convert_int_to_roman(3999) + expected = "MMMCMXCIX" + self.assertEqual(actual, expected) + + def test_invalid_input_zero(self): + """Should raise a ValueError for input less than 1""" + with self.assertRaises(ValueError): + convert_int_to_roman(0) + + def test_invalid_input_large(self): + """Should raise a ValueError for input greater than 3999""" + with self.assertRaises(ValueError): + convert_int_to_roman(4000) + + +if __name__ == "__main__": + unittest.main() From f0d98a39d33d6eedc14d6cd290b426f0c53d7e46 Mon Sep 17 00:00:00 2001 From: KimaciaJr Date: Tue, 7 Jan 2025 09:04:19 +0300 Subject: [PATCH 093/117] Deleted the second solution --- solutions/convert_int_to_roman | 61 ----------------------- solutions/tests/test_convert_int_to_roman | 56 --------------------- 2 files changed, 117 deletions(-) delete mode 100644 solutions/convert_int_to_roman delete mode 100644 solutions/tests/test_convert_int_to_roman diff --git a/solutions/convert_int_to_roman b/solutions/convert_int_to_roman deleted file mode 100644 index 1a46585d9..000000000 --- a/solutions/convert_int_to_roman +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Created on 04/01/2025 -@author: Peter Ngugi -""" - - -def convert_int_to_roman(num: int) -> str: - """ - Converts an integer to its Roman numeral representation. - - Parameters: - num (int): A non-negative integer between 1 and 3999 inclusive. - - Returns: - str: A string representing the Roman numeral corresponding to the integer. - - Raises: - ValueError: If the input is not between 1 and 3999 inclusive. - - Examples: - >>> convert_int_to_roman(5) - "V" - - >>> convert_int_to_roman(100) - "C" - - >>> convert_int_to_roman(33) - "XXXIII" - - >>> convert_int_to_roman(1) - 'I' - """ - if not (1 <= num <= 3999): - raise ValueError("Input must be between 1 and 3999") - - romans = { - 1: "I", - 4: "IV", - 5: "V", - 9: "IX", - 10: "X", - 40: "XL", - 50: "L", - 90: "XC", - 100: "C", - 400: "CD", - 500: "D", - 900: "CM", - 1000: "M", - } - - r = "" - values = sorted(romans.keys(), reverse=True) - for n in values: - while n <= num: - r += romans[n] - num -= n - - return r diff --git a/solutions/tests/test_convert_int_to_roman b/solutions/tests/test_convert_int_to_roman deleted file mode 100644 index b705a0851..000000000 --- a/solutions/tests/test_convert_int_to_roman +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Created on 04/01/2025 -@author: Peter Ngugi -""" - -import unittest - -from solutions import convert_int_to_roman - - -class TestConvertIntToRoman(unittest.TestCase): - """Test the Convert_int_to_roman function""" - - def test_single_digit_int(self): - """ "Should return a roman numeral - representation for a single digit integer""" - actual = convert_int_to_roman(7) - expected = "VII" - self.assertEqual(actual, expected) - - def test_double_digit_int(self): - """Should return a roman numeral - representation for a double-digit integer""" - actual = convert_int_to_roman(42) - expected = "XLII" - self.assertEqual(actual, expected) - - def test_triple_digit_int(self): - """Should return a roman numeral - representation for a triple-digit integer""" - actual = convert_int_to_roman(387) - expected = "CCCLXXXVII" - self.assertEqual(actual, expected) - - def test_boundary_value(self): - """Should return a roman numeral - representation for the maximum input of 3999""" - actual = convert_int_to_roman(3999) - expected = "MMMCMXCIX" - self.assertEqual(actual, expected) - - def test_invalid_input_zero(self): - """Should raise a ValueError for input less than 1""" - with self.assertRaises(ValueError): - convert_int_to_roman(0) - - def test_invalid_input_large(self): - """Should raise a ValueError for input greater than 3999""" - with self.assertRaises(ValueError): - convert_int_to_roman(4000) - - -if __name__ == "__main__": - unittest.main() From db670a21bee26945123d0856a84bb3a373c89a75 Mon Sep 17 00:00:00 2001 From: KimaciaJr Date: Wed, 8 Jan 2025 09:23:14 +0300 Subject: [PATCH 094/117] Corrected highlighted issues in the merge_two_sorted_lists function and its unittests --- solutions/merge_two_sorted_lists | 29 ++++++++------ solutions/tests/test_merge_two_sorted_lists | 44 +++++++++++++++++++-- 2 files changed, 59 insertions(+), 14 deletions(-) diff --git a/solutions/merge_two_sorted_lists b/solutions/merge_two_sorted_lists index 7dda1f57e..89067a93a 100644 --- a/solutions/merge_two_sorted_lists +++ b/solutions/merge_two_sorted_lists @@ -3,16 +3,21 @@ """ Created on 04/01/2025 @author: Peter Ngugi + +This module provides a function to merge two sorted lists into one while maintaining sorted order. + +Function: +- merge_two_sorted_lists(list1: list, list2: list) -> list: Combines two sorted lists efficiently. """ -def merge_two_sorted_lists(l1: list, l2: list) -> list: +def merge_two_sorted_lists(list1: list, list2: list) -> list: """ Merges two sorted Python lists and returns a single sorted list. Parameters: - l1 (list): The first sorted list. - l2 (list): The second sorted list. + list1 (list): The first sorted list. + list2 (list): The second sorted list. Returns: list: A single sorted list merged from the two input lists. @@ -30,23 +35,25 @@ def merge_two_sorted_lists(l1: list, l2: list) -> list: >>> merge_two_sorted_lists([], []) [] """ - if not isinstance(l1, list) or not isinstance(l2, list): - raise TypeError("Both inputs must be lists.") + if not isinstance(list1, list) or not isinstance(list2, list): + raise TypeError( + f"Both inputs must be lists, got {type(list1).__name__} and {type(list2).__name__}." + ) i, j = 0, 0 merged = [] # Merge while there are elements in both lists - while i < len(l1) and j < len(l2): - if l1[i] <= l2[j]: - merged.append(l1[i]) + while i < len(list1) and j < len(list2): + if list1[i] <= list2[j]: + merged.append(list1[i]) i += 1 else: - merged.append(l2[j]) + merged.append(list2[j]) j += 1 # Append any remaining elements - merged.extend(l1[i:]) - merged.extend(l2[j:]) + merged.extend(list1[i:]) + merged.extend(list2[j:]) return merged diff --git a/solutions/tests/test_merge_two_sorted_lists b/solutions/tests/test_merge_two_sorted_lists index 2ca803e74..e8d8da64c 100644 --- a/solutions/tests/test_merge_two_sorted_lists +++ b/solutions/tests/test_merge_two_sorted_lists @@ -4,6 +4,11 @@ """ Created on 04/01/2025 @author: Peter Ngugi + +Unit tests for the merge_two_sorted_lists function. These tests verify the function's +ability to merge two sorted lists, handle edge cases like empty lists, support lists +with integers, floating-point numbers, and raise errors for invalid inputs like non-list types. + """ import unittest @@ -20,19 +25,19 @@ class TestMergeTwoLists(unittest.TestCase): expected = [1, 2, 3, 4, 5, 6] self.assertEqual(actual, expected) - def test_one_list_empty(self): + def test_one_empty_list(self): """Should return a list containing values of the single list provided""" actual = merge_two_sorted_lists([], [1, 2, 3]) expected = [1, 2, 3] self.assertEqual(actual, expected) - def test_both_lists_empty(self): + def test_empty_lists(self): """Should return an empty list""" actual = merge_two_sorted_lists([], []) expected = [] self.assertEqual(actual, expected) - def test_lists_unequal_length(self): + def test_unequal_length_lists(self): """Should return a single sorted list""" actual = merge_two_sorted_lists([1, 4], [2, 3, 5, 6]) expected = [1, 2, 3, 4, 5, 6] @@ -50,6 +55,39 @@ class TestMergeTwoLists(unittest.TestCase): expected = [-5, -4, -2, 0, 1, 3] self.assertEqual(actual, expected) + def test_lists_with_floats(self): + """Should return a single sorted list with floating-point numbers""" + actual = merge_two_sorted_lists([1.1, 3.3, 5.5], [2.2, 4.4, 6.6]) + expected = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6] + self.assertEqual(actual, expected) + + def test_invalid_inputs(self): + """Should raise a TypeError when inputs are not lists""" + + # First input is not a list + with self.assertRaises(TypeError): + merge_two_sorted_lists("not a list", [1, 2, 3]) + + # Second input is not a list + with self.assertRaises(TypeError): + merge_two_sorted_lists([1, 2, 3], 123) + + # Both inputs are not lists + with self.assertRaises(TypeError): + merge_two_sorted_lists("string1", "string2") + + # Lists with mixed types + with self.assertRaises(TypeError): + merge_two_sorted_lists([1, "two", 3], [4, 5, "six"]) + + # One input is None + with self.assertRaises(TypeError): + merge_two_sorted_lists(None, [1, 2, 3]) + + # Both inputs are None + with self.assertRaises(TypeError): + merge_two_sorted_lists(None, None) + if __name__ == "__main__": unittest.main() From a59569bec6fea34d7481f5fa228c54e4e7833bfb Mon Sep 17 00:00:00 2001 From: KimaciaJr Date: Wed, 8 Jan 2025 14:17:12 +0300 Subject: [PATCH 095/117] Updated import statement --- solutions/tests/test_merge_two_sorted_lists | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_merge_two_sorted_lists b/solutions/tests/test_merge_two_sorted_lists index e8d8da64c..99f324301 100644 --- a/solutions/tests/test_merge_two_sorted_lists +++ b/solutions/tests/test_merge_two_sorted_lists @@ -13,7 +13,7 @@ with integers, floating-point numbers, and raise errors for invalid inputs like import unittest -from solutions import merge_two_sorted_lists +from solutions.merge_two_sorted_lists import merge_two_sorted_lists class TestMergeTwoLists(unittest.TestCase): From 40207da43a670141c853bd67b97d6d2eee2b5260 Mon Sep 17 00:00:00 2001 From: fikre Date: Tue, 7 Jan 2025 01:17:27 +0300 Subject: [PATCH 096/117] fixing py_test Error --- solutions/number_guessing.py | 67 ++++++++++++++++++++ solutions/tests/test_number_guessing.py | 83 +++++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 solutions/number_guessing.py create mode 100644 solutions/tests/test_number_guessing.py diff --git a/solutions/number_guessing.py b/solutions/number_guessing.py new file mode 100644 index 000000000..ff224221a --- /dev/null +++ b/solutions/number_guessing.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +This is a guessing random number game where you guess a number between 1 and 100. + +Created on: 2025/01/06 +@author Fikremichael Mamo +""" + +import random + + +def play_game(target_number=None, simulated_guesses=None): + """ + Play a number guessing game. + + Args: + target_number (int, optional): The target number to guess. If None, a random number between 1 and 100 is used. + simulated_guesses (list of int, optional): A list of simulated guesses to replace user input for testing purposes. + + Returns: + int: The number of attempts it took to guess the target number correctly. + """ + if target_number is None: + target_number = random.randint(1, 100) + + attempts = 0 + previous_guess_diff = None + guess_index = 0 + + # Use simulated guesses if provided, no input from user + while True: + if simulated_guesses is not None and guess_index < len(simulated_guesses): + guess = simulated_guesses[guess_index] + guess_index += 1 + else: + # If no simulated guesses are given, the game will not proceed + print("No more simulated guesses.") + break + + # Check if the guess is within the allowed range + if guess < 1 or guess > 100: + print("Please guess a number between 1 and 100.") + continue + + attempts += 1 + guess_diff = abs(guess - target_number) + + if guess < target_number: + print("Too low!") + elif guess > target_number: + print("Too high!") + else: + print(f"Congratulations! You guessed the number in {attempts} attempts.") + break + + if previous_guess_diff is not None: + if guess_diff < previous_guess_diff: + print("You're getting warmer!") + elif guess_diff > previous_guess_diff: + print("You're getting colder!") + else: + print("Start guessing!") + + previous_guess_diff = guess_diff + + return attempts # Return the number of attempts to facilitate testing diff --git a/solutions/tests/test_number_guessing.py b/solutions/tests/test_number_guessing.py new file mode 100644 index 000000000..cb68aca8c --- /dev/null +++ b/solutions/tests/test_number_guessing.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +This is a guessing random number game where you guess a number between 1 and 100. + +Created on: 2025/01/06 +@author Fikremichael Mamo +""" + +import unittest +from ..number_guessing import ( + play_game, +) # Ensure the correct path to the `play_game` function. + + +class TestPlayGame(unittest.TestCase): + """ + Unit tests for the play_game function. + """ + + def test_correct_guess_in_one_attempt(self): + """ + Test if the game returns 1 attempt when the player guesses correctly on the first try. + """ + result = play_game(target_number=50, simulated_guesses=[50]) + self.assertEqual( + result, + 1, + "Should return 1 attempt when guessed correctly on the first try.", + ) + + def test_multiple_attempts_with_correct_guess(self): + """ + Test if the game counts the correct number of attempts when multiple guesses are required. + """ + result = play_game(target_number=30, simulated_guesses=[10, 20, 30]) + self.assertEqual( + result, + 3, + "Should return the correct number of attempts when multiple guesses are made.", + ) + + def test_all_guesses_too_low(self): + """ + Test if the game handles the case where all guesses are lower than the target number. + """ + result = play_game(target_number=50, simulated_guesses=[10, 20, 30, 40]) + self.assertEqual( + result, + 4, # Expecting 5 attempts: 4 low guesses + 1 correct guess + "Should take 5 attempts when all guesses are too low.", + ) + + def test_invalid_guesses(self): + """ + Test if the game ignores invalid guesses (e.g., less than 1 or greater than 100) + and only counts valid attempts. + """ + result = play_game(target_number=25, simulated_guesses=[-1, 101, 25]) + self.assertEqual( + result, + 1, + "Should ignore invalid guesses and return correct attempts, counting only valid guesses.", + ) + + def test_warmer_and_colder_logic(self): + """ + Test if the game provides 'warmer' and 'colder' feedback correctly based on guesses. + """ + # In this test, we expect the game to give 'warmer' feedback as the guess gets closer to 50. + result = play_game(target_number=50, simulated_guesses=[30, 40, 50]) + self.assertEqual( + result, + 3, + "Should return correct attempts including 'warmer' and 'colder' feedback.", + ) + + +if __name__ == "__main__": + """ + Entry point for running the unittests. + """ + unittest.main() From a8bdc7697ce81ebb6e0a5c1d945639d1fdde1379 Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Tue, 7 Jan 2025 08:57:25 -0800 Subject: [PATCH 097/117] Update number_guessing.py --- solutions/number_guessing.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/solutions/number_guessing.py b/solutions/number_guessing.py index ff224221a..2521b1fdf 100644 --- a/solutions/number_guessing.py +++ b/solutions/number_guessing.py @@ -10,7 +10,7 @@ import random -def play_game(target_number=None, simulated_guesses=None): +def number_guessing(target_number=None, simulated_guesses=None): """ Play a number guessing game. @@ -40,16 +40,15 @@ def play_game(target_number=None, simulated_guesses=None): # Check if the guess is within the allowed range if guess < 1 or guess > 100: - print("Please guess a number between 1 and 100.") - continue + print(f"Invalid guess: {guess}. Please guess a number between 1 and 100.") attempts += 1 guess_diff = abs(guess - target_number) if guess < target_number: - print("Too low!") + print(f"{guess} is too low! Try guessing higher.") elif guess > target_number: - print("Too high!") + print(f"{guess} is too high! Aim low") else: print(f"Congratulations! You guessed the number in {attempts} attempts.") break From 19b2449829484ba6a2c991e2d9bd437965a739f2 Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Tue, 7 Jan 2025 09:00:30 -0800 Subject: [PATCH 098/117] Update test_number_guessing.py update function name --- solutions/tests/test_number_guessing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_number_guessing.py b/solutions/tests/test_number_guessing.py index cb68aca8c..69339f23a 100644 --- a/solutions/tests/test_number_guessing.py +++ b/solutions/tests/test_number_guessing.py @@ -9,7 +9,7 @@ import unittest from ..number_guessing import ( - play_game, + number_guessing, ) # Ensure the correct path to the `play_game` function. From 32c0f82293bad52d1544f75aa25d384a1db148c4 Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Tue, 7 Jan 2025 09:01:44 -0800 Subject: [PATCH 099/117] Update test_number_guessing.py --- solutions/tests/test_number_guessing.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/solutions/tests/test_number_guessing.py b/solutions/tests/test_number_guessing.py index 69339f23a..9eb6ec212 100644 --- a/solutions/tests/test_number_guessing.py +++ b/solutions/tests/test_number_guessing.py @@ -10,19 +10,19 @@ import unittest from ..number_guessing import ( number_guessing, -) # Ensure the correct path to the `play_game` function. +) # Ensure the correct path to the `number_guessing` function. class TestPlayGame(unittest.TestCase): """ - Unit tests for the play_game function. + Unit tests for the number_guessing function. """ def test_correct_guess_in_one_attempt(self): """ Test if the game returns 1 attempt when the player guesses correctly on the first try. """ - result = play_game(target_number=50, simulated_guesses=[50]) + result = number_guessing(target_number=50, simulated_guesses=[50]) self.assertEqual( result, 1, @@ -33,7 +33,7 @@ def test_multiple_attempts_with_correct_guess(self): """ Test if the game counts the correct number of attempts when multiple guesses are required. """ - result = play_game(target_number=30, simulated_guesses=[10, 20, 30]) + result = number_guessing(target_number=30, simulated_guesses=[10, 20, 30]) self.assertEqual( result, 3, @@ -44,7 +44,7 @@ def test_all_guesses_too_low(self): """ Test if the game handles the case where all guesses are lower than the target number. """ - result = play_game(target_number=50, simulated_guesses=[10, 20, 30, 40]) + result = number_guessing(target_number=50, simulated_guesses=[10, 20, 30, 40]) self.assertEqual( result, 4, # Expecting 5 attempts: 4 low guesses + 1 correct guess @@ -56,7 +56,7 @@ def test_invalid_guesses(self): Test if the game ignores invalid guesses (e.g., less than 1 or greater than 100) and only counts valid attempts. """ - result = play_game(target_number=25, simulated_guesses=[-1, 101, 25]) + result = number_guessing(target_number=25, simulated_guesses=[-1, 101, 25]) self.assertEqual( result, 1, @@ -68,7 +68,7 @@ def test_warmer_and_colder_logic(self): Test if the game provides 'warmer' and 'colder' feedback correctly based on guesses. """ # In this test, we expect the game to give 'warmer' feedback as the guess gets closer to 50. - result = play_game(target_number=50, simulated_guesses=[30, 40, 50]) + result = number_guessing(target_number=50, simulated_guesses=[30, 40, 50]) self.assertEqual( result, 3, From 375c852f66b5d9a49419c4722036abc0343429af Mon Sep 17 00:00:00 2001 From: Fikremichael Mamo Date: Tue, 7 Jan 2025 09:04:30 -0800 Subject: [PATCH 100/117] Update test_number_guessing.py --- solutions/tests/test_number_guessing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_number_guessing.py b/solutions/tests/test_number_guessing.py index 9eb6ec212..e4f67da57 100644 --- a/solutions/tests/test_number_guessing.py +++ b/solutions/tests/test_number_guessing.py @@ -59,7 +59,7 @@ def test_invalid_guesses(self): result = number_guessing(target_number=25, simulated_guesses=[-1, 101, 25]) self.assertEqual( result, - 1, + 3, "Should ignore invalid guesses and return correct attempts, counting only valid guesses.", ) From bbc580c34bf85e1f97b44c3f7c030a0dde54003e Mon Sep 17 00:00:00 2001 From: fikre Date: Thu, 9 Jan 2025 18:13:56 +0300 Subject: [PATCH 101/117] update the atm, test_atm, fix all issus and add docstrings --- solutions/atm.py | 126 +++++++++++++++++++----------------- solutions/tests/test_atm.py | 52 +++++++++++---- 2 files changed, 104 insertions(+), 74 deletions(-) diff --git a/solutions/atm.py b/solutions/atm.py index 93349c618..65b4f556f 100644 --- a/solutions/atm.py +++ b/solutions/atm.py @@ -2,71 +2,82 @@ # -*- coding: utf-8 -*- """ Welcome to WIT International Bank. -This program operates the ATM system, allowing users to perform various banking transactions, -including checking their balance, depositing cash, and withdrawing money securely. +This program operates the ATM system, allowing users to perform +various banking transactions, +including checking their balance, depositing cash, and withdrawing +money securely. -Thank you for choosing WIT International Bank. Your satisfaction is our priority. +Thank you for choosing WIT International Bank. Your satisfaction is +our priority. Created on: 2025/01/02 By: Fikremichael Mamo """ -def show_balance(balance): +def show_balance(balance: float) -> str: """ - Display the user's current account balance. - - Parameters: - balance (float): The current balance in the user's account. - - Returns: - str: A formatted string showing the balance. + Returns the formatted balance as a string. + + >>> show_balance(0) + 'Your Balance is $0.00' + >>> show_balance(100.50) + 'Your Balance is $100.50' + >>> show_balance(1234.56) + 'Your Balance is $1234.56' """ return f"Your Balance is ${balance:.2f}" -def deposit(balance, amount): - """ - Deposit a specified amount into the user's account. - - Parameters: - balance (float): The current balance in the user's account. - amount (float): The amount to deposit. - - Returns: - float: The updated balance after the deposit. - str: An error message if the amount is invalid. +def deposit(balance: float, amount: float) -> tuple[float, str]: """ - if not isinstance(amount, (float, int)) or amount <= 0: - return balance, "Invalid amount! Please enter a positive number." - return balance + amount, "Deposit successful." - - -def withdraw(balance, amount): + Deposits an amount into the balance and returns the new balance + with a message. + + >>> deposit(100, 50) + (150, 'Deposit successful.') + >>> deposit(100, -10) + Traceback (most recent call last): + ... + ValueError: Amount must be a positive number. + >>> deposit(100, 'fifty') + Traceback (most recent call last): + ... + TypeError: Amount must be a number. """ - Withdraw a specified amount from the user's account. - - Parameters: - balance (float): The current balance in the user's account. - amount (float): The amount to withdraw. - - Returns: - float: The updated balance after withdrawal. - str: An error message if the operation is invalid. + if not isinstance(amount, (int, float)): + raise TypeError("Amount must be a number.") + if amount < 0: + raise ValueError("Amount must be a positive number.") + balance += amount + return balance, "Deposit successful." + + +def withdraw(balance: float, amount: float) -> tuple[float, str]: + """Withdraw a specified amount from the user's account. + >>> withdraw(100, 50) + (50, 'Withdrawal successful.') + >>> withdraw(50, 50) + (0, 'Withdrawal successful.') + >>> withdraw(50, 60) + (50, 'Insufficient balance.') + >>> withdraw(100, -10) + Traceback (most recent call last): + ... + ValueError: Amount must be a positive number. + >>> withdraw(100, 'fifty') + Traceback (most recent call last): + ... + TypeError: Amount must be a number. """ + if amount <= 0: + raise ValueError("Amount must be greater than 0.") if amount > balance: return balance, "Insufficient balance." - elif amount <= 0: - return balance, "Amount must be greater than 0." return balance - amount, "Withdrawal successful." def main(): - """ - Main function to operate the ATM system. - - Allows the user to perform actions such as checking balance, depositing funds, - withdrawing funds, or exiting the system. Repeats until the user chooses to exit. - """ + """Main function to operate the ATM system.""" balance = 0.0 while True: @@ -78,33 +89,26 @@ def main(): try: choice = int(input("\nEnter your choice: ")) - if choice == 1: print(show_balance(balance)) elif choice == 2: - try: - amount = float(input("Enter an amount to deposit: ")) - balance, message = deposit(balance, amount) - print(message) - except ValueError: - print("Invalid input! Please enter a numerical value.") + amount = float(input("Enter an amount to deposit: ")) + balance, message = deposit(balance, amount) + print(message) elif choice == 3: + amount = float(input("Enter an amount to withdraw: ")) try: - amount = float(input("Enter an amount to withdraw: ")) balance, message = withdraw(balance, amount) print(message) - except ValueError: - print("Invalid input! Please enter a numerical value.") + except ValueError as e: + print(e) elif choice == 4: - print( - "Thank you for choosing WIT International Bank.\nThe Bank that you can always rely on." - ) + print("Thank you for choosing WIT International Bank.") break else: - print("That is not a valid choice.") - + print("Invalid choice. Please choose between 1 and 4.") except ValueError: - print("Invalid input! Please enter a number between 1 and 4.") + print("Invalid input! Please enter a valid number.") if __name__ == "__main__": diff --git a/solutions/tests/test_atm.py b/solutions/tests/test_atm.py index 2c120570a..1552174dd 100644 --- a/solutions/tests/test_atm.py +++ b/solutions/tests/test_atm.py @@ -7,7 +7,7 @@ """ import unittest -from ..atm import show_balance, deposit, withdraw +from solutions.atm import show_balance, deposit, withdraw """ Unit tests for ATM functions: show_balance, deposit, and withdraw. @@ -15,24 +15,50 @@ class TestATMFunctions(unittest.TestCase): - def test_show_balance(self): - """ - Test that show_balance correctly formats and returns the account balance. - """ + def test_show_balance_zero_balance(self): + """Test show_balance formats zero balance.""" + self.assertEqual(show_balance(0), "Your Balance is $0.00") + + def test_show_balance_positive_balance(self): + """Test show_balance formats a positive balance.""" self.assertEqual(show_balance(100.50), "Your Balance is $100.50") - def test_deposit(self): - """ - Test that deposit correctly updates the balance and handles invalid inputs. - """ + def test_deposit_success(self): + """Test deposit adds funds correctly.""" self.assertEqual(deposit(100, 50), (150, "Deposit successful.")) - def test_withdraw(self): - """ - Test that withdraw correctly updates the balance and handles invalid and insufficient funds. - """ + def test_deposit_negative_amount(self): + """Test deposit with negative amount raises ValueError.""" + with self.assertRaises(ValueError): + deposit(100, -10) + + def test_deposit_invalid_type(self): + """Test deposit with a non-numeric input raises TypeError.""" + with self.assertRaises(TypeError): + deposit(100, "fifty") + + def test_withdraw_success(self): + """Test withdraw reduces balance correctly.""" self.assertEqual(withdraw(100, 50), (50, "Withdrawal successful.")) + def test_withdraw_exact_balance(self): + """Test withdraw with exact balance leaves zero.""" + self.assertEqual(withdraw(50, 50), (0, "Withdrawal successful.")) + + def test_withdraw_insufficient_funds(self): + """Test withdraw when balance is insufficient.""" + self.assertEqual(withdraw(50, 60), (50, "Insufficient balance.")) + + def test_withdraw_negative_amount(self): + """Test withdraw with negative amount raises ValueError.""" + with self.assertRaises(ValueError): + withdraw(100, -10) + + def test_withdraw_invalid_type(self): + """Test withdraw with a non-numeric input raises TypeError.""" + with self.assertRaises(TypeError): + withdraw(100, "fifty") + if __name__ == "__main__": unittest.main() From c18b6dbd248bdb996b0c42d446dcddbefa347ab6 Mon Sep 17 00:00:00 2001 From: collyns-linc Date: Fri, 10 Jan 2025 18:07:03 +0300 Subject: [PATCH 102/117] fix assertion error --- solutions/calculate_bmi.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/solutions/calculate_bmi.py b/solutions/calculate_bmi.py index eaac7b4ab..942727202 100644 --- a/solutions/calculate_bmi.py +++ b/solutions/calculate_bmi.py @@ -34,8 +34,9 @@ def calculate_bmi(weight: float, height: float) -> float: 31.08 """ - assert isinstance(weight, (float, int)), "Weight must be a number (float)." - assert isinstance(height, (float, int)), "Height must be a number (float)." + assert isinstance(weight, (float, int)) and isinstance( + height, (float, int) + ), "Weight and Height must be a number (float or int)." if weight <= 0 or height <= 0: raise ValueError("Weight and height must be positive numbers.") From 33e60e841ac92c4ee79f3f06ec1b692224c3bc7c Mon Sep 17 00:00:00 2001 From: collyns-linc Date: Fri, 10 Jan 2025 18:09:40 +0300 Subject: [PATCH 103/117] update calculte_bmi.py file --- solutions/calculate_bmi.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/solutions/calculate_bmi.py b/solutions/calculate_bmi.py index 942727202..0ed4df148 100644 --- a/solutions/calculate_bmi.py +++ b/solutions/calculate_bmi.py @@ -43,3 +43,7 @@ def calculate_bmi(weight: float, height: float) -> float: bmi = weight / (height**2) return round(bmi, 2) + + +if __name__ == "__main__": + print(calculate_bmi("", 1.68)) From 953e04a35a7fdbbf66dca5fbe50496a519ddb075 Mon Sep 17 00:00:00 2001 From: collyns-linc Date: Fri, 10 Jan 2025 18:11:21 +0300 Subject: [PATCH 104/117] remove function call --- solutions/calculate_bmi.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/solutions/calculate_bmi.py b/solutions/calculate_bmi.py index 0ed4df148..942727202 100644 --- a/solutions/calculate_bmi.py +++ b/solutions/calculate_bmi.py @@ -43,7 +43,3 @@ def calculate_bmi(weight: float, height: float) -> float: bmi = weight / (height**2) return round(bmi, 2) - - -if __name__ == "__main__": - print(calculate_bmi("", 1.68)) From 2ef21d8330038af08aefa5ce2654453b58e7f78e Mon Sep 17 00:00:00 2001 From: collyns-linc Date: Fri, 10 Jan 2025 18:54:09 +0300 Subject: [PATCH 105/117] fix ruff formating --- solutions/calculate_bmi.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solutions/calculate_bmi.py b/solutions/calculate_bmi.py index 942727202..fa470eb12 100644 --- a/solutions/calculate_bmi.py +++ b/solutions/calculate_bmi.py @@ -34,9 +34,9 @@ def calculate_bmi(weight: float, height: float) -> float: 31.08 """ - assert isinstance(weight, (float, int)) and isinstance( - height, (float, int) - ), "Weight and Height must be a number (float or int)." + assert isinstance(weight, (float, int)) and isinstance(height, (float, int)), ( + "Weight and Height must be a number (float or int)." + ) if weight <= 0 or height <= 0: raise ValueError("Weight and height must be positive numbers.") From 9c85ea8e08ff6fc15b7189eec41d50e8c75887b4 Mon Sep 17 00:00:00 2001 From: Dorcas Njeri Date: Sat, 11 Jan 2025 14:45:04 +0300 Subject: [PATCH 106/117] Add solutions and test files for Palindrome number and Remove Duplicates from Sorted Array --- .../Remove_Duplicates_from_sorted_Array.py | 57 +++++++++++++++++ solutions/palindrome number.py | 49 ++++++++++++++ ...est_Remove_Duplicates_from_sorted_Array.py | 64 +++++++++++++++++++ solutions/tests/test_palindrome_number.py | 64 +++++++++++++++++++ 4 files changed, 234 insertions(+) create mode 100644 solutions/Remove_Duplicates_from_sorted_Array.py create mode 100644 solutions/palindrome number.py create mode 100644 solutions/tests/test_Remove_Duplicates_from_sorted_Array.py create mode 100644 solutions/tests/test_palindrome_number.py diff --git a/solutions/Remove_Duplicates_from_sorted_Array.py b/solutions/Remove_Duplicates_from_sorted_Array.py new file mode 100644 index 000000000..0eedc8155 --- /dev/null +++ b/solutions/Remove_Duplicates_from_sorted_Array.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 11/01/2025 +@author: Dorcas Wanja Njeri +""" + +def remove_duplicates_from_sorted_array(nums: list) -> int: + """ + Challenge: Remove Duplicates from Sorted Array + Removes duplicates from a sorted array in place and returns the new length. + + Parameters: + nums (list): A sorted list of integers. + + Returns: + int: The length of the array after removing duplicates. + The first part of the array (up to the returned length) + will contain only unique elements. + + Raises: + TypeError: If nums is not a list of integers. + IndexError: If nums is modified externally during execution. + + Examples: + >>> nums = [1, 1, 2] + >>> remove_duplicates_from_sorted_array(nums) + 2 + >>> nums[:2] + [1, 2] + + >>> nums = [0, 0, 1, 1, 2, 2, 3, 3, 4] + >>> remove_duplicates_from_sorted_array(nums) + 5 + >>> nums[:5] + [0, 1, 2, 3, 4] + + >>> nums = [] + >>> remove_duplicates_from_sorted_array(nums) + 0 + """ + if not isinstance(nums, list): + raise TypeError("Input must be a list of integers.") + if not all(isinstance(x, int) for x in nums): + raise TypeError("All elements in the input list must be integers.") + + if not nums: + return 0 + + j = 0 # Initialize the pointer for the unique elements + + for i in range(1, len(nums)): # Start from the second element + if nums[i] != nums[j]: # If the current element is different + j += 1 # Move to the next unique position + nums[j] = nums[i] # Place the unique element in its position + + return j + 1 diff --git a/solutions/palindrome number.py b/solutions/palindrome number.py new file mode 100644 index 000000000..96638aa35 --- /dev/null +++ b/solutions/palindrome number.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 11/01/2025 +@author: Dorcas Wanja Njeri +""" + +def is_palindrome_number(x: int) -> bool: + """ + Determines if a given integer is a palindrome number. + + A palindrome number is one that remains the same when its digits are reversed. + + Parameters: + x (int): The integer to check for palindrome. + + Returns: + bool: True if the number is a palindrome, False otherwise. + + Raises: + ValueError: If the input is not an integer. + + Examples: + >>> is_palindrome_number(121) + True + >>> is_palindrome_number(-121) + False + >>> is_palindrome_number(123) + False + >>> is_palindrome_number(5) + True + >>> is_palindrome_number(12321) + True + >>> is_palindrome_number(0) + True + """ + if not isinstance(x, int): + raise ValueError("The input must be an integer.") + + # Negative numbers and numbers that end with a 0 (except 0 itself) are not palindromes + if x < 0 or (x % 10 == 0 and x != 0): + return False + + reversed_half = 0 + while x > reversed_half: + reversed_half = reversed_half * 10 + x % 10 + x //= 10 + + return x == reversed_half or x == reversed_half // 10 diff --git a/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py b/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py new file mode 100644 index 000000000..d19a7c545 --- /dev/null +++ b/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 11/01/2025 +@author: Dorcas Wanja Njeri +""" + +import unittest + +from solutions import remove_duplicates_from_sorted_array + + +class TestRemoveDuplicatesFromSortedArray(unittest.TestCase): + """Test the remove_duplicates_from_sorted_array function""" + + def test_basic_example(self): + """Should remove duplicates in a basic sorted array""" + nums = [1, 1, 2] + length = remove_duplicates_from_sorted_array(nums) + expected = [1, 2] + self.assertEqual(length, 2) + self.assertEqual(nums[:length], expected) + + def test_longer_array_with_duplicates(self): + """Should remove duplicates from a longer sorted array""" + nums = [0, 0, 1, 1, 2, 2, 3, 3, 4] + length = remove_duplicates_from_sorted_array(nums) + expected = [0, 1, 2, 3, 4] + self.assertEqual(length, 5) + self.assertEqual(nums[:length], expected) + + def test_no_duplicates(self): + """Should return the same list if there are no duplicates""" + nums = [1, 2, 3, 4, 5] + length = remove_duplicates_from_sorted_array(nums) + expected = [1, 2, 3, 4, 5] + self.assertEqual(length, 5) + self.assertEqual(nums[:length], expected) + + def test_all_duplicates(self): + """Should return a list with a single element if all elements are duplicates""" + nums = [2, 2, 2, 2, 2] + length = remove_duplicates_from_sorted_array(nums) + expected = [2] + self.assertEqual(length, 1) + self.assertEqual(nums[:length], expected) + + def test_empty_array(self): + """Should return 0 for an empty array""" + nums = [] + length = remove_duplicates_from_sorted_array(nums) + self.assertEqual(length, 0) + + def test_single_element(self): + """Should return the same list if there is only one element""" + nums = [5] + length = remove_duplicates_from_sorted_array(nums) + expected = [5] + self.assertEqual(length, 1) + self.assertEqual(nums[:length], expected) + + +if __name__ == "__main__": + unittest.main() diff --git a/solutions/tests/test_palindrome_number.py b/solutions/tests/test_palindrome_number.py new file mode 100644 index 000000000..d19a7c545 --- /dev/null +++ b/solutions/tests/test_palindrome_number.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 11/01/2025 +@author: Dorcas Wanja Njeri +""" + +import unittest + +from solutions import remove_duplicates_from_sorted_array + + +class TestRemoveDuplicatesFromSortedArray(unittest.TestCase): + """Test the remove_duplicates_from_sorted_array function""" + + def test_basic_example(self): + """Should remove duplicates in a basic sorted array""" + nums = [1, 1, 2] + length = remove_duplicates_from_sorted_array(nums) + expected = [1, 2] + self.assertEqual(length, 2) + self.assertEqual(nums[:length], expected) + + def test_longer_array_with_duplicates(self): + """Should remove duplicates from a longer sorted array""" + nums = [0, 0, 1, 1, 2, 2, 3, 3, 4] + length = remove_duplicates_from_sorted_array(nums) + expected = [0, 1, 2, 3, 4] + self.assertEqual(length, 5) + self.assertEqual(nums[:length], expected) + + def test_no_duplicates(self): + """Should return the same list if there are no duplicates""" + nums = [1, 2, 3, 4, 5] + length = remove_duplicates_from_sorted_array(nums) + expected = [1, 2, 3, 4, 5] + self.assertEqual(length, 5) + self.assertEqual(nums[:length], expected) + + def test_all_duplicates(self): + """Should return a list with a single element if all elements are duplicates""" + nums = [2, 2, 2, 2, 2] + length = remove_duplicates_from_sorted_array(nums) + expected = [2] + self.assertEqual(length, 1) + self.assertEqual(nums[:length], expected) + + def test_empty_array(self): + """Should return 0 for an empty array""" + nums = [] + length = remove_duplicates_from_sorted_array(nums) + self.assertEqual(length, 0) + + def test_single_element(self): + """Should return the same list if there is only one element""" + nums = [5] + length = remove_duplicates_from_sorted_array(nums) + expected = [5] + self.assertEqual(length, 1) + self.assertEqual(nums[:length], expected) + + +if __name__ == "__main__": + unittest.main() From 9a5ae81e80352143a9497a5d9af8dd28b6ed6cbb Mon Sep 17 00:00:00 2001 From: Dorcas Njeri Date: Sun, 12 Jan 2025 07:39:15 +0300 Subject: [PATCH 107/117] docs: add docstring and fix syntax errors in palindrome solution --- solutions/palindrome number.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/solutions/palindrome number.py b/solutions/palindrome number.py index 96638aa35..aeca6e583 100644 --- a/solutions/palindrome number.py +++ b/solutions/palindrome number.py @@ -3,17 +3,23 @@ """ Created on 11/01/2025 @author: Dorcas Wanja Njeri + +Script to check if an integer is a palindrome. +A palindrome number is one that remains the same when its digits are reversed. +The script includes basic unit tests to validate the correctness +of the function with various test cases. + """ def is_palindrome_number(x: int) -> bool: - """ + """" Determines if a given integer is a palindrome number. A palindrome number is one that remains the same when its digits are reversed. - + Parameters: x (int): The integer to check for palindrome. - + Returns: bool: True if the number is a palindrome, False otherwise. From e8465d1d91f3eb0f0010ea9b14a646749c2dc1c2 Mon Sep 17 00:00:00 2001 From: Dorcas Njeri Date: Sun, 12 Jan 2025 16:58:20 +0300 Subject: [PATCH 108/117] Fix import issue in Palindrome_Number.py solution --- solutions/Palindrome_Number.py | 50 ++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 solutions/Palindrome_Number.py diff --git a/solutions/Palindrome_Number.py b/solutions/Palindrome_Number.py new file mode 100644 index 000000000..fcab25ec1 --- /dev/null +++ b/solutions/Palindrome_Number.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 11/01/2025 +@author: Dorcas Wanja Njeri +""" + + +def is_Palindrome_Number(x: int) -> bool: + """ + Determines if a given integer is a palindrome number. + + A palindrome number is one that remains the same when its digits are reversed. + + Parameters: + x (int): The integer to check for palindrome. + + Returns: + bool: True if the number is a palindrome, False otherwise. + + Raises: + ValueError: If the input is not an integer. + + Examples: + >>> is_palindrome_number(121) + True + >>> is_palindrome_number(-121) + False + >>> is_palindrome_number(123) + False + >>> is_palindrome_number(5) + True + >>> is_palindrome_number(12321) + True + >>> is_palindrome_number(0) + True + """ + if not isinstance(x, int): + raise ValueError("The input must be an integer.") + + # Negative numbers and numbers that end with a 0 (except 0 itself) are not palindromes + if x < 0 or (x % 10 == 0 and x != 0): + return False + + reversed_half = 0 + while x > reversed_half: + reversed_half = reversed_half * 10 + x % 10 + x //= 10 + + return x == reversed_half or x == reversed_half // 10 From b1dcd79a8fa4afb329b208425ebf7d5575ccf114 Mon Sep 17 00:00:00 2001 From: Dorcas Njeri Date: Sun, 12 Jan 2025 16:59:55 +0300 Subject: [PATCH 109/117] Fix import issue in test_Palindrome_Number.py --- solutions/tests/test_palindrome_number.py | 98 +++++++++++------------ 1 file changed, 47 insertions(+), 51 deletions(-) diff --git a/solutions/tests/test_palindrome_number.py b/solutions/tests/test_palindrome_number.py index d19a7c545..3b00edf23 100644 --- a/solutions/tests/test_palindrome_number.py +++ b/solutions/tests/test_palindrome_number.py @@ -7,57 +7,53 @@ import unittest -from solutions import remove_duplicates_from_sorted_array - - -class TestRemoveDuplicatesFromSortedArray(unittest.TestCase): - """Test the remove_duplicates_from_sorted_array function""" - - def test_basic_example(self): - """Should remove duplicates in a basic sorted array""" - nums = [1, 1, 2] - length = remove_duplicates_from_sorted_array(nums) - expected = [1, 2] - self.assertEqual(length, 2) - self.assertEqual(nums[:length], expected) - - def test_longer_array_with_duplicates(self): - """Should remove duplicates from a longer sorted array""" - nums = [0, 0, 1, 1, 2, 2, 3, 3, 4] - length = remove_duplicates_from_sorted_array(nums) - expected = [0, 1, 2, 3, 4] - self.assertEqual(length, 5) - self.assertEqual(nums[:length], expected) - - def test_no_duplicates(self): - """Should return the same list if there are no duplicates""" - nums = [1, 2, 3, 4, 5] - length = remove_duplicates_from_sorted_array(nums) - expected = [1, 2, 3, 4, 5] - self.assertEqual(length, 5) - self.assertEqual(nums[:length], expected) - - def test_all_duplicates(self): - """Should return a list with a single element if all elements are duplicates""" - nums = [2, 2, 2, 2, 2] - length = remove_duplicates_from_sorted_array(nums) - expected = [2] - self.assertEqual(length, 1) - self.assertEqual(nums[:length], expected) - - def test_empty_array(self): - """Should return 0 for an empty array""" - nums = [] - length = remove_duplicates_from_sorted_array(nums) - self.assertEqual(length, 0) - - def test_single_element(self): - """Should return the same list if there is only one element""" - nums = [5] - length = remove_duplicates_from_sorted_array(nums) - expected = [5] - self.assertEqual(length, 1) - self.assertEqual(nums[:length], expected) +from solutions.Palindrome_Number import is_Palindrome_Number + + +class TestPalindromeNumber(unittest.TestCase): + """Test the is_palindrome_number function""" + + def test_palindrome_number(self): + """Should return True for a number that is a palindrome""" + actual = is_Palindrome_Number(121) + expected = True + self.assertEqual(actual, expected) + + def test_negative_palindrome(self): + """Should return False for a negative number (never a palindrome)""" + actual = is_Palindrome_Number(-121) + expected = False + self.assertEqual(actual, expected) + + def test_non_palindrome_number(self): + """Should return False for a number that is not a palindrome""" + actual = is_Palindrome_Number(123) + expected = False + self.assertEqual(actual, expected) + + def test_single_digit_number(self): + """Should return True for a single digit number (always a palindrome)""" + actual = is_Palindrome_Number(5) + expected = True + self.assertEqual(actual, expected) + + def test_large_palindrome(self): + """Should return True for a large palindrome number""" + actual = is_Palindrome_Number(12321) + expected = True + self.assertEqual(actual, expected) + + def test_large_non_palindrome(self): + """Should return False for a large non-palindrome number""" + actual = is_Palindrome_Number(12345) + expected = False + self.assertEqual(actual, expected) + + def test_zero(self): + """Should return True for zero (considered a palindrome)""" + actual = is_Palindrome_Number(0) + expected = True + self.assertEqual(actual, expected) if __name__ == "__main__": From 6eabd73b2261b696db689436067db25d4f268ea8 Mon Sep 17 00:00:00 2001 From: Dorcas Njeri Date: Mon, 13 Jan 2025 06:18:06 +0300 Subject: [PATCH 110/117] Fix import and formatting issues for Remove_Duplicates_from_sorted_Array --- solutions/Remove_Duplicates_from_sorted_Array.py | 4 ++-- .../test_Remove_Duplicates_from_sorted_Array.py | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/solutions/Remove_Duplicates_from_sorted_Array.py b/solutions/Remove_Duplicates_from_sorted_Array.py index 0eedc8155..eee8b32bd 100644 --- a/solutions/Remove_Duplicates_from_sorted_Array.py +++ b/solutions/Remove_Duplicates_from_sorted_Array.py @@ -5,9 +5,9 @@ @author: Dorcas Wanja Njeri """ -def remove_duplicates_from_sorted_array(nums: list) -> int: +def Remove_Duplicates_from_sorted_Array(nums: list) -> int: """ - Challenge: Remove Duplicates from Sorted Array + Challenge: Remove Duplicates from sorted Array Removes duplicates from a sorted array in place and returns the new length. Parameters: diff --git a/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py b/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py index d19a7c545..15392fdd6 100644 --- a/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py +++ b/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py @@ -7,7 +7,8 @@ import unittest -from solutions import remove_duplicates_from_sorted_array +from ..Remove_Duplicates_from_sorted_Array import Remove_Duplicates_from_sorted_Array + class TestRemoveDuplicatesFromSortedArray(unittest.TestCase): @@ -16,7 +17,7 @@ class TestRemoveDuplicatesFromSortedArray(unittest.TestCase): def test_basic_example(self): """Should remove duplicates in a basic sorted array""" nums = [1, 1, 2] - length = remove_duplicates_from_sorted_array(nums) + length = Remove_Duplicates_from_sorted_Array(nums) expected = [1, 2] self.assertEqual(length, 2) self.assertEqual(nums[:length], expected) @@ -24,7 +25,7 @@ def test_basic_example(self): def test_longer_array_with_duplicates(self): """Should remove duplicates from a longer sorted array""" nums = [0, 0, 1, 1, 2, 2, 3, 3, 4] - length = remove_duplicates_from_sorted_array(nums) + length = Remove_Duplicates_from_sorted_Array(nums) expected = [0, 1, 2, 3, 4] self.assertEqual(length, 5) self.assertEqual(nums[:length], expected) @@ -32,7 +33,7 @@ def test_longer_array_with_duplicates(self): def test_no_duplicates(self): """Should return the same list if there are no duplicates""" nums = [1, 2, 3, 4, 5] - length = remove_duplicates_from_sorted_array(nums) + length = Remove_Duplicates_from_sorted_Array(nums) expected = [1, 2, 3, 4, 5] self.assertEqual(length, 5) self.assertEqual(nums[:length], expected) @@ -40,7 +41,7 @@ def test_no_duplicates(self): def test_all_duplicates(self): """Should return a list with a single element if all elements are duplicates""" nums = [2, 2, 2, 2, 2] - length = remove_duplicates_from_sorted_array(nums) + length = Remove_Duplicates_from_sorted_Array(nums) # noqa: F821 expected = [2] self.assertEqual(length, 1) self.assertEqual(nums[:length], expected) @@ -48,13 +49,13 @@ def test_all_duplicates(self): def test_empty_array(self): """Should return 0 for an empty array""" nums = [] - length = remove_duplicates_from_sorted_array(nums) + length = Remove_Duplicates_from_sorted_Array(nums) self.assertEqual(length, 0) def test_single_element(self): """Should return the same list if there is only one element""" nums = [5] - length = remove_duplicates_from_sorted_array(nums) + length = Remove_Duplicates_from_sorted_Array(nums) # noqa: F821 expected = [5] self.assertEqual(length, 1) self.assertEqual(nums[:length], expected) From eb9589ab32f7125a8a76ba6898ed8dbd9b807140 Mon Sep 17 00:00:00 2001 From: Dorcas Njeri Date: Mon, 13 Jan 2025 06:40:31 +0300 Subject: [PATCH 111/117] Add new Palindrome_Number.py and fix tests --- solutions/tests/test_palindrome_number.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/solutions/tests/test_palindrome_number.py b/solutions/tests/test_palindrome_number.py index 3b00edf23..ced5f6cc8 100644 --- a/solutions/tests/test_palindrome_number.py +++ b/solutions/tests/test_palindrome_number.py @@ -6,8 +6,7 @@ """ import unittest - -from solutions.Palindrome_Number import is_Palindrome_Number +from ..Palindrome_Number import is_Palindrome_Number class TestPalindromeNumber(unittest.TestCase): From 5b754273d4e475efbf1814ede27ed3ff9d4c9146 Mon Sep 17 00:00:00 2001 From: Dorcas Njeri Date: Mon, 13 Jan 2025 07:02:33 +0300 Subject: [PATCH 112/117] Fix formatting and update logic for Palindrome_Number.py and add test updates --- solutions/Remove_Duplicates_from_sorted_Array.py | 1 + solutions/tests/test_Remove_Duplicates_from_sorted_Array.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/Remove_Duplicates_from_sorted_Array.py b/solutions/Remove_Duplicates_from_sorted_Array.py index eee8b32bd..00c91a19e 100644 --- a/solutions/Remove_Duplicates_from_sorted_Array.py +++ b/solutions/Remove_Duplicates_from_sorted_Array.py @@ -5,6 +5,7 @@ @author: Dorcas Wanja Njeri """ + def Remove_Duplicates_from_sorted_Array(nums: list) -> int: """ Challenge: Remove Duplicates from sorted Array diff --git a/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py b/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py index 15392fdd6..cba266634 100644 --- a/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py +++ b/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py @@ -10,7 +10,6 @@ from ..Remove_Duplicates_from_sorted_Array import Remove_Duplicates_from_sorted_Array - class TestRemoveDuplicatesFromSortedArray(unittest.TestCase): """Test the remove_duplicates_from_sorted_array function""" From 08f233c9b3a9ff143b7a98a8308b6c2fb7423a7c Mon Sep 17 00:00:00 2001 From: Dorcas Njeri Date: Mon, 13 Jan 2025 07:59:39 +0300 Subject: [PATCH 113/117] Fix import issue and update logic for Palindrome Number function --- solutions/palindrome number.py | 55 ----------------------- solutions/tests/test_palindrome_number.py | 2 +- 2 files changed, 1 insertion(+), 56 deletions(-) delete mode 100644 solutions/palindrome number.py diff --git a/solutions/palindrome number.py b/solutions/palindrome number.py deleted file mode 100644 index aeca6e583..000000000 --- a/solutions/palindrome number.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Created on 11/01/2025 -@author: Dorcas Wanja Njeri - -Script to check if an integer is a palindrome. -A palindrome number is one that remains the same when its digits are reversed. -The script includes basic unit tests to validate the correctness -of the function with various test cases. - -""" - -def is_palindrome_number(x: int) -> bool: - """" - Determines if a given integer is a palindrome number. - - A palindrome number is one that remains the same when its digits are reversed. - - Parameters: - x (int): The integer to check for palindrome. - - Returns: - bool: True if the number is a palindrome, False otherwise. - - Raises: - ValueError: If the input is not an integer. - - Examples: - >>> is_palindrome_number(121) - True - >>> is_palindrome_number(-121) - False - >>> is_palindrome_number(123) - False - >>> is_palindrome_number(5) - True - >>> is_palindrome_number(12321) - True - >>> is_palindrome_number(0) - True - """ - if not isinstance(x, int): - raise ValueError("The input must be an integer.") - - # Negative numbers and numbers that end with a 0 (except 0 itself) are not palindromes - if x < 0 or (x % 10 == 0 and x != 0): - return False - - reversed_half = 0 - while x > reversed_half: - reversed_half = reversed_half * 10 + x % 10 - x //= 10 - - return x == reversed_half or x == reversed_half // 10 diff --git a/solutions/tests/test_palindrome_number.py b/solutions/tests/test_palindrome_number.py index ced5f6cc8..613d171ea 100644 --- a/solutions/tests/test_palindrome_number.py +++ b/solutions/tests/test_palindrome_number.py @@ -6,7 +6,7 @@ """ import unittest -from ..Palindrome_Number import is_Palindrome_Number +from solutions.Palindrome_Number import is_Palindrome_Number class TestPalindromeNumber(unittest.TestCase): From 2320be81e91415bb57b411b3ad32256b68a5475b Mon Sep 17 00:00:00 2001 From: Dorcas Njeri Date: Mon, 13 Jan 2025 08:05:07 +0300 Subject: [PATCH 114/117] Fix import issue and update logic for Remove Duplicates function --- solutions/tests/test_Remove_Duplicates_from_sorted_Array.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py b/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py index cba266634..d49c83e43 100644 --- a/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py +++ b/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py @@ -7,7 +7,7 @@ import unittest -from ..Remove_Duplicates_from_sorted_Array import Remove_Duplicates_from_sorted_Array +from solutions.Remove_Duplicates_from_sorted_Array import Remove_Duplicates_from_sorted_Array class TestRemoveDuplicatesFromSortedArray(unittest.TestCase): From 032b029f5717eb3c45733d7f7b93a997bfcbd0c2 Mon Sep 17 00:00:00 2001 From: Dorcas Njeri Date: Mon, 13 Jan 2025 08:41:21 +0300 Subject: [PATCH 115/117] Resolve merge conflict in test_palindrome_number.py --- solutions/tests/test_palindrome_number.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_palindrome_number.py b/solutions/tests/test_palindrome_number.py index 613d171ea..04541cf01 100644 --- a/solutions/tests/test_palindrome_number.py +++ b/solutions/tests/test_palindrome_number.py @@ -10,7 +10,7 @@ class TestPalindromeNumber(unittest.TestCase): - """Test the is_palindrome_number function""" + """Test the is_Palindrome_Number function""" def test_palindrome_number(self): """Should return True for a number that is a palindrome""" From 6e789d4ced74b8fd8958cf6013975dc35f73f544 Mon Sep 17 00:00:00 2001 From: Dorcas Njeri Date: Mon, 13 Jan 2025 08:48:25 +0300 Subject: [PATCH 116/117] Fix test_palindrome_number.py --- solutions/tests/test_palindrome_number.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_palindrome_number.py b/solutions/tests/test_palindrome_number.py index 04541cf01..c13c451a3 100644 --- a/solutions/tests/test_palindrome_number.py +++ b/solutions/tests/test_palindrome_number.py @@ -6,7 +6,7 @@ """ import unittest -from solutions.Palindrome_Number import is_Palindrome_Number +from ..Palindrome_Number import is_Palindrome_Number class TestPalindromeNumber(unittest.TestCase): From 016f5cd749a5c8caf54a34494751ca7a08f991a1 Mon Sep 17 00:00:00 2001 From: Dorcas Njeri Date: Mon, 13 Jan 2025 08:52:41 +0300 Subject: [PATCH 117/117] fix import issues --- solutions/tests/test_Remove_Duplicates_from_sorted_Array.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py b/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py index d49c83e43..cba266634 100644 --- a/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py +++ b/solutions/tests/test_Remove_Duplicates_from_sorted_Array.py @@ -7,7 +7,7 @@ import unittest -from solutions.Remove_Duplicates_from_sorted_Array import Remove_Duplicates_from_sorted_Array +from ..Remove_Duplicates_from_sorted_Array import Remove_Duplicates_from_sorted_Array class TestRemoveDuplicatesFromSortedArray(unittest.TestCase):