diff --git a/.assets/logo.png b/.assets/logo.png new file mode 100644 index 000000000..e0f78fe6a Binary files /dev/null and b/.assets/logo.png differ diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index eba8a7be2..db6a23664 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 b3d7b0052..22b2c5c09 100644 --- a/.github/workflows/ci-checks.yml +++ b/.github/workflows/ci-checks.yml @@ -4,19 +4,19 @@ on: [push, pull_request, workflow_dispatch] jobs: ls_linting: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: ls-lint/action@v2.2.3 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ls-lint/action@v2.2.3 md_formatting: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: nosborn/github-action-markdown-cli@v3.3.0 - with: - files: . - config_file: .markdownlint.yml + - uses: actions/checkout@v4 + - uses: nosborn/github-action-markdown-cli@v3.3.0 + with: + files: . + config_file: .markdownlint.yml py_formatting: runs-on: ubuntu-latest @@ -55,11 +55,11 @@ 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: | @@ -73,7 +73,7 @@ jobs: 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 diff --git a/.ls-lint.yml b/.ls-lint.yml index 11468c980..f1b67a8ab 100644 --- a/.ls-lint.yml +++ b/.ls-lint.yml @@ -15,3 +15,4 @@ ignore: - __pycache__ - .ls-lint.yml - .markdownlint.yml + - .assets diff --git a/.vscode/settings.json b/.vscode/settings.json index 252022b48..4555e1491 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -122,5 +122,5 @@ "source.fixAll.ruff": "explicit", "source.organizeImports.ruff": "explicit" } - } + }, } diff --git a/README.md b/README.md index e69de29bb..e6d26fe4b 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,69 @@ +# MIT Emergent Talent Foundation Track Assignment - Group 12 + +![logo](.assets/logo.png) + +Welcome to the repository for **Group 12**'s assignment as part of the MIT Emerging +Talent Foundation +Track. This repository represents our collaborative effort to explore, learn, and +apply essential skills in software development through the implementation of a +**calculator project**. Each member of the team is contributing unique functionalities +to the calculator, reviewing each other’s code, and refining the project as a group. + +## Project Overview + +This repository serves as the final deliverable for the Foundation Track, showcasing +our teamwork and dedication to mastering foundational concepts in software development. +Our primary objective is to collaboratively design and develop a calculator, with +every team member contributing to its various functionalities. + +As a team of **10 emerging talents**, we are working together to: + +- Implement different features of the **calculator project**, including basic arithmetic, +advanced functions, and more. +- Collaborate on code reviews to ensure high quality and maintainability. +- Utilize **Git** for version control and collaboration. +- Navigate and manage projects effectively on **GitHub** using issues, pull requests, +and project boards. +- Adhere to **test-driven development (TDD)** cycles to ensure robust and reliable +code. + +## Tools and Technologies + +- **Programming Language**: Python +- **Version Control**: Git, integrated with GitHub +- **Editor**: Visual Studio Code (VS Code) with extensions to enhance productivity +- **Collaboration**: GitHub issues, pull requests, and project boards + +## About Group 12 + +We are a motivated and enthusiastic group of learners, collaborating as contributors +to this shared repository. This assignment is more than an assessment requirement +for us—it is an opportunity to build skills, share knowledge, and grow together as +a team. Through the development of this calculator project, we aim to foster a culture +of learning and innovation, focusing on: + +- **Teamwork**: Working together to design, implement, and refine the calculator’s +features. +- **Communication**: Ensuring clear and constructive collaboration during reviews +and discussions. +- **Continuous Learning**: Building technical and soft skills through hands-on experience +and feedback. + +## Project Structure + +The calculator project is structured to ensure modularity and ease of collaboration. +Key elements include: + +- **Feature Modules**: Each team member is responsible for implementing specific +features, such as addition, subtraction, or other advanced scientific functions. +- **Testing**: A dedicated test suite ensures all functionalities work as intended, +following TDD principles. +- **Documentation**: Comprehensive documentation accompanies the code to ensure +clarity and usability. + +--- + +We invite you to explore this repository and witness our journey of growth, teamwork, +and learning through the development of this calculator project. + +Thank you for visiting our repository! diff --git a/collaboration/README.md b/collaboration/README.md index 20889b951..744ab4e80 100644 --- a/collaboration/README.md +++ b/collaboration/README.md @@ -2,4 +2,63 @@ +## Group Norms Summary + +The group values open communication, mutual respect, and collaboration through +clear updates, constructive feedback, and trust. Meetings are punctual, inclusive, +and focused on progress, while conflicts are resolved respectfully. Flexibility +and support ensure individual growth and team success. + +--- + + +## Group Norms + +1. **Open Communication** + - Share ideas freely, listen actively, and use platforms like Slack and GitHub + for updates and collaboration. + - Channels: Use Slack for updates and general communication, and GitHub for technical + discussions. Zoom or other tools may be used for synchronous discussions. + - Response Time: Respond to messages within + one working day on weekdays to ensure timely progress. + +2. **Respect for Time** + Adhere to meeting schedules, start and end meetings punctually, and communicate + any delays or absences in advance. + +3. **Constructive Feedback** + - Give specific, respectful, and actionable feedback to help team members grow + and improve. + - Use a feedback framework like "What went well, What can improve, and How to + improve" for clarity and effectiveness. + +4. **Asynchronous Work** + Update task progress regularly and respect individual schedules while ensuring + timely completion of tasks. + +5. **Team Support** + Assist members facing challenges by sharing resources, guidance, and technical + expertise. + +6. **Conflict Resolution** + - Address disagreements calmly, focusing on ideas rather than individuals, and + use votes or polls to resolve prolonged debates. + - Resolve disagreements by focusing on ideas rather than individuals. + +7. **Trust and Transparency** + Build trust through consistent communication, meet deadlines, and handle damaged + trust openly and maturely. + +8. **Inclusivity and Respect** + Value diverse perspectives and ensure everyone has a chance to participate without + fear of exclusion or disrespect. + +9. **Documentation and Clarity** + - Maintain clear and updated documentation for tasks, code, and decisions to support + collaborative work. + - Use templates for consistent documentation across the team. + +10. **Focus on Growth** + Share learning opportunities, celebrate wins, and embrace challenges as opportunities + to improve collectively. diff --git a/collaboration/communication.md b/collaboration/communication.md index 484652e0f..fe222bdef 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -13,17 +13,20 @@ ______________________________________________________________________ ## Communication Schedule -| Day | How | The topic of discussion | | --- | :-: | ----------------------- | -| | | | +| Day | How | The topic of discussion | +| ----------- | --------- | ------------------------------ | +| 23.12.24 | Kick-off | Introduction and project overview | +| 30.12.2024 | Weekly update | Progress review and task allocation | +| 06.01.2025 | Deadline Check | Retrospective and deadline review | ## Communication Channels -how often will we get in touch on each channel, and what we will discuss there: +How often will we get in touch on each channel, and what we will discuss there: -- **Issues**: -- **Pull Requests**: -- **Slack/Discord**: -- **Video Calls**: +- **Issues**: Asynchronous, to discuss and track tasks. +- **Pull Requests**: Asynchronous, to review and merge code changes. +- **Slack/WhatsApp**: Asynchronous, for general communication and updates. +- **Video Calls**: Weekly on Mondays, with additional one-on-one calls as needed. ______________________________________________________________________ @@ -31,17 +34,25 @@ ______________________________________________________________________ ### Availability for calling/messaging -| Day | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday | | ------- | :----: | :-----: | :-------: | :------: | :----: | :------: | :----: | -| _name_ | | | | | | | | +|Day|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday| +|-|-|-|-|-|-|-|-| +|Yevheniia Rudenko|14:00-20:00|14:00-20:00|14:00-20:00| 14:00-20:00|14:00-20:00|19:00-21:00|19:00-21:00| +|Abdul Qader Dost|17:00-21:00| 17:00-21:00|17:00-21:00| 17:00-21:00 |17:00-21:00|14:00-20:00|14:00-20:00| +|Awaab Hussein|21:00-00:00|21:00-00:00| 21:00-00:00|21:00-00:00|21:00-00:00|21:00-00:00|21:00-00:00| +|Lukmon Alao|21:00-00:00|21:00-00:00| 21:00-00:00|21:00-00:00|21:00-00:00|21:00-00:00|21:00-00:00| +|Ridwan Ayinde|21:00-00:00|21:00-00:00| 21:00-00:00|21:00-00:00|21:00-00:00|13:00-16:00|13:00-16:00| +|Zephaniah Okoye|19:00-23:00|19:00-23:00|19:00-23:00|19:00-23:00|19:00-23:00|12:00-17:00|14:00-19:00| +|Olubusayo Solola|20:00-00:00|21:00-00:00| 20:00-00:00|21:00-00:00|20:00-00:00|13:00-16:00|12:00-16:00| ### How many hours everyone has per day -- name: _5h_; -- name: _6h_; -- name: _5h_; -- name: _4h_; -- name: _3h_; +- Yevheniia Rudenko: _~5h_; +- Abdul Qader Dost: _~4_; +- Awaab Hussein: _~3h_; +- Lukmon Alao: _3h_; +- Ridwan Ayinde: _3h_; +- Zephaniah Okoye: _~4h_; +- Olubusayo Solola: _2h_; ## Asking for Help diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 24079505c..c35b688b2 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -2,7 +2,9 @@ # Constraints -Some boundaries around our project. +This document outlines the key boundaries and constraints for our project. +These guidelines will help ensure alignment and smooth collaboration throughout +the project. ## External @@ -14,6 +16,22 @@ Some boundaries around our project. - power or connectivity - ... --> +These constraints are beyond our team's control and have +been imposed by external factors: + +- **Official Deadline:** The project must be completed by **10.01.2025** +(extended until 12.01.2025). +- **Number of Unit test:** We were not under any compulsion to have +a specific number of unit tests, however we were advised to test our +functions in different ways in order to make it robust, reliable, and +behaves correctly under any conditions such as edge cases that ensures +our software under unusual but valid inputs still works. +- **Tools and Platforms:** We will use **GitHub** for version +control and **Python** for development. +- **Code Review Requirements:** Each pull request must be reviewed +by at least one other team member before merging. +- **Accessibility and Connectivity:** Team members must ensure they have reliable +internet access to collaborate effectively. ## Internal: Involuntary @@ -22,6 +40,23 @@ Some boundaries around our project. - each of your individual skill levels - amount of time available to work on the project --> +These constraints come from within our team and are beyond our control: + +- **Time Zone Differences:** Team members are in different time zones, +requiring asynchronous work and collaboration. +- **Varied Availability:** Each team member has different primary +responsibilities, which may limit available time for the project. +- **Varying Skill Levels:** Team members have different levels of experience +with **Python** and **GitHub**, which may affect task completion speed and code quality. +- **Learning Curves:** As this project is part of a learning track, team members +are still in the process of mastering some of the technologies and practices, which +may affect productivity. +- **Health and Well-being:** Team members' health and well-being take priority, + and any health-related issues may impact project timelines. +- **Unforeseen Circumstances:** Unexpected events like personal + emergencies may affect team members' availability. +- **Work-Life Balance:** Team members must balance project work + with other personal and professional commitments. ## Internal: Voluntary @@ -32,3 +67,34 @@ Some boundaries around our project. - the number of hours you want to spend working - only using the colors black and white --> + +These constraints are decisions made by the team to help scope and guide the project: + +- **Submission Requirements:** All personal branches with functions must be +added to the project by **06.01.2025** (internal deadline), +with corresponding pull requests for each team member. +- **Task Division:** Team members will work on separate branches to minimize +merge conflicts and maintain clear ownership of tasks. +- **Review Process:** Each pull request must be thoroughly reviewed by at +least one other team member to ensure code quality and prevent errors. +- **Communication Channels:** We will use **Slack/WhatsApp** for general communication +and **GitHub** for technical discussions. **Zoom** may be used for synchronous +meetings if necessary. +- **Learning Goals:** Each team member will contribute tasks that align with +their personal learning objectives for the project. +- **Coding Standards:** We will follow a common coding style guide to ensure consistency +throughout the project. All code must adhere to **PEP8** standards and be well-documented. +- **Meeting Cadence:** Regular team meetings will be held once + a week to ensure alignment and progress tracking. +- **Documentation Standards:** All code and project documentation must be + maintained in a consistent and organized manner. +- **Code Quality Metrics:** The team will adhere to code quality metrics such as + maintaining a certain percentage of test coverage and ensuring minimal code duplication. +- **Knowledge Sharing:** Team members will share their learnings + and insights through regular knowledge-sharing sessions. + +--- + +This document serves as a framework to ensure all team members understand +the constraints and expectations for the project. All changes and feedback will +be reviewed before merging into the main branch. diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 11c583d2b..e54b5a337 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -1,5 +1,229 @@ # Learning Goals -## Collective +## Collective Goals -## Individual +1. **Effective Collaboration**: Develop skills in working as a team to contribute +to a shared codebase, fostering clear communication and conflict resolution. +2. **Version Control Mastery**: Learn to use Git effectively for version control, +including branching strategies, managing commit histories, and resolving merge conflicts. +3. **Code Review Practices**: Enhance the ability to perform thorough and constructive +code reviews, focusing on code quality, functionality, and documentation. +4. **Project Management with GitHub**: Gain experience with GitHub's project management +tools, such as: + - Creating and managing issues. + - Using project boards to track progress. + - Assigning tasks and setting priorities. +5. **Continuous Integration**: Understand and integrate CI/CD pipelines into the +development process to ensure code reliability and quality. +6. **Promoting Growth and Learning**: Foster an environment that supports continuous + learning by encouraging team members to enhance both technical and soft + skills through hands-on experience and feedback. +7. **Constructive Feedback Environment**: Create a space where feedback is + regularly shared, focusing on constructive input that helps team members + improve their work and grow professionally. + +## Individual Goals + +### Awaab Hussein + +1. **Git Basics and Advanced Usage**: + - Learn how to use Git via the terminal for local development. + - Understand how to clone remote branches and keep local branches up-to-date. + - Gain confidence in committing changes and managing commit histories. + - Master the process of pushing code to remote branches and managing pull requests. +2. **GitHub Navigation and Management**: + - Become proficient in navigating GitHub, including: + - Managing project boards. + - Understanding and addressing issues. + - Tracking and updating progress on tasks. +3. **Collaboration and Communication**: + - Improve skills in collaborating effectively with team members. + - Engage in productive discussions during pull requests, including: + - Reviewing and providing constructive feedback on others' code. + - Addressing feedback on your own code. +4. **Code Review Skills**: + - Learn to initiate and conduct thorough code reviews. + - Develop an eye for identifying issues in code and documentation. + - Practice discussing and resolving code-related challenges with peers. + +### Yevheniia Rudenko + +1. **Mastering Git and GitHub**: + - Learn to use Git effectively for version control, + including branching, merging, and conflict resolution. + - Get comfortable with GitHub’s tools for managing + issues, tracking progress with project boards, and collaborating on code. + +2. **Effective Collaboration and Communication**: + - Develop strong teamwork skills by contributing to a shared codebase, + ensuring clear communication, and collaborating on changes and task delegation. + +3. **Code Quality and Review**: + - Improve the ability to review code for functionality, quality, + and documentation, while providing constructive feedback to peers. + +4. **Project Management and CI/CD**: + - Gain experience using GitHub for project management, including task + distribution and progress tracking, while learning about CI/CD + processes to maintain code reliability. + +5. **Continuous Learning and Feedback**: + - Foster a culture of continuous learning and improvement, encouraging + the team to grow both technically and professionally through feedback and collaboration. + +### Abdul Qader Dost + +#### 1. Learn Git and GitHub + +- Master the fundamentals of version control using Git. +- Become proficient in using GitHub for collaboration, including creating +branches, committing changes, and merging pull requests. +- Understand the use of GitHub issues, pull requests, and project boards for +project tracking. + +#### 2. Collaboration and Communication + +- Improve communication skills for effective teamwork in a collaborative +coding environment. +- Learn how to share progress, ask for help, and provide feedback to +team members. +- Foster a collaborative environment through regular check-ins and discussions +on Slack or GitHub discussions. + +#### 3. Code Review + +- Understand best practices for conducting code reviews. +- Learn how to give constructive feedback on code while focusing on improving +the quality and maintainability of the project. +- Get comfortable reviewing others’ code and making suggestions for improvement. + +#### 4. Project Management with GitHub + +- Use GitHub tools for project management, such as project boards, issues, and milestones. +- Track progress, manage tasks, and prioritize work within the GitHub repository. +- Learn how to break down large tasks into smaller, manageable parts and ensure +deadlines are met. + +#### 5. Learning Recursion Algorithms + +- Understand the concept of recursion and how it applies to problem-solving. +- Implement common recursive algorithms and troubleshoot recursive logic. +- Apply recursion to real-world problems and optimize recursive solutions +where necessary. + +### Lukmon ALAO + +1. **Effective Collaboration**: + - I develop my collaboration skills as a programmer in a team project. + - I will improve my communication and skills and learn the dynamics of working + - in a multi-cultural environment. + +2. **version control and mastering**: + - learn the use git and git command for version mastering and merge conflict resolution. + - This skill is pivotal for hassle free collaboration. + +3. **Code review practices**: + - To imbibe the best practice for code writing and review code written by others. + - by adopting the review religiously as outlined in the template. + +4. **mastering Github**: + - familiarize with github interface. + - Gain an understanding of how to use it for effective collaboration. + +### Zephaniah Okoye + +1. **Advanced Git and GitHub Mastery**: + - Gain a deeper understanding of advanced Git features, + such as interactive rebase, cherry-picking, and stashing. + - Master the use of GitHub Actions for + automating workflows and continuous integration. + +2. **Proficiency in CI/CD Pipelines**: + - Learn to set up and configure CI/CD pipelines + using tools like GitHub Actions, Jenkins, or CircleCI. + - Ensure automated testing, code quality checks, and + deployment processes are integrated into the development workflow. + +3. **Enhanced Code Review Practices**: + - Develop a keen eye for identifying code + smells and potential refactoring opportunities. + - Practice providing detailed, constructive feedback on + pull requests to improve code quality and team collaboration. + +4. **Advanced Project Management with GitHub**: + - Utilize GitHub project boards to manage + complex project workflows and track progress efficiently. + - Implement issue templates and + workflows to streamline task creation and tracking. + +5. **Deep Dive into Documentation**: + - Write comprehensive and user-friendly + documentation for codebases, APIs, and workflows. + - Learn to use tools like Sphinx or MkDocs to + generate professional-quality project documentation. + +6. **Mentoring and Leadership**: + - Take on mentoring roles within the team to support + junior developers and foster a collaborative learning environment. + - Develop leadership skills by leading + project initiatives and facilitating team discussions. + +7. **Continuous Learning and Innovation**: + - Stay up-to-date with the latest development + tools, frameworks, and best practices. + - Encourage a culture of innovation by experimenting + with new technologies and sharing insights with the team. + +8. **Soft Skills Development**: + - Improve communication and presentation skills + to effectively convey ideas and technical concepts. + - Enhance conflict resolution skills to + address and resolve team challenges constructively. + +### Olubusayo Solola + +1. **Team Collaboration** + - Work better with others by joining team projects. + - Get better at communication with teammates. + +2. **Learning Git and Version Control** + - Practice using Git commands for managing versions, + and fixing merge conflicts. + - Make teamwork easier by keeping everything organized with Git. + +3. **Improving Code Reviews** + - Learn how to write cleaner code that others can understand easily. + - Get better at reviewing other people's code and giving helpful feedback. + +4. **Getting Comfortable with GitHub** + - Explore GitHub and learn how to use its features. + - Use GitHub to collaborate with others, + track issues, and manage projects. + +### Ridwan Ayinde + +1. **Improve Github Proficiency**: + - Gain confidence in collaborating with others on GitHub. + - Learn how to efficiently create and manage repository. + - Understand how to create branches, commits, pull requests + and its uses. + +2. **Master VS Code for Deployment**: + - Learn to use integrated Git features in VS code for + better control version. + - Practiced writing code, debugging, and running scripts on + VS code. + +3. **Problem Solving Skill**: + - Learn to ask meaningful questions anytime I am stuck. + - Applied problem solving strategy to complete assigned task. + +4. **Understand Asynchronous Collaboration**: + - Participate in project by contributing to repository meant for my + group. + - Understand the ability to work with my team asynchronously. + +--- + +*Each team member is encouraged to add their individual goals below to document +their learning objectives for this project.* diff --git a/collaboration/retrospective.md b/collaboration/retrospective.md index 74e18813b..53f1ede0b 100644 --- a/collaboration/retrospective.md +++ b/collaboration/retrospective.md @@ -1,23 +1,361 @@ +# Retrospective -# Retrospective +This document represents the retrospective for our Team Project, created by +Group 12. Below, you will find individual retrospectives +from each team member, reflecting on their experiences, +lessons learned, and areas for improvement. -## Stop Doing +The structure and plan for this retrospective were initially proposed to us as +a guide to help each participant conduct their own reflection. While this +structure is not mandatory, it was created to assist in organizing thoughts in +a consistent and professional manner. You can review the suggested structure +below, which we followed to provide clarity and coherence in our reflections. -## Continue Doing +--- -## Start Doing +## Retrospective Structure -## Lessons Learned +### Key Reflection Topics -______________________________________________________________________ +- Stop Doing +- Continue Doing +- Start Doing +- Lessons Learned -## Strategy vs. Board +### Strategy vs. Board - Key Questions for Reflection -### What parts of your plan went as expected? +- What parts of your plan went as expected? +- What parts of your plan did not work out? +- Did you need to add things that weren't in your strategy? +- Or remove extra steps? -### What parts of your plan did not work out? +By following this structured approach, we aimed to capture valuable insights +from each participant while maintaining a professional and organized +presentation of our reflections. This document not only serves as a +summary of our achievements and challenges but also as a foundation +for improving our workflows and collaboration in future projects. -### Did you need to add things that weren't in your strategy? +--- -### Or remove extra steps? +# Individual Retrospectives + +# Retrospective - Olubusayo Solola + +Below are things I will stop doing moving forward + +- Waste time instead of asking for help. +- Overlooking the importance of consistent communication with teammates. + +Below are things I will start/continue doing moving forward + +- Breaking tasks into smaller steps. +- Be available to help +- Proactively communicating progress with teammates +- Being more flexible and open to suggestions or changes proposed by the team. + +A lot didn't go as planned 😏 but what I learnt is teamwork always wins + +# Retrospective - Yevheniia Rudenko + +Below are things I will stop doing moving forward: + +- Working without a clear schedule and relying on daily availability instead of +following a structured plan. + +Below are things I will start/continue doing moving forward: + +- Following a more precise schedule to maintain better structure in my work. +- Ensuring clear and proactive communication with the team when I encounter +challenges or misunderstandings. +- Continuing to meet milestones and internal deadlines while +collaborating effectively with the team. + +Reflection: +Having a structure, even a relative one, proved to be very important for our +team. Milestones kept us on track, and we successfully achieved them together. +Teamwork can be incredibly productive and educational, especially when you can +rely on your teammates for help. Effective communication is the key to success. + +# Retrospective - Awaab Hussein + +## What I will stop doing + +Honestly, there’s nothing that I feel I need to stop doing. I’ve been intentional +about my approach to this project, and it’s been going great. For example, my +structured Git workflow, regular communication with the team, and consistent contributions +to reviews have all been effective. I’ve also learned the importance of balancing +quality and efficiency, and these efforts are paying off. + +## What I will continue doing + +- **Collaborative Reviews:** I’ve been actively reviewing my teammates’ work and +offering constructive feedback, and I will continue doing this because it improves +the overall quality of our code. +- **Clear Git Workflow:** I’ve been following a structured Git workflow by creating +branches, committing regularly, and writing detailed pull requests. I will stick +to this because it’s been very effective. +- **Team Support:** I’ve been fostering open discussions and supporting my teammates, +and I will keep doing this because it helps us work better as a team. + +## What I will start doing + +- **Regular Check-ins:** I plan in future projects to suggest having more frequent +check-ins with the team to stay aligned and track our progress more effectively. +- **Automated Testing:** I want to start incorporating more automated testing into +my workflow to catch potential errors early and ensure our code is reliable. + +## The lessons that I have learned + +- **Importance of Communication:** I’ve learned how crucial it is to communicate +effectively with my team. Misunderstandings can lead to delays, so I now focus on +being clear and concise. +- **Value of Feedback:** I’ve realized how valuable it is to receive and give constructive +feedback during code reviews. It’s helped me grow and write better code. +- **Patience with Learning:** I’ve also learned that it’s okay to take time to fully +understand new tools or techniques instead of rushing through them. + +## The parts of my plan that went as expected + +I found that my structured Git workflow and clear communication for pull requests +worked as I had planned. These practices helped me stay organized and complete tasks +efficiently. + +## The parts of my plan that did not work out + +There wasn’t anything that didn’t work out in the overall sense. The general track +of the project went exactly the way I planned it. Although the process involved +trying things out, and some of these didn’t work, that was all part of the learning +experience. Each trial added to my understanding and contributed to the success of +the project. + +## Things that I added that weren't in my initial strategy + +I had to include more detailed documentation for my work after realizing it +might not be clear enough for my teammates during reviews. + +# Retrospective - Zephaniah Okoye + +## What I will refrain from doing + +- **Delaying Communication**: Avoid waiting too + long before seeking help or clarifying doubts. +- **Ignoring Time Management**: Stop neglecting the + importance of a structured schedule. +- **Working in Isolation**: Avoid working on tasks + without collaborating with teammates. + +## What I will keep doing + +- **Collaborative Efforts**: Maintain active + participation in team discussions and code reviews. +- **Structured Workflow**: Continue following a clear + Git workflow and maintaining organized commit histories. +- **Proactive Communication**: Keep communicating progress + and challenges regularly with the team. + +## What I will commence doing + +- **Regular Check-Ins**: Implement more frequent check-ins with + the team to ensure alignment and track progress. +- **Automated Testing**: Incorporate more automated testing + into the development workflow to enhance code reliability. +- **Detailed Documentation**: Start adding more comprehensive + documentation to ensure clarity for teammates during reviews. + +## What went well + +- **Team Collaboration**: The team worked together effectively, + leading to timely completion of tasks and high-quality output. +- **Code Reviews**: Constructive feedback during code + reviews significantly improved the code quality. +- **Communication**: Regular and clear communication helped in + resolving issues quickly and maintaining progress. +- **Seeking Help**: My ability to ask for help from teammates both + privately and on the Slack general communication platform was a lifesaver. + +## What could have been improved + +- **Time Management**: More structured scheduling could have + helped in meeting deadlines more efficiently. +- **Early Testing**: Integrating automated testing earlier in + the development process could have caught potential issues sooner. +- **Documentation**: More detailed documentation from the beginning + would have provided better clarity for team members. + +## Lessons gleaned from my experience + +- **Importance of Teamwork**: Collaboration and clear + communication are key to project success. +- **Effective Feedback**: Constructive feedback during code + reviews helps improve code quality and personal growth. +- **Time Management**: A well-structured schedule enhances + productivity and ensures timely completion of tasks. +- **Continuous Learning**: It's crucial to stay updated with + new tools and techniques and to be patient with the learning process. + +# Retrospective - Ridwan Ayinde + +## Stop doing + +-Since I am new to github, and I followed all the instructions given to us, +I do not feel there is anything for me to stop doing. +I ensured I communicated with my team on problems I encounter, +and they are always responsive. + +## Continue doing + +- **Effective Communication:** I have been communicating with my team +effectively. Anything, I do not understand, I ask questions directly +on the group. + +- **Mid-Sprint Check-Ins:** I learnt a lot from the meetings on mondays where +we discuss progress and blockers. Like Insights tab on github, I did not notice +this tab until during the meeting. + +- **Thorough Testing:** I did thorough testing of code before I deploy +on github. + +- **Open Communication:** I enjoyed how open our communication is +on how to solve our problems on github. + +- **Naming Convention:** I noticed how my reviewer improved my naming. +convention for clarity. Therefore, I will put more attention to how I will +name my variables for better understanding. + +- **Control Version:** I will continue to make use of git and github, +because this effectively track changes. + +- **Performance Optimization:** I like the way we have checklist to mark + during the review stage. This is to ensure the person writing the code has + done all necessary things to ensure the task is 100% complete. + +## Start doing + +- **Automated Testing:** I want to start implementing automated + testing to reduce manual effort such as the way we did unit test + on the functions before deployment of our calculator project. + +- **Project Mangement Tools:** I believe it is better to use project +management tools like github to manage our project. This ensure better +tracking making everyone work on their own time within a given deadline. + +- **Post-Deployment Report** I will like to try out writing out post-deployment +reports to analyze feature such as a new function or a new update to evaluate +what went wrong, the challenges during the software development stage. + +## Lessons Learned + +- **Quality Over Speed:** In my team, we focused on choosing a simpler code +for our project so that we could have more time understanding the code, git, +vs code and github platform. +- **Effective Communication:** Effective communication is key within our team. +We communicated both on github, slack and the docs sent to us. We had less +misunderstandings amongst ourselves as we are all focused on getting the work +done. +- **Adaptability:** I have learnt to be adaptable as this crucial. This is first +time I will be working with people I have not met before and our project was a success. +Being flexible with our timeline helps the team succeed. + +- **Documentation Matters:** It helps provide clear explanation of how things work, +which makes it easier for onboarding and troubleshooting. + +## The part of my plan that went as expected + +I relied on studying what we were taught in class and collaborating +with the group members. And this went well, as they did wonders in helping me +understand the group project. + +## My Plan that did not work out + +I underestimated the time required for debugging especially when I want +to push my code to github and it is requesting me to merge. I actually expected +to just push my code after changing and the unexpected keep resisting me. + +## Things that I included that weren't in my initial strategy + +I had to my add some things in my code during the review that were not part of +my initial strategy. Like the edge cases in my add-function. + +# Retrospective - Abdul Qader Dost + +## Things I'll Stop Doing Moving Forward + +- **Procrastination**: I'll stop putting off tasks that I can tackle right away. +- **Underestimating Deadlines**: I'll stop assuming I have more time than I +actually do to complete tasks. + +## Things I'll Start/Continue Doing Moving Forward + +- **Proactive Communication**: I'll keep the team updated on my progress and +reach out for help whenever I'm stuck. +- **Action Over Stress**: Instead of stressing out or overthinking a task, I'll +focus on taking small actions to move forward. +- **Collaborative Reviews**: I'll continue giving helpful feedback to my teammates +and asking for feedback on my work to improve quality. +- **Structured Workflow**: I'll stick to a clear Git workflow with regular commits +and detailed pull requests to keep things organized. +- **Team Support**: I'll stay available to help my teammates and offer support +when needed. +- **Time Blocking**: I'll try to plan my work better by allocating dedicated time +for focused tasks. +- **Prioritizing Tasks**: I'll focus on the most urgent and impactful tasks first +to make sure I'm working on the right things. +- **Building Soft Skills**: I'll keep working on improving skills like negotiation, +adaptability, and conflict resolution to help the team function better. +- **Post-Task Reflection**: After each task, I'll take a moment to reflect on what +went well and what could be improved. +- **Knowledge Sharing**: I'll share insights and helpful techniques I pick up with +my team to help everyone grow together. + +## Reflection + +Having a structure and clear communication is really important. It helps me stay +on track and be more productive. Working with the team is not only productive, +but also really educational - we learn a lot from each other. The key takeaway? +Teamwork and effective communication really make a difference in achieving success. + +# Retrospective - Lukmon Olamilekan Alao + +## stop doing + +I will stop doing the following: + +- spending a long hour on finding solutions to technical problem I encountered +- acknowledge my beginner level and ask for help when I face challenges + +## Things I will continuing doing + +- dedicating extra time to catch-up with the group activities +- solving simple problem and increasing the difficulty as I progress +- using the git commands I have learnt so it become second nature +- being a good team player +- using the code review template for all the code I write + +## Things I will start doing + +I will start doing the following: + +- time blocking for programming practice +- adopting best code writing practice +- documenting the codes I write +- communicating my growth and the new skill I learnt on my social media +- volunteering to teach the skills I have learnt already + +### part of my plan that went well + +- ensured i complete my tasks against all odds +- learn as much as possible from my teammates +- have better understanding of how to use github and git + +### plans that did not work out + +- to help my teammates a lot +- to be present in all of the workshop and team meetings +- to submit all my assignment before the deadline day + +### Things I included that were not in my plan + +- using extra hour for self study +- watching lot of youtube videos on git and git command +- later using AI to learn the git commands effectively diff --git a/notes/README.md b/notes/README.md index 17e0f0ded..d21087cc9 100644 --- a/notes/README.md +++ b/notes/README.md @@ -1 +1,52 @@ # Notes + +## Calculator Project To-Do List + +### Step 1: Repository Setup + +- [ ] Clone the repository to your local machine. +- [ ] Open the repository in VS Code. +- [ ] Create a personal branch in the repository named after your assigned challenge. +- [ ] Create an issue for the assigned functions in the repository to track +progress and discussions. + +### Step 2: Function Implementation + +- [ ] Choose two functions from the available list. +- [ ] Create a file named `your_function.py` inside the `solutions` folder in the +repository. +- [ ] Document the selected functions in the your_function.py file. +- [ ] Implement the logic for your assigned functions in the calculator. + +### Step 3: Writing Docstrings + +- [ ] Write detailed docstrings for each function. +- [ ] Include a brief description, parameters, and return type in the docstring +for each function. + +### Step 4: Writing Unit Tests + +- [ ] Create a separate file for unit tests inside the `tests` folder, +named `test_your_function.py`. +- [ ] Write unit tests for each of your implemented functions. +- [ ] Ensure the unit tests cover a variety of cases, including edge cases. + +### Step 5: Committing Changes + +- [ ] Stage your changes in Git. +- [ ] Write a clear and descriptive commit message for your changes. +- [ ] Push your changes to your personal branch on GitHub. +- [ ] Create a pull request for it to be merged into the main branch. +- [ ] Write `closes #issue_number` (to link your pull request to the issue you +created for this function). + +### Step 6: Collaboration + +- [ ] Review the pull requests of other team members. +- [ ] Test the functionality of other implemented functions as part of the +review process. +- [ ] Provide constructive feedback and resolve any conflicts in the code. + +### Step 7: Finalizing + +- [ ] Merge your reviewed function branch into the main branch once approved. diff --git a/solutions/README.md b/solutions/README.md index 9852346d2..8d7eb33c8 100644 --- a/solutions/README.md +++ b/solutions/README.md @@ -1 +1,77 @@ -# Solutions +# Python Calculator Application Documentation + +## Simple Basic Calculator + +This is a simple calculator application written in Python. It includes +basic arithmetic operations, statistical calculations, and a few advanced +mathematical functions. + +### Features + +The calculator supports the following functionalities: + +- **Addition** (`add`): Adds two numbers. +- **Subtraction** (`subtract`): Subtracts the second number from the first. +- **Calculate Average** (`calculate_average`): Calculates the average of a +list of numbers. +- **Calculate Percentage** (`calculate_percentage`): Calculates the percentage +of a number. +- **Factorial** (`factorial`): Computes the factorial of a number. +- **Absolute Value** (`absolute_value`): Returns the absolute value of a number. +- **Find Max** (`find_max`): Finds the maximum value in a list of numbers. +- **Find Min** (`find_min`): Finds the minimum value in a list of numbers. +- **Inverse of a 2x2 Matrix** (`inverse_2x2_matrix`): Calculates the inverse +of a 2x2 matrix. +- **Binary Search (Recursive)** (`binary_search_recursive`): Performs a +binary search on a sorted list of numbers. +- **Square** (`square_function`): Calculates the square of a number. +- **Square root** (`square_root_function`): Calculates the square root of a number. +- **Multiply** (`multiply-function`): Multiplies two numbers and returns the result. +- **Modulus**(`modulus`): Calculates the remainder of dividing two numbers. +- **Divide**(`divide`): Divides the first number by +the second and handles division by zero. +- **Exponentiation**(`exponentiation`): A more general exponentiation function +to raise any number to any power. + +### Contributors + +- **Add**: Ridwan Ayinde +- **Subtract**: Ridwan Ayinde +- **Calculate Average**: Yevheniia Rudenko +- **Calculate Percentage**: Yevheniia Rudenko +- **Factorial**: Abdul Qader Dost +- **Absolute Value**: Abdul Qader Dost +- **Find Max**: Lukmon (NGN) +- **Find Min**: Lukmon (NGN) +- **Inverse of a 2x2 Matrix**: Awaab +- **Binary Search Algorithm (Recursive)**: Awaab +- **Square**: Ayodele Ayomide +- **Square root**: Ayodele Ayomide +- **Multiply**: Olubusayo Solola +- **Modulus**: Olubusayo Solola +- **Divide**: Zephaniah Okoye +- **Exponentiation**: Zephaniah Okoye + +### How to Use + +1. Clone the repository: + + ```bash + git clone https://github.com/MIT-Emerging-Talent/ET6-foundations-group-12.git + ``` + +2. Navigate to the project directory: + + ```bash + cd ET6-foundations-group-12 + ``` + +### Requirements + +- Python 3.7 or higher + +### License + +See the [LICENSE][license-link] file for more details. + +[license-link]: https://github.com/MIT-Emerging-Talent/ET6-foundations-group-12/pull/LICENSE diff --git a/solutions/absolute_value.py b/solutions/absolute_value.py new file mode 100644 index 000000000..c1de4d0a5 --- /dev/null +++ b/solutions/absolute_value.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for computing absolute value of a given number. + +Module contents: + - absolute_value: Computes the absolute value of a given number. + +Created on 12-27-2024 + +@author: Abdul Qader Dost +""" + + +def absolute_value(number: float) -> float: + """The absolute_value function computes the absolute value of a given number. + The absolute value of a number is its distance from zero, regardless of its sign. + For example, the absolute value of both -5 and 5 is 5. This function works for + both integer and floating numbers. + + Parameters: + number: int, float, A number whose absolute value is to be computed. + + Returns -> float, Returns the absolute value of the input number. + + Raises: + TypeError: If the input is not a number (int or float). + + >>> absolute_value(0) + 0 + + >>> absolute_value(10) + 10 + + >>> absolute_value(-10) + 10 + """ + # the number should be an integer or float + if not isinstance(number, (int, float)): + raise TypeError(f"The input: {number} must be an int or float") + + # Return the absolute value + return number if number >= 0 else -number diff --git a/solutions/add.py b/solutions/add.py new file mode 100644 index 000000000..8e150f8d3 --- /dev/null +++ b/solutions/add.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for adding two numbers. + + +Module contents: + -add: adds two numbers and returns the result. + + +Created on 28.12.2024 +@author : Ridwan Ayinde + +""" + + +def add(num1: float, num2: float) -> float: + """Add two numbers and returns their sum. + + Parameters: + num1:(int, float), the first number to be added + num2:(int, float), the second number to be added + + Returns -> float: the sum of num1 and num2 + + Raises: + AssertionError: if num1 or num2 is not an integer or float + + >>> add(4, 6) + 10.0 + >>> add(0, 0) + 0.0 + >>> add(7, -3) + 4.0 + >>> add(-5, -3) + -8.0 + + >>> add(7, -3) + 4.0 + >>> add(-5, -3) + -8.0 + + """ + # Validate inputs + assert isinstance(num1, (int, float)), "num1 must be a int or float" + assert isinstance(num2, (int, float)), "num2 must be a int or float" + return float(num1 + num2) diff --git a/solutions/calculate_average.py b/solutions/calculate_average.py new file mode 100644 index 000000000..844215cd8 --- /dev/null +++ b/solutions/calculate_average.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for calculating the average of two numbers. + +Module contents: + - calculate_average: calculates the average of two numbers. + +Created on 26.12.2024 +@author: Yevheniia Rudenko +""" + + +def calculate_average(the_first_number: float, the_second_number: float) -> float: + """Calculate the average of two numbers. + + Parameters: + the_first_number: float, the first number + the_second_number: float, the second number + + Returns: + float: the average of the two numbers + + Raises: + TypeError: if any argument is not a number + + Examples: + >>> calculate_average(4, 6) + 5.0 + >>> calculate_average(10, 20) + 15.0 + >>> calculate_average(-3, 3) + 0.0 + """ + if not isinstance(the_first_number, (int, float)): + raise TypeError( + f"the_first_number must be a number, got {type(the_first_number).__name__}" + ) + if not isinstance(the_second_number, (int, float)): + raise TypeError( + f"the_second_number must be a number, got {type(the_second_number).__name__}" + ) + + return (the_first_number + the_second_number) / 2 diff --git a/solutions/calculate_percentage.py b/solutions/calculate_percentage.py new file mode 100644 index 000000000..dd1c96b9f --- /dev/null +++ b/solutions/calculate_percentage.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for calculating the percentage of one number relative to another. + +Module contents: + - calculate_percentage: calculates what percentage the first number is of the second. + +Created on 26.12.2024 +@author: Yevheniia Rudenko +""" + + +def calculate_percentage(numerator: float, denominator: float) -> float: + """This function calculates the percentage by dividing numerator by denominator and then multiplying by 100. + + Parameters: + numerator: float, the numerator value + denominator: float, the denominator value + + Returns -> float: the percentage of `numerator` in `denominator` + + Raises: + AssertionError: if any argument is not a number + ZeroDivisionError: if `denominator` is zero + + >>> calculate_percentage(50, 200) + 25.0 + >>> calculate_percentage(5, 20) + 25.0 + >>> calculate_percentage(0, 100) + 0.0 + """ + assert isinstance(numerator, (int, float)), "numerator must be a number" + assert isinstance(denominator, (int, float)), "denominator must be a number" + if denominator == 0: + raise ZeroDivisionError("denominator must not be zero") + + return (numerator / denominator) * 100 diff --git a/solutions/exponentiation.py b/solutions/exponentiation.py new file mode 100644 index 000000000..81c45cb4b --- /dev/null +++ b/solutions/exponentiation.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for generating exponentiation of two numbers (inputs) "base" and "exponent" + +Module contents: + - Exponentiation: finds the exponentiation value of two numbers. + +Created on 05.01.2025 +@author: Zephaniah Okoye +""" + + +def exponentiation(base: float, exponent: int) -> float: + """ + Compute the exponentiation of a base raised to a given exponent. + + The function calculates base^exponent, which is the base multiplied + by itself exponent times. For example, 2^3 is 2 * 2 * 2 = 8. + + Parameters: + base (float): The base number to be raised. + exponent (int): The exponent to which the base is raised. + + Returns: + float: The result of the base raised to the given exponent. + + Raises: + TypeError: If the base is not a float or the exponent is not an int. + + Examples: + >>> exponentiation(2, 3) + 8.0 + >>> exponentiation(5, 0) + 1.0 + >>> exponentiation(1.5, 2) + 2.25 + >>> exponentiation(2, -2) + 0.25 + """ + if not isinstance(base, (float, int)): + raise TypeError(f"Invalid base: {base}. The base must be a float or int") + if not isinstance(exponent, int): + raise TypeError(f"Invalid exponent: {exponent}. The exponent must be an int") + + return float(base**exponent) diff --git a/solutions/factorial.py b/solutions/factorial.py new file mode 100644 index 000000000..dd277731a --- /dev/null +++ b/solutions/factorial.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for calculating the factorial of a number. + +Module contents: + - factorial: Calculate the factorial of a number. + +Created on 01-03-2024 + +@author: Abdul Qader Dost +""" + + +def factorial(number: int) -> int: + """The factorial function computes the factorial of a given + non-negative integer. The factorial of a number (n!) is the + result of multiplying all whole numbers from 1 up to number. + For example, the factorial of 5 is 5 * 4 * 3 * 2 * 1 = 120. + + Parameters: + number: int, A non-negative integer whose factorial is to be computed. + + Returns -> int, Returns the factorial of the input number. + + Raises: + ValueError: If the input is a negative integer. + TypeError: If the input is not an integer. + + + >>> factorial(1) + 1 + + >>> factorial(2) + 2 + + >>> factorial(3) + 6 + + >>> factorial(4) + 24 + """ + # the number should be an integer + if not isinstance(number, int): + raise TypeError("The input must be an int or float") + + if number < 0: + raise ValueError("The input must be a non-negative integer.") + + # Base Case 1 + if number == 0: + return 1 + + return number * factorial(number - 1) diff --git a/solutions/find_maximum_value.py b/solutions/find_maximum_value.py new file mode 100644 index 000000000..6a7583213 --- /dev/null +++ b/solutions/find_maximum_value.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +A module for calculating the highest value from a list. + +Module contents: + - find_maximum_value: returns the highest value from a list + +Created on 2024-12-26 +Author: Lukmon Olamilekan Alao +""" + + +def find_maximum_value(values: list): + """Returns the highest value from a list of numbers input + + takes a list of numbers and return a single number which is the highest value from the list. + + Parameters: + values: list, the input values to process + + Returns -> number: the highest value from the list of numbers. + + Raises: + TypeError: if input is not a list or a non-numerical data + + Examples: + >>> find_maximum_value([1, 2, 3, 4]) + 4 + >>> find_maximum_value([2.24, 4, 5.23, 1]) + 5.23 + >>> find_maximum_value([1.2, 3.4, 2.7, 0.5]) + 3.4 + """ + + assert isinstance(values, list) + assert all( + isinstance(item, (int, float)) for item in values + ) # "values must be an int or a float" + ordered_list_of_values = sorted(values) + highest = ordered_list_of_values[-1] + return highest diff --git a/solutions/find_minimum_value.py b/solutions/find_minimum_value.py new file mode 100644 index 000000000..455791581 --- /dev/null +++ b/solutions/find_minimum_value.py @@ -0,0 +1,43 @@ +""" +A module for calculating the minimum value from a list of values. + +Module contents: + - find_minimum_value: returns the lowest value in a list + +Created on 2024-12-28 +Author: Lukmon Olamilekan Alao +""" + + +def find_minimum_value(values: list): + """Returns the lowest value from a list of numbers input + + takes a list of numbers and return a single number which is the lowest value from the list. + + Parameters: + values: list, the input values to process + + Returns -> number: the lowest value from the list of numbers. + + Raises: + AssertionError: if input is not a list and non-numeric input data + + Examples: + >>> find_minimum_value([1, 2, 3, 4]) + 1 + >>> find_minimum_value([2.24, 4, 5.23, 1]) + 1 + >>> find_minimum_value([1.2, 3.4, 2.7, 0.5]) + 0.5 + """ + + # trunk-ignore(bandit/B101) + assert isinstance(values, list) # verifies that 'values' is a list + + # trunk-ignore(bandit/B101) + assert all( + isinstance(item, (int, float)) for item in values + ) # "values must be an int or a float" + ordered_list_of_values = sorted(values) # returns the list in ascending order + lowest = ordered_list_of_values[0] # gives the minimum value from the ordered list + return lowest diff --git a/solutions/matrix_2x2_inversion.py b/solutions/matrix_2x2_inversion.py new file mode 100644 index 000000000..bb5106c4b --- /dev/null +++ b/solutions/matrix_2x2_inversion.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +A module for calculating the inverse of a matrix that has two rows +and two columns. + +Module contents: + - matrix_2x2_inversion: returns the inverse of a 2x2 matrix. + +Created on 2024-12-26 +Author: Awaab98 +""" + + +def matrix_2x2_inversion(matrix: list[list[float]]) -> list[list[float]]: + """ + Calculates the inverse of a 2x2 matrix. + + The function calculates the inverse of a 2x2 matrix. The input matrix + must be an invertible 2x2 matrix (i.e., the determinant is not zero). + + + Parameters: + matrix: list, a list of lists representing a 2x2 matrix in which + every element is either int of float. + + Returns: + list: a list of lists representing the inverse of the input matrix. + + Raises: + TypeError: if the input matrix is not a list of lists. + TypeError: if one of the elements of the input matrix is not int or float. + AssertionError: if the input matrix is not a 2x2 matrix. + ValueError: if the determinant of input matrix is zero. + + + Examples: + >>> matrix_2x2_inversion([[1, 2], [3, 4]]) + [[-2.0, 1.0], [1.5, -0.5]] + >>> matrix_2x2_inversion([[1.0, 2.0], [3.0, 4.0]]) + [[-2.0, 1.0], [1.5, -0.5]] + >>> matrix_2x2_inversion([[1, 2.0], [3, 4]]) + [[-2.0, 1.0], [1.5, -0.5]] + """ + + # Check if the input matrix is a list of lists + if not isinstance(matrix, list) or not all(isinstance(row, list) for row in matrix): + raise TypeError("Input matrix must be a list of lists.") + + # Check if the elements of the input matrix are either int or float + if not all(isinstance(element, (int, float)) for row in matrix for element in row): + raise TypeError("Elements of input matrix must be either int or float.") + + # Check if the input matrix is a 2x2 matrix + if len(matrix) != 2 or not all(len(row) == 2 for row in matrix): + raise AssertionError("Input matrix must be a 2x2 matrix.") + + # Calculate the determinant + determinant = matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0] + + # If determinant is 0, the matrix is not invertible + if determinant == 0: + raise ValueError("Matrix is not invertible because determinant is zero.") + + # Calculate the inverse using the 2x2 matrix formula + inverse = [ + [matrix[1][1] / determinant, -matrix[0][1] / determinant], + [-matrix[1][0] / determinant, matrix[0][0] / determinant], + ] + + return inverse diff --git a/solutions/mode_of_numbers.py b/solutions/mode_of_numbers.py new file mode 100644 index 000000000..817dd08ff --- /dev/null +++ b/solutions/mode_of_numbers.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for generating the Mode numbers + +Module contents: + - mode_of numbers: finds the mode(s) of a list of numbers. + +Created on 12/01/2025 +@author: Deborah Oyibo +""" +from collections import Counter + +def mode_of_numbers(numbers: list[int]) -> list[int]: + """Returns the mode(s) of a list of numbers. + + The mode is the number that appears most frequently in the list. + If there are multiple modes, all of them are returned in a list. + If there is no mode (i.e., all elements appear once), an empty list is returned. + + Parameters: + numbers: A list of integers or floats. + + Returns: + A list of integers (or floats) representing the mode(s) of the input list. + + Raises: + AssertionError: If the input is not a list or if the list contains non-numeric values. + + >>> mode_of_numbers([1, 2, 2, 3, 4]) + [2] + + >>> mode_of_numbers([1, 2, 2, 3, 3, 4]) + [2, 3] + + >>> mode_of_numbers([1, 2, 3, 4]) + [] + + >>> mode_of_numbers([]) + [] + + >>> mode_of_numbers([5, 5, 5, 5]) + [5] + """ + + # Check if the input is a list + assert isinstance(numbers, list), "Input must be a list." + + # Check if all elements in the list are numbers (integers or floats) + assert all(isinstance(num, (int, float)) for num in numbers), "All elements in the list must be numbers." + + # Handle the case for an empty list + if not numbers: + return [] + + # Count the frequency of each element using Counter + count = Counter(numbers) + + # Get the highest frequency + max_frequency = max(count.values()) + + # Find all numbers that have the highest frequency + modes = [num for num, freq in count.items() if freq == max_frequency] + + return modes \ No newline at end of file diff --git a/solutions/modulus.py b/solutions/modulus.py new file mode 100644 index 000000000..45190e26d --- /dev/null +++ b/solutions/modulus.py @@ -0,0 +1,48 @@ +def modulus(a: float, b: float) -> float: + """ + Calculates the remainder when one number is divided by another. + + Parameters: + a (float): The numerator (the number to be divided). + b (float): The denominator (the number to divide by, must be non-zero). + + Returns: + float: The remainder when 'a' is divided by 'b'. + + Raises: + ValueError: If the denominator 'b' is zero. + TypeError: If 'a' or 'b' is not a float or int. + + Examples: + >>> modulus(10, 3) + 1 + >>> modulus(-10, 3) + -1 + >>> modulus(10, -3) + 1 + >>> modulus(-10, -3) + -1 + >>> modulus(10.5, 3) + 1.5 + >>> modulus(0, 3) + 0.0 + >>> modulus(10, 0) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ValueError: Denominator cannot be zero. + >>> modulus("10", 3) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + TypeError: Both numerator and denominator must be numbers. + """ + if not isinstance(a, (int, float)) or not isinstance(b, (int, float)): + raise TypeError("Both numerator and denominator must be numbers.") + + if b == 0: + raise ValueError("Denominator cannot be zero.") + + remainder = a % b + + # Adjust the result to match the dividend's sign + if (a < 0 and remainder > 0) or (a > 0 and remainder < 0): + remainder -= b + + return remainder diff --git a/solutions/multiply.py b/solutions/multiply.py new file mode 100644 index 000000000..367956646 --- /dev/null +++ b/solutions/multiply.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +A module for multiplication of two numbers. + +Module contents: + multiply: Multiplies two numbers (int or float) and returns the result. + +Created on 06.01.2025 +@author : Simi-Solola +""" + + +def multiply(a: float, b: float) -> float: + """ + Multiplies two numbers (int or float) and returns the result. + + Parameters: + a (int or float): The first number. + b (int or float): The second number. + + Returns: + int or float: The result of multiplying `a` and `b`. Returns an `int` if both inputs are integers, + otherwise returns a `float`. + + Raises: + AssertionError: If `a` or `b` is not an int or float. + + Examples: + >>> multiply(3, 4) + 12 + >>> multiply(2.5, 4) + 10.0 + >>> multiply(-2, 3.5) + -7.0 + >>> multiply(0, 5) + 0 + """ + # Defensive assertions to ensure valid input types + assert isinstance(a, (int, float)), "a must be an int or float" + assert isinstance(b, (int, float)), "b must be an int or float" + + result = a * b + # Return an int if both inputs are integers, else return a float + return int(result) if isinstance(a, int) and isinstance(b, int) else float(result) + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/solutions/negate.py b/solutions/negate.py new file mode 100644 index 000000000..b68aeca7a --- /dev/null +++ b/solutions/negate.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for negating numbers. + +Module contents: + - negate: generates the negative of the input number. + +Created on 02.01.2025 +@author: Abdul Qader Dost +""" + + +def negate(number: float) -> float: + """Returns the negation of the input number. + + Parameters: number (float): The number to negate. + + Returns: float: The negation of the input number. + + Raises: + TypeError: If the argument is not an integer or float. + + >>> negate(2) + -2 + + >>> negate(-2) + 2 + + >>> negate(10) + -10 + """ + + if not isinstance(number, (int, float)): + raise TypeError("Input must be a number") + return -number diff --git a/solutions/square_root.py b/solutions/square_root.py new file mode 100644 index 000000000..2b7f47dba --- /dev/null +++ b/solutions/square_root.py @@ -0,0 +1,37 @@ +def square_root(num: int | float) -> int | float: + """ + Calculate the square root of a number. + + Parameters: + num (int | float): The number to find the square root of. Must be non-negative. + + Returns: + int | float: The square root of the input number. Returns an int if the result is a whole number, otherwise a float. + + Raises: + ValueError: If the input number is negative. + + Examples: + >>> square_root(4) + 2 + >>> square_root(0) + 0 + >>> square_root(2.25) + 1.5 + >>> square_root(10) + 3.1622776601683795 + >>> square_root(-4) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ValueError: Cannot calculate the square root of a negative number. + """ + if num < 0: + raise ValueError("Cannot calculate the square root of a negative number.") + + result = num**0.5 + return int(result) if result.is_integer() else result + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/solutions/subtract.py b/solutions/subtract.py new file mode 100644 index 000000000..f82a7a4c4 --- /dev/null +++ b/solutions/subtract.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python 3 +# -*- coding: utf-8 -*- + +""" +A module for subtracting two numbers. + +Module contents: + subtract: subtract one number from another and returns the result. + +Created on 31.12.2024 +@author : Ridwan Ayinde + +""" + + +def subtract(num1: float, num2: float) -> float: + """ + Subtract one number from the other. + + Parameters: + num1:float, the first number + num2:float, the second number + + Returns -> float : the subtraction of b from a + + Raises: + AssertionError: if any argument is not a number + + >>> subtract (10, 5) + 5.0 + >>> subtract (-5, 5) + -10.0 + >>> subtract (-5, -2) + -3.0 + >>> subtract (-2, -2) + 0.0 + + """ + + # Validate inputs + assert isinstance(num1, (int, float)), "a must be a number" + assert isinstance(num2, (int, float)), " b must be a number" + return float(num1 - num2) diff --git a/solutions/tests/test_absolute_value.py b/solutions/tests/test_absolute_value.py new file mode 100644 index 000000000..77039b113 --- /dev/null +++ b/solutions/tests/test_absolute_value.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 12.29.2024 + +@author: Abdul Qader Dost +""" + +import unittest + +from ..absolute_value import absolute_value + + +class TestAbsoluteValue(unittest.TestCase): + """Test the absolute_value function""" + + def test_absolute_value_of_zero(self): + """It should return 0 when the input is 0""" + actual = absolute_value(0) + expected = 0 + self.assertEqual(actual, expected) + + def test_absolute_value_of_positive_number(self): + """It should return the positive value of a number""" + actual = absolute_value(10) + expected = 10 + self.assertEqual(actual, expected) + + def test_absolute_value_of_negative_number(self): + """It should return the positive value of a negative number""" + actual = absolute_value(-10) + expected = 10 + self.assertEqual(actual, expected) + + def test_absolute_value_of_float(self): + """It should return the absolute value of a float""" + actual = absolute_value(-3.14) + expected = 3.14 + self.assertEqual(actual, expected) + + def test_absolute_value_of_large_number(self): + """It should handle large numbers correctly""" + actual = absolute_value(1000000) + expected = 1000000 + self.assertEqual(actual, expected) + + def test_absolute_value_of_small_number(self): + """It should handle small numbers correctly""" + actual = absolute_value(0.000001) + expected = 0.000001 + self.assertEqual(actual, expected) + + def test_type_error_for_non_number_input(self): + """It should raise a TypeError for non-number input""" + with self.assertRaises(TypeError): + absolute_value("hello") + + def test_type_error_for_string_input(self): + """It should raise a TypeError for string input""" + with self.assertRaises(TypeError): + absolute_value("42") + + def test_type_error_for_list_input(self): + """It should raise a TypeError for list input""" + with self.assertRaises(TypeError): + absolute_value([1, 2, 3]) + + def test_type_error_for_dict_input(self): + """It should raise a TypeError for dict input""" + with self.assertRaises(TypeError): + absolute_value({"a": 1}) diff --git a/solutions/tests/test_add.py b/solutions/tests/test_add.py new file mode 100644 index 000000000..009e9c49f --- /dev/null +++ b/solutions/tests/test_add.py @@ -0,0 +1,93 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- + +""" +Test for addition of two numbers + +Created on 28.12.2024 +@author : Ridwan Ayinde + + +""" + +import unittest +from solutions.add import add # Import the function to test + + +class TestAddFunction(unittest.TestCase): + """ + TestAddFunction test two numbers + on different cases with the add function + and returns the result. + """ + + def test_add_positive_numbers(self): + """Test adding two positive numbers""" + self.assertEqual(add(4, 6), 10) + + def test_add_negative_numbers(self): + """Test add two negative numbers""" + self.assertEqual(add(-4, -5), -9) + + def test_add_mixed_sign_numbers(self): + """Test adding a positive and a negative number""" + self.assertEqual(add(4, -5), -1) + + def test_add_zero(self): + """Test adding zero to a number""" + self.assertEqual(add(4, 0), 4) + + def test_non_numbers(self): + """it should raise an AssertionError for non numbers input""" + with self.assertRaises(AssertionError): + add("a", 5) # Invalid input: string instead of a number + + def test_for_large_values(self): + """Test adding large values""" + self.assertAlmostEqual(add(1e10, 2e10), 3e10, places=1) + + def test_for_small_values(self): + """Test adding very small numbers""" + self.assertAlmostEqual(add(1e-10, 2e-10), 3e-10, places=10) + + def test_precision_handling(self): + """Test addition with floating point precision""" + self.assertAlmostEqual( + add(0.1, 0.2), 0.3, places=7, msg="precision error in add function" + ) + + def test_integer_overflow(self): + """Test large integers. Failed to handle large + integers correctly""" + result = add(2**100, 2**100) + self.assertEqual(result, 2**101) + + def test_string_inputs(self): + """Test for strings instead of numbers""" + with self.assertRaises(AssertionError): + add("3", "5") + + def test_none_inputs(self): + """Test for none input with number""" + with self.assertRaises(AssertionError): + add(None, 5) + + def test_non_numeric_iterables(self): + """Test adding a list with a number""" + with self.assertRaises(AssertionError): + add([1, 2, 3], 5) + + def test_boolean_inputs(self): + """Test adding booleans""" + self.assertEqual(add(True, False), 1.0) + self.assertEqual(add(True, True), 2.0) + self.assertEqual(add(False, True), 1.0) + self.assertEqual(add(False, False), 0.0) + + def test_boolean_inputs_with_numbers(self): + """Test adding boolean input with numbers""" + self.assertEqual(add(True, 5), 6.0) + + +if __name__ == "__main__": + unittest.main() diff --git a/solutions/tests/test_calculate_average.py b/solutions/tests/test_calculate_average.py new file mode 100644 index 000000000..626624cfa --- /dev/null +++ b/solutions/tests/test_calculate_average.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Tests for calculate_average function. + +This module includes tests for the following cases: + - Positive numbers + - Negative numbers + - Mixed positive and negative numbers + - Invalid (non-numeric) inputs + +Created on 26.12.2024 +Author: Yevheniia Rudenko +""" + +import unittest + +from ..calculate_average import calculate_average + + +class TestCalculateAverage(unittest.TestCase): + """Test the calculate_average function.""" + + def test_positive_numbers(self): + """It should return the correct average for positive numbers.""" + self.assertEqual(calculate_average(4, 6), 5.0) + + def test_negative_numbers(self): + """It should return the correct average for negative numbers.""" + self.assertEqual(calculate_average(-3, -5), -4.0) + + def test_positive_and_negative_numbers(self): + """It should return the correct average for both positive and negative numbers.""" + self.assertEqual(calculate_average(-3, 3), 0.0) + + def test_not_numbers(self): + """It should raise TypeError for non-numeric input.""" + with self.assertRaises(TypeError): + calculate_average("a", 3) + with self.assertRaises(TypeError): + calculate_average(3, None) diff --git a/solutions/tests/test_calculate_percentage.py b/solutions/tests/test_calculate_percentage.py new file mode 100644 index 000000000..0cd91de74 --- /dev/null +++ b/solutions/tests/test_calculate_percentage.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Tests for calculate percentage function + +Created on 26.12.2024 +@author: Yevheniia Rudenko +""" + +import unittest + +from ..calculate_percentage import calculate_percentage + + +class TestCalculatePercentage(unittest.TestCase): + """Test the calculate_percentage function.""" + + def test_positive_numbers(self): + """It should return percentage for positive numbers""" + self.assertEqual(calculate_percentage(50, 200), 25.0) + + def test_zero_numerator(self): + """It should return 0% when the first number is zero""" + self.assertEqual(calculate_percentage(0, 100), 0.0) + + def test_denominator_zero(self): + """It should raise ZeroDivisionError if the second number is zero""" + with self.assertRaises(ZeroDivisionError): + calculate_percentage(50, 0) + + def test_not_numbers(self): + """It should raise AssertionError for non-numeric input""" + with self.assertRaises(AssertionError): + calculate_percentage("50", 100) + + def test_100_percent(self): + """It should return 100% when numerator equals denominator""" + self.assertEqual(calculate_percentage(100, 100), 100.0) + + def test_negative_numerator(self): + """It should calculate correctly for negative numerator""" + self.assertEqual(calculate_percentage(-50, 200), -25.0) + + def test_negative_denominator(self): + """It should calculate correctly for negative denominator""" + self.assertEqual(calculate_percentage(50, -200), -25.0) + + def test_percentage_greater_than_100(self): + """It should calculate correctly for percentage greater than 100""" + self.assertEqual(calculate_percentage(300, 200), 150.0) + + def test_small_values(self): + """It should handle very small values correctly""" + self.assertAlmostEqual(calculate_percentage(0.0005, 0.002), 25.0, places=5) + + def test_large_values(self): + """It should handle very large values correctly""" + self.assertEqual(calculate_percentage(1_000_000, 10_000_000), 10.0) + + def test_precision_handling(self): + """It should maintain precision for floating-point calculations""" + self.assertAlmostEqual(calculate_percentage(1, 3), 33.3333, places=4) diff --git a/solutions/tests/test_exponentiation.py b/solutions/tests/test_exponentiation.py new file mode 100644 index 000000000..0d08ddd03 --- /dev/null +++ b/solutions/tests/test_exponentiation.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 05.01.2025 + +@author: Zephaniah Okoye +""" + +import unittest +from ..exponentiation import exponentiation + + +class TestExponentiation(unittest.TestCase): + """Test the exponentiation function""" + + def test_exponentiation_positive_exponent(self): + """It should return the correct result for a positive exponent""" + actual = exponentiation(2, 3) + expected = 8.0 + self.assertEqual(actual, expected) + + def test_exponentiation_zero_exponent(self): + """It should return 1.0 when the exponent is 0""" + actual = exponentiation(5, 0) + expected = 1.0 + self.assertEqual(actual, expected) + + def test_exponentiation_negative_exponent(self): + """It should return the correct result for a negative exponent""" + actual = exponentiation(2, -2) + expected = 0.25 + self.assertEqual(actual, expected) + + def test_exponentiation_float_base(self): + """It should return the correct result for a float base""" + actual = exponentiation(1.5, 2) + expected = 2.25 + self.assertEqual(actual, expected) + + def test_type_error_for_invalid_base(self): + """It should raise a TypeError for an invalid base""" + with self.assertRaises(TypeError): + exponentiation("2", 3) + + def test_type_error_for_invalid_exponent(self): + """It should raise a TypeError for an invalid exponent""" + with self.assertRaises(TypeError): + exponentiation(2, "3") + + def test_exponentiation_large_exponent(self): + """It should handle large exponents correctly""" + actual = exponentiation(2, 1000) + expected = 2**1000 + self.assertEqual(actual, expected) + + def test_exponentiation_zero_base_positive_exponent(self): + """It should return 0.0 when the base is 0 and exponent is positive""" + actual = exponentiation(0, 3) + expected = 0.0 + self.assertEqual(actual, expected) + + def test_exponentiation_zero_base_zero_exponent(self): + """It should return 1.0 when both base and exponent are 0""" + actual = exponentiation(0, 0) + expected = 1.0 + self.assertEqual(actual, expected) diff --git a/solutions/tests/test_factorial.py b/solutions/tests/test_factorial.py new file mode 100644 index 000000000..9622a18d7 --- /dev/null +++ b/solutions/tests/test_factorial.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 01-03-2024 + +@author: Abdul Qader Dost +""" + +import unittest + +from ..factorial import factorial + + +class TestFactorial(unittest.TestCase): + """Test the absolute_value function""" + + def test_factorial_of_zero(self): + """It should return 1 for the special case of zero, where 0! = 1.""" + actual = factorial(0) + expected = 1 + self.assertEqual(actual, expected) + + def test_factorial_of_one(self): + """It should return 1 when the input is 1, as 1! equals 1.""" + actual = factorial(1) + expected = 1 + self.assertEqual(actual, expected) + + def test_factorial_of_two(self): + """It should return 1 when the input is 2, as 2! equals 2.""" + actual = factorial(2) + expected = 2 + self.assertEqual(actual, expected) + + def test_factorial_of_three(self): + """It should return 1 when the input is 3, as 3! equals 6.""" + actual = factorial(3) + expected = 6 + self.assertEqual(actual, expected) + + def test_factorial_of_four(self): + """It should return 1 when the input is 4, as 4! equals 24.""" + actual = factorial(4) + expected = 24 + self.assertEqual(actual, expected) + + def test_factorial_of_negative_number(self): + """It should raise a ValueError when the input is a + negative number.""" + with self.assertRaises(ValueError): + factorial(-1) + + def test_factorial_float_input(self): + """It should raise a TypeError when the input is not an integer.""" + with self.assertRaises(TypeError): + factorial(3.5) + + def test_factorial_of_large_number(self): + """It should return the correct factorial for large numbers, + e.g., 10! = 3,628,800.""" + actual = factorial(40) + expected = 815915283247897734345611269596115894272000000000 + self.assertEqual(actual, expected) + + def test_factorial_of_string(self): + """It should raise a TypeError when the input is a string.""" + with self.assertRaises(TypeError): + factorial("string") + + def test_factorial_of_negative_non_integer(self): + """It should raise a TypeError for a negative non-integer.""" + with self.assertRaises(TypeError): + factorial(-3.5) diff --git a/solutions/tests/test_find_maximum_value.py b/solutions/tests/test_find_maximum_value.py new file mode 100644 index 000000000..9fa8b0d48 --- /dev/null +++ b/solutions/tests/test_find_maximum_value.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for testing the find_maximum_value function. + +Test categories: + - Standard test cases: test the function with typical inputs. + - Edge test cases: test the function with extreme inputs. + - Defensive tests: test the function with invalid inputs. + + +Created on 2024-12-28 +Author: Lukmon Alao +""" + +import unittest + +from ..find_maximum_value import find_maximum_value + + +class TestFindMaximumValue(unittest.TestCase): + """Test the find_maximum_value from a list""" + + # standard and edge test + def test_first_four_integers(self): + """It gives 4 when [1, 2, 3, 4] is pass to the function""" + actual = find_maximum_value([1, 2, 3, 4]) # call function with test argument + expected = 4 # hand-write the expected return value + self.assertEqual(actual, expected) + + def test_float_only(self): + """It should return the highest float value""" + self.assertEqual(find_maximum_value([1.2, 3.4, 2.7, 0.5]), 3.4) + + def test_list_of_float_and_int(self): + """It returns the highest value in list""" + self.assertEqual(find_maximum_value([2.24, 4, 5.23, 1]), 5.23) + + def test_negative_values(self): + """It should return the negative number with the lowest value""" + self.assertEqual(find_maximum_value([-1, -2, -3, -4]), -1) + + def test_list_with_negative_and_positive_int_values(self): + """It should return the highest value from the list""" + self.assertEqual(find_maximum_value([-1, 15, -9, 6]), 15) + + def test_list_with_negative_and_positive_float_values(self): + """It should return the highest value from the list""" + self.assertEqual(find_maximum_value([-0.35, 0.1, 2.4, -4.234]), 2.4) + + def test_list_with_both_negative_and_positive_values_of_int_and_float(self): + """It should return the highest value from the list""" + self.assertEqual(find_maximum_value([-1.2, 3, 3.78, -5]), 3.78) + + # Defensive tests + def test_none_input(self): + """It should raise Assertion error for none input""" + with self.assertRaises(AssertionError): + find_maximum_value(None) + + def test_input_value_is_not_list(self): + """It should raise an assertion error if the input value is a string""" + with self.assertRaises(AssertionError): + find_maximum_value("1") diff --git a/solutions/tests/test_find_minimum_value.py b/solutions/tests/test_find_minimum_value.py new file mode 100644 index 000000000..fbaf5ed95 --- /dev/null +++ b/solutions/tests/test_find_minimum_value.py @@ -0,0 +1,62 @@ +""" +A module for testing the find_minimum_value function. + +Test categories: + - Standard test cases: test the function with typical inputs. + - Edge test cases: test the function with extreme inputs. + - Defensive tests: test the function with invalid inputs. + + +Created on 2024-12-28 +Author: Lukmon Olamilekan Alao +""" + +import unittest + +from ..find_minimum_value import find_minimum_value + + +class TestFindMinimumValue(unittest.TestCase): + """Test the find_minimum_value from a list""" + + # standard and edge test + def test_first_four_integers(self): + """It gives 1 when [1, 2, 3, 4] is pass to the function""" + actual = find_minimum_value([1, 2, 3, 4]) # call function with test argument + expected = 1 # hand-write the expected return value + self.assertEqual(actual, expected) + + def test_float_only(self): + """It should return the smallest float value""" + self.assertEqual(find_minimum_value([1.2, 3.4, 2.7, 0.5]), 0.5) + + def test_list_of_float_and_int(self): + """It returns the smallest value in list""" + self.assertEqual(find_minimum_value([2.24, 4, 5.23, 1]), 1) + + def test_negative_values(self): + """It should return the negative number with the highest value""" + self.assertEqual(find_minimum_value([-1, -2, -3, -4]), -4) + + def test_list_with_negative_and_positive_int_values(self): + """It should return the smallest value from the list""" + self.assertEqual(find_minimum_value([-1, 15, -9, 6]), -9) + + def test_list_with_negative_and_positive_float_values(self): + """It should return the smallest value from the list""" + self.assertEqual(find_minimum_value([-0.35, 0.1, 2.4, -4.234]), -4.234) + + def test_list_with_both_negative_and_positive_values_of_int_and_float(self): + """It should return the smallest value from the list""" + self.assertEqual(find_minimum_value([-1.2, 3, 3.78, -5]), -5) + + # Defensive tests + def test_none_input(self): + """It should raise Assertion error for none input""" + with self.assertRaises(AssertionError): + find_minimum_value(None) + + def test_input_value_is_not_list(self): + """It should raise an assertion error if the input value is a string""" + with self.assertRaises(AssertionError): + find_minimum_value("1") diff --git a/solutions/tests/test_matrix_2x2_inversion.py b/solutions/tests/test_matrix_2x2_inversion.py new file mode 100644 index 000000000..295596404 --- /dev/null +++ b/solutions/tests/test_matrix_2x2_inversion.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for testing the matrix_2x2_inversion function. + +Test categories: + - Standard test cases: test the function with typical inputs. + - Edge test cases: test the function with extreme inputs. + - Defensive tests: test the function with invalid inputs. + + +Created on 2024-12-26 +Author: Awaab98 +""" + +import unittest +from solutions.matrix_2x2_inversion import matrix_2x2_inversion + + +class TestMatrix2x2Inversion(unittest.TestCase): + """Tests suite for the matrix_2x2_inversion function.""" + + # Standard test cases + def test_matrix_with_integer_elements(self): + """It should return the inverse of the input matrix, handling integers.""" + self.assertEqual( + matrix_2x2_inversion([[1, 2], [3, 4]]), [[-2.0, 1.0], [1.5, -0.5]] + ) + + def test_matrix_with_float_elements(self): + """It should return the inverse of the input matrix, handling floats.""" + self.assertEqual( + matrix_2x2_inversion([[1.0, 2.0], [3.0, 4.0]]), [[-2.0, 1.0], [1.5, -0.5]] + ) + + def test_matrix_with_mixed_elements(self): + """It should return the inverse of the input matrix, handling mixed-types elements.""" + self.assertEqual( + matrix_2x2_inversion([[1, 2.0], [3, 4]]), [[-2.0, 1.0], [1.5, -0.5]] + ) + + def test_matrix_with_negative_elements(self): + """It should return the inverse of the input matrix, handling negative elements.""" + self.assertEqual( + matrix_2x2_inversion([[-1, -2], [-3, -4]]), [[2.0, -1.0], [-1.5, 0.5]] + ) + + def test_identity_matrix(self): + """It should return the identity matrix.""" + self.assertEqual(matrix_2x2_inversion([[1, 0], [0, 1]]), [[1, 0], [0, 1]]) + + def test_symmetric_matrix(self): + """It should return the inverse.""" + self.assertEqual( + matrix_2x2_inversion([[2, 1], [1, 2]]), + [ + [0.6666666666666666, -0.3333333333333333], + [-0.3333333333333333, 0.6666666666666666], + ], + ) + + # Edge test cases + def test_matrix_with_zero_determinant(self): + """It should raise a ValueError because the determinant is zero.""" + with self.assertRaises(ValueError): + matrix_2x2_inversion([[1, 1], [2, 2]]) + + def test_matrix_with_zero_elements(self): + """It should raise a ValueError because the determinant is zero.""" + with self.assertRaises(ValueError): + matrix_2x2_inversion([[0, 0], [0, 0]]) + + # Defensive test cases + def test_non_list_input(self): + """It should raise a TypeError because the input is not a list of lists.""" + with self.assertRaises(TypeError): + matrix_2x2_inversion("1, 2, 3, 4") + + def test_non_numeric_elements(self): + """It should raise a TypeError because the input matrix contains non-numeric elements.""" + with self.assertRaises(TypeError): + matrix_2x2_inversion([[1, 2], [3, "4"]]) + + def test_non_2x2_matrix(self): + """It should raise an AssertionError because the input matrix is not a 2x2 matrix.""" + with self.assertRaises(AssertionError): + matrix_2x2_inversion([[1, 2, 3], [4, 5, 6]]) + + def test_zero_determinant_matrix(self): + """It should raise a ValueError because the determinant is zero.""" + with self.assertRaises(ValueError): + matrix_2x2_inversion([[1, 1], [2, 2]]) diff --git a/solutions/tests/test_mode_of_numbers.py b/solutions/tests/test_mode_of_numbers.py new file mode 100644 index 000000000..20557e732 --- /dev/null +++ b/solutions/tests/test_mode_of_numbers.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 12/01/2025 + +@author: Deborah Oyibo +""" + +# test_Mode_of_numbers.py +import unittest + +from solutions.mode_of_numbers import mode_of_numbers # Corrected import + +class TestModeOfNumbers(unittest.TestCase): + """Test the mode_of_numbers function""" + + def test_Mode_0(self): + """It should return an empty list for an empty input""" + actual = mode_of_numbers([]) + expected = [] + self.assertEqual(actual, expected) + + def test_Mode_1(self): + """It should return [2] for a list where 2 appears most frequently""" + actual = mode_of_numbers([1, 2, 2, 3, 4]) + expected = [2] + self.assertEqual(actual, expected) + + def test_Mode_2(self): + """It should return [2, 3] for a list with two modes""" + actual = mode_of_numbers([1, 2, 2, 3, 3, 4]) + expected = [2, 3] + self.assertEqual(actual, expected) + + def test_Mode_3(self): + """It should return an empty list for a list with no repeating numbers""" + actual = mode_of_numbers([1, 2, 3, 4]) + expected = [] + self.assertEqual(actual, expected) + + def test_Mode_4(self): + """It should return [5] for a list where 5 appears most frequently""" + actual = mode_of_numbers([5, 5, 5, 5]) + expected = [5] + self.assertEqual(actual, expected) + + def test_Mode_5(self): + """It should return [1] for a list where 1 appears the most times""" + actual = mode_of_numbers([1] * 1000 + [2] * 500) + expected = [1] + self.assertEqual(actual, expected) + + def test_Mode_6(self): + """It should return [-2] for a list with negative numbers""" + actual = mode_of_numbers([-1, -2, -2, -3]) + expected = [-2] + self.assertEqual(actual, expected) + + def test_Mode_7(self): + """It should return an empty list for a list where no number repeats equally""" + actual = mode_of_numbers([1, 2, 1, 2]) + expected = [] + self.assertEqual(actual, expected) + + def test_Mode_8(self): + """It should return an empty list for a list where all numbers appear only once""" + actual = mode_of_numbers([1, 2, 3, 4, 5, 6]) + expected = [] + self.assertEqual(actual, expected) + + def test_Mode_9(self): + """It should return [5, 10] for a list with two modes""" + actual = mode_of_numbers([5, 5, 10, 10, 15]) + expected = [5, 10] + self.assertEqual(actual, expected) + + def test_Mode_invalid_input(self): + """It should raise an assertion error for invalid input (non-list)""" + with self.assertRaises(AssertionError): + mode_of_numbers("not a list") + + def test_Mode_non_numeric_input(self): + """It should raise an assertion error if the list contains non-numeric values""" + with self.assertRaises(AssertionError): + mode_of_numbers([1, 2, "a"]) + +if __name__ == '__main__': + unittest.main() diff --git a/solutions/tests/test_modulus.py b/solutions/tests/test_modulus.py new file mode 100644 index 000000000..260a8773d --- /dev/null +++ b/solutions/tests/test_modulus.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Test for modulus of 2 numbers + +Created on 06.01.2025 + +@author:Simi-Solola + + +""" + +import unittest + +from solutions.modulus import modulus + + +class TestModulus(unittest.TestCase): + """ + Unit tests for the modulus function. + """ + + def test_positive_numbers(self): + """Test modulus with positive numbers.""" + self.assertEqual(modulus(10, 3), 1) + self.assertEqual(modulus(25, 4), 1) + self.assertEqual(modulus(100, 7), 2) + + def test_negative_numbers(self): + """Test modulus with negative numbers.""" + self.assertEqual(modulus(-10, 3), -1) + self.assertEqual(modulus(-10, -3), -1) + self.assertEqual(modulus(10, -3), 1) + + def test_zero_numerator(self): + """Test modulus when the numerator is zero.""" + self.assertEqual(modulus(0, 5), 0) + + def test_zero_denominator(self): + """Test modulus when the denominator is zero.""" + with self.assertRaises(ValueError): + modulus(10, 0) + + def test_float_inputs(self): + """Test modulus with floating-point numbers.""" + self.assertAlmostEqual(modulus(10.5, 3), 1.5) + self.assertAlmostEqual(modulus(-10.5, 3), -1.5) + self.assertAlmostEqual(modulus(-10.5, -3), -1.5) + self.assertAlmostEqual(modulus(10.5, -3), 1.5) + + +def test_large_and_small_numbers(self): + """Test modulus with very large and very small numbers.""" + self.assertEqual(modulus(1e18, 3), 1) + self.assertAlmostEqual(modulus(1, 1e-10), 0) + + +def test_defensive_inputs(self): + """Test modulus with invalid or unusual inputs.""" + with self.assertRaises(TypeError): + modulus("10", 3) # When Numerator is a string + with self.assertRaises(TypeError): + modulus(10, "3") # When Denominator is a string + with self.assertRaises(TypeError): + modulus(None, 3) # When Numerator is None + with self.assertRaises(TypeError): + modulus(10, None) # When Denominator is None + + +if __name__ == "__main__": + unittest.main() diff --git a/solutions/tests/test_multiply.py b/solutions/tests/test_multiply.py new file mode 100644 index 000000000..baba31ebd --- /dev/null +++ b/solutions/tests/test_multiply.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Test for multiplying of 2 numbers + +Created on 06.01.2025 + +@author: Simi-Solola +""" + +import unittest +import math +from solutions.multiply import multiply + + +class TestMultiply(unittest.TestCase): + """ + Test case for the multiply function. + Tests include: + - Positive numbers + - Negative numbers + - Error case for non-numeric input + - Boundary cases like large numbers, small numbers, infinity, and NaN + """ + + def test_multiply_positive_numbers(self): + """Test multiplying two positive numbers.""" + result = multiply(2, 3) + self.assertEqual(result, 6.0) + + def test_multiply_negative_number(self): + """Test multiplying a positive number by a negative number.""" + result = multiply(-2, 3) + self.assertEqual(result, -6.0) + + def test_multiply_non_numeric_input(self): + """Test that non-numeric inputs raise an assertion error.""" + with self.assertRaises(AssertionError): + multiply(2, "a") + + def test_multiply_float_input(self): + """Test multiplying two floating-point numbers.""" + result = multiply(2.5, 4.0) + self.assertEqual(result, 10.0) + + def test_multiply_large_numbers(self): + """Test multiplying very large numbers.""" + result = multiply(1e100, 1e100) + self.assertEqual(result, 1e200) + + def test_multiply_small_numbers(self): + """Test multiplying very small numbers.""" + result = multiply(1e-100, 1e-100) + self.assertEqual(result, 1e-200) + + def test_multiply_infinity(self): + """Test multiplying by infinity.""" + result = multiply(1, math.inf) + self.assertEqual(result, math.inf) + result = multiply(-1, math.inf) + self.assertEqual(result, -math.inf) + + def test_multiply_nan(self): + """Test multiplying by NaN.""" + result = multiply(math.nan, 5) + self.assertTrue(math.isnan(result)) + result = multiply(5, math.nan) + self.assertTrue(math.isnan(result)) + + +if __name__ == "__main__": + unittest.main() diff --git a/solutions/tests/test_negate.py b/solutions/tests/test_negate.py new file mode 100644 index 000000000..c5a075f47 --- /dev/null +++ b/solutions/tests/test_negate.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on 02.01.2025 + +@author: Abdul Qader Dost +""" + +import unittest + +from ..negate import negate + + +class TestNegate(unittest.TestCase): + """Tests for the negate function.""" + + def test_negate_positive_number(self): + """It should negate positive numbers correctly.""" + actual = negate(2) + expected = -2 + self.assertEqual(actual, expected) + + def test_negate_negative_number(self): + """It should negate negative numbers correctly.""" + actual = negate(-2) + expected = 2 + self.assertEqual(actual, expected) + + def test_negate_zero(self): + """It should handle zero correctly.""" + actual = negate(0) + expected = 0 + self.assertEqual(actual, expected) + + def test_non_numeric_input(self): + """It should raise a TypeError for non-numeric inputs.""" + with self.assertRaises(TypeError): + negate("hello") + + def test_overflow(self): + """It should handle overflow correctly.""" + actual = negate(1e308) # Maximum float value + expected = -1e308 + self.assertEqual(actual, expected) + + def test_underflow(self): + """It should handle underflow correctly.""" + actual = negate(-1e-323) # Minimum subnormal positive float value + expected = 1e-323 + self.assertEqual(actual, expected) diff --git a/solutions/tests/test_square_root.py b/solutions/tests/test_square_root.py new file mode 100644 index 000000000..4a46feca5 --- /dev/null +++ b/solutions/tests/test_square_root.py @@ -0,0 +1,43 @@ +import unittest +from solutions.square_root import square_root + + +class TestSquareRootFunction(unittest.TestCase): + """ + Unit tests for the square_root function. + Methods: + - test_square_root: Tests the square root of positive numbers, zero, and raises errors for negative numbers. + """ + + def test_square_root_of_positive_number(self): + """ + Test square root of a positive number. + Verifies that the square root of a positive number is calculated correctly. + """ + self.assertEqual(square_root(4), 2) + + def test_square_root_of_zero(self): + """ + Test square root of zero. + Verifies that the square root of zero is 0. + """ + self.assertEqual(square_root(0), 0) + + def test_square_root_of_decimal(self): + """ + Test square root of a decimal number. + Verifies that the square root of a decimal number is calculated correctly. + """ + self.assertAlmostEqual(square_root(2.25), 1.5) + + def test_square_root_of_negative_number(self): + """ + Test square root of a negative number (should raise ValueError). + Verifies that the function raises a ValueError for negative numbers. + """ + with self.assertRaises(ValueError): + square_root(-4) + + +if __name__ == "__main__": + unittest.main(argv=["first-arg-is-ignored"], exit=False) diff --git a/solutions/tests/test_subtract.py b/solutions/tests/test_subtract.py new file mode 100644 index 000000000..896194cd0 --- /dev/null +++ b/solutions/tests/test_subtract.py @@ -0,0 +1,64 @@ +#! usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Test for subtraction of one number from the other. + +Created on 31.12.2024 + +@author: + + +""" + +import unittest +from solutions.subtract import subtract + + +class TestSubtractFunction(unittest.TestCase): + """The TestsubtractFunction shows different + functions for different test cases and confirms + the result + """ + + def test_subtract_positive_numbers(self): + """Test subtracting two positive numbers""" + self.assertEqual(subtract(7, 4), 3) + + def test_subtract_negative_numbers(self): + """Test subtract two negative numbers""" + self.assertEqual(subtract(-5, -5), 0) + + def test_subtract_mixed_sign_numbers(self): + """This test should subtract the negative second + number from the first number""" + self.assertEqual(subtract(7, -5), 12) + + def test_not_numbers(self): + """This should raise an AssertionError for not numbers input""" + self.assertEqual(subtract(-5, -5), 0) + + def test_for_small_values(self): + """Test subtracting big number from small number""" + self.assertEqual(subtract(2, 9), -7) + + def test_precision_handling(self): + """Test subtraction with floating point precision""" + self.assertAlmostEqual( + subtract(0.3, 0.2), 0.1, places=7, msg="precision error in add function" + ) + + def test_for_very_small_values(self): + """Test subtracting very small numbers""" + self.assertAlmostEqual(subtract(4e-10, 2e-10), 2e-10, places=10) + + def test_integer_overflow(self): + """Test large integers to simulate overflow scenarios in fixed systems""" + large_number1 = 10**100 + large_number2 = 10**100 - 1 + result = subtract(large_number1, large_number2) + self.assertEqual(result, 1) + + +if __name__ == "__main__": + unittest.main()