From 9d832a3247d019eb45b3e6bd1022e72b49c01471 Mon Sep 17 00:00:00 2001 From: Madiha Maikzada <119412836+MadiMalik@users.noreply.github.com> Date: Sat, 21 Dec 2024 23:21:18 +0530 Subject: [PATCH 001/133] Update README.md --- collaboration/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collaboration/README.md b/collaboration/README.md index 20889b951..9054a4d29 100644 --- a/collaboration/README.md +++ b/collaboration/README.md @@ -1,5 +1,5 @@ # Collaboration - +Encourage Open and Respectful Communication: From 3834a49fd5a580d9886b6cf2002b96ef39454900 Mon Sep 17 00:00:00 2001 From: Fatima Malik <154790631+fatima-malik99@users.noreply.github.com> Date: Sat, 21 Dec 2024 22:56:10 +0500 Subject: [PATCH 002/133] Group Norms updated.md --- collaboration/README.md | 45 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/collaboration/README.md b/collaboration/README.md index 9054a4d29..43e7c51f3 100644 --- a/collaboration/README.md +++ b/collaboration/README.md @@ -3,3 +3,48 @@ Encourage Open and Respectful Communication: +# Collaborative Group Project Norms + +## 1. Encourage Open and Respectful Communication +- Ensure all members feel heard and valued in discussions. +- Prioritize clear and constructive communication, encouraging everyone to share their ideas and perspectives without fear of judgment or interruption. + +## 2. Balance Discussion and Debate +- Promote productive collaboration through thoughtful discourse. +- Use discussions to generate ideas and debates to critically evaluate them while maintaining respect and focusing on project goals. + +## 3. Technical Meetings +- Use **Slack** as the primary platform for technical discussions to maintain clear and accessible communication. + +## 4. Reminders for Code Review +- To ensure timely code reviews, feel free to send a friendly reminder on Slack or WhatsApp when necessary. + +## 5. Handling Delays and Meeting Attendance +- Meetings will start as scheduled to respect everyone's time. +- If unable to attend, members should share their situation in advance and catch up via recordings. +- If there are delays in completing tasks, inform the team promptly to prevent further delays. + +## 6. Maintain a Positive Team Environment +- Avoid rude or mean behavior. +- If any interaction causes discomfort, address it respectfully to resolve the issue and foster understanding. + +## 7. Create a Safe Feedback Culture +- Encourage constructive feedback to improve team performance. +- Focus on solutions rather than blame when giving or receiving feedback. + +## 8. Clear Handoffs When Required +- Minimize dependency issues by clearly communicating expectations and timelines when tasks require input or dependencies from another member. + +## 9. Respect for Different Work Styles +- Foster individuality while ensuring progress. +- Respect that everyone has a unique working style, provided deliverables are submitted on time and meet agreed standards. + +## 10. Responsiveness and Accountability +- While everyone has different schedules, acknowledging messages on Slack or WhatsApp—even with a brief reply—helps keep the team informed and connected. +- This ensures smooth collaboration and demonstrates respect for everyone’s efforts. + +--- + +## **Summary of Norms** +Our goal is to create a collaborative environment where everyone feels comfortable asking questions and working together. We will start with the basics, progress toward project goals, and remain respectful, helpful, and connected throughout the journey. + From 8f04891477811ebaf172c70d6c557bc12025074c Mon Sep 17 00:00:00 2001 From: Madiha Maikzada <119412836+MadiMalik@users.noreply.github.com> Date: Sat, 21 Dec 2024 23:30:03 +0530 Subject: [PATCH 003/133] remove the second headder --- collaboration/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/collaboration/README.md b/collaboration/README.md index 43e7c51f3..6ef626b5d 100644 --- a/collaboration/README.md +++ b/collaboration/README.md @@ -1,9 +1,8 @@ # Collaboration -Encourage Open and Respectful Communication: + -# Collaborative Group Project Norms ## 1. Encourage Open and Respectful Communication - Ensure all members feel heard and valued in discussions. From ec0b27ba1edf556e32ab779c26274e21924cb3c2 Mon Sep 17 00:00:00 2001 From: Madiha Maikzada <119412836+MadiMalik@users.noreply.github.com> Date: Sat, 21 Dec 2024 23:36:02 +0530 Subject: [PATCH 004/133] updated norms --- collaboration/README.md | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/collaboration/README.md b/collaboration/README.md index 6ef626b5d..8ca52d227 100644 --- a/collaboration/README.md +++ b/collaboration/README.md @@ -2,48 +2,46 @@ +## Summary of Norms +Our goal is to create a collaborative environment where everyone feels comfortable asking questions and working together. We will start with the basics, progress toward project goals, and remain respectful, helpful, and connected throughout the journey. -## 1. Encourage Open and Respectful Communication +### 1. Encourage Open and Respectful Communication - Ensure all members feel heard and valued in discussions. - Prioritize clear and constructive communication, encouraging everyone to share their ideas and perspectives without fear of judgment or interruption. -## 2. Balance Discussion and Debate +### 2. Balance Discussion and Debate - Promote productive collaboration through thoughtful discourse. - Use discussions to generate ideas and debates to critically evaluate them while maintaining respect and focusing on project goals. -## 3. Technical Meetings +### 3. Technical Meetings - Use **Slack** as the primary platform for technical discussions to maintain clear and accessible communication. -## 4. Reminders for Code Review +### 4. Reminders for Code Review - To ensure timely code reviews, feel free to send a friendly reminder on Slack or WhatsApp when necessary. -## 5. Handling Delays and Meeting Attendance +### 5. Handling Delays and Meeting Attendance - Meetings will start as scheduled to respect everyone's time. - If unable to attend, members should share their situation in advance and catch up via recordings. - If there are delays in completing tasks, inform the team promptly to prevent further delays. -## 6. Maintain a Positive Team Environment +### 6. Maintain a Positive Team Environment - Avoid rude or mean behavior. - If any interaction causes discomfort, address it respectfully to resolve the issue and foster understanding. -## 7. Create a Safe Feedback Culture +### 7. Create a Safe Feedback Culture - Encourage constructive feedback to improve team performance. - Focus on solutions rather than blame when giving or receiving feedback. -## 8. Clear Handoffs When Required +### 8. Clear Handoffs When Required - Minimize dependency issues by clearly communicating expectations and timelines when tasks require input or dependencies from another member. -## 9. Respect for Different Work Styles +### 9. Respect for Different Work Styles - Foster individuality while ensuring progress. - Respect that everyone has a unique working style, provided deliverables are submitted on time and meet agreed standards. -## 10. Responsiveness and Accountability +### 10. Responsiveness and Accountability - While everyone has different schedules, acknowledging messages on Slack or WhatsApp—even with a brief reply—helps keep the team informed and connected. - This ensures smooth collaboration and demonstrates respect for everyone’s efforts. ---- - -## **Summary of Norms** -Our goal is to create a collaborative environment where everyone feels comfortable asking questions and working together. We will start with the basics, progress toward project goals, and remain respectful, helpful, and connected throughout the journey. From cced8cdf2539be19e6c82ec2e9f86ae37269504e Mon Sep 17 00:00:00 2001 From: Mojtaba Fayyaz <123536786+mojtabafayyaz@users.noreply.github.com> Date: Sun, 22 Dec 2024 15:04:36 +0500 Subject: [PATCH 005/133] Update on section 3.md --- collaboration/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collaboration/README.md b/collaboration/README.md index 8ca52d227..3264f1400 100644 --- a/collaboration/README.md +++ b/collaboration/README.md @@ -15,7 +15,8 @@ Our goal is to create a collaborative environment where everyone feels comfortab - Use discussions to generate ideas and debates to critically evaluate them while maintaining respect and focusing on project goals. ### 3. Technical Meetings -- Use **Slack** as the primary platform for technical discussions to maintain clear and accessible communication. +- Use **Slack** for technical discussions and project updates. +- Use **WhatsApp** for urgent matters and quick clarifications. ### 4. Reminders for Code Review - To ensure timely code reviews, feel free to send a friendly reminder on Slack or WhatsApp when necessary. From 35e779144d313bde31b46bb1a6a78fcec96b5644 Mon Sep 17 00:00:00 2001 From: Muhammad Shahroz <114472614+Shahroz657@users.noreply.github.com> Date: Mon, 23 Dec 2024 03:06:49 +0500 Subject: [PATCH 006/133] Update README.md --- collaboration/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/collaboration/README.md b/collaboration/README.md index 3264f1400..6abd0d6ed 100644 --- a/collaboration/README.md +++ b/collaboration/README.md @@ -20,11 +20,12 @@ Our goal is to create a collaborative environment where everyone feels comfortab ### 4. Reminders for Code Review - To ensure timely code reviews, feel free to send a friendly reminder on Slack or WhatsApp when necessary. +- Encourage team members to notify the requester once the code review is completed. ### 5. Handling Delays and Meeting Attendance - Meetings will start as scheduled to respect everyone's time. - If unable to attend, members should share their situation in advance and catch up via recordings. -- If there are delays in completing tasks, inform the team promptly to prevent further delays. + ### 6. Maintain a Positive Team Environment - Avoid rude or mean behavior. @@ -35,6 +36,7 @@ Our goal is to create a collaborative environment where everyone feels comfortab - Focus on solutions rather than blame when giving or receiving feedback. ### 8. Clear Handoffs When Required +- If there are delays in completing tasks, inform the team promptly to prevent further delays. - Minimize dependency issues by clearly communicating expectations and timelines when tasks require input or dependencies from another member. ### 9. Respect for Different Work Styles From 4529ef61f4feb4ac609bedb5807bd1d149b50098 Mon Sep 17 00:00:00 2001 From: Fatima Malik <154790631+fatima-malik99@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:47:05 +0500 Subject: [PATCH 007/133] Team name and overview added. --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index e69de29bb..3807226f0 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,12 @@ +# Git it Done + +## Overview +Welcome to the **Git it Done** repository! + +This is a collaborative learning project where our team works together to solve problems and learn new skills. Each teammate will: +- Solve 2 problems. +- Help resolve 2 problems contributed by others. + +Our team is made up of people with different levels of experience—some of us are complete beginners, while others have a little experience. But one thing we all share is a strong eagerness to learn. By the end of this project, we will no longer be complete beginners. + +We are learning collaboratively, growing through our mistakes, and working as a team to improve. . From a16e848eec0d02d62cc108663d5357e72ce8e4e2 Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Mon, 23 Dec 2024 20:36:00 +0530 Subject: [PATCH 008/133] example --- solutions/abcd.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 solutions/abcd.py diff --git a/solutions/abcd.py b/solutions/abcd.py new file mode 100644 index 000000000..136c80182 --- /dev/null +++ b/solutions/abcd.py @@ -0,0 +1 @@ +print("example") \ No newline at end of file From 74fc680dcae3f116ebbb1879a59a2d309670baed Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Mon, 23 Dec 2024 21:56:06 +0530 Subject: [PATCH 009/133] added a comment --- solutions/abcd.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/solutions/abcd.py b/solutions/abcd.py index 136c80182..739dfd80f 100644 --- a/solutions/abcd.py +++ b/solutions/abcd.py @@ -1 +1,2 @@ -print("example") \ No newline at end of file +# this is an example file +print("example") From c5ef39f64792c627bb82ff5f9d9263b6d98fe1dd Mon Sep 17 00:00:00 2001 From: Madiha Maikzada <119412836+MadiMalik@users.noreply.github.com> Date: Wed, 25 Dec 2024 00:14:37 +0530 Subject: [PATCH 010/133] Update communication.md Added communication methods and updated my schedule --- collaboration/communication.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/collaboration/communication.md b/collaboration/communication.md index 484652e0f..02c0a1841 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -20,10 +20,10 @@ ______________________________________________________________________ how often will we get in touch on each channel, and what we will discuss there: -- **Issues**: -- **Pull Requests**: -- **Slack/Discord**: -- **Video Calls**: +- **Issues**: Adding availability to the schedule +- **Pull Requests**: Reviewing each other's code and giving feedback +- **Slack/Discord**: Email, Slack, and WhatsApp +- **Video Calls**: Zoom and Google Meet ______________________________________________________________________ @@ -33,20 +33,20 @@ ______________________________________________________________________ | Day | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday | | ------ | :----: | :-----: | :-------: | :------: | :----: | :------: | :----: | -| _name_ | | | | | | | | +**Madiha**| Monday ✓| Tuesday ✓| Wednesday ✓| Thursday ✓| Friday ✓| Saturday ✓| Sunday ✓| | ### How many hours everyone has per day - name: _5h_; - name: _6h_; -- name: _5h_; +- Madiha: _5h_; - name: _4h_; - name: _3h_; ## Asking for Help There's a fine line between confidently learning from your mistakes, and -stubbornly getting no where. Here is a general guide for when to ask for help +stubbornly getting nowhere. Here is a general guide for when to ask for help based on how long you've been stuck on the same problem: 1. _0 -> 30 min_: Try on your own From d25c9bf9dc5db58ff25a16c3858e775f5c5330d3 Mon Sep 17 00:00:00 2001 From: Madiha Maikzada <119412836+MadiMalik@users.noreply.github.com> Date: Wed, 25 Dec 2024 03:41:44 +0530 Subject: [PATCH 011/133] Update constraints.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This pull request defines our group’s constraints in the constraints file, detailing external, involuntary, and voluntary constraints. It includes platform requirements, deadlines, team skill levels, and agreed standards for testing, documentation, and collaboration. --- collaboration/constraints.md | 49 ++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 24079505c..a6c028932 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -1,10 +1,10 @@ - + # Constraints -Some boundaries around our project. +This section outlines the boundaries and considerations for our project to ensure smooth collaboration, efficient learning, and effective task completion. -## External +## External Constraints -## Internal: Involuntary +**These factors outside our control influence how we work on this project.** +- **Platform Requirements:** + - Problems must be selected from the workshop's exercises, CodeWars, LeetCode, or similar coding platforms. + - Solutions must comply with the workshop's requirements (e.g., unittest, documentation, and clear variable name). +- **Deadlines:** + - Projects must be finished at the timeline set by the MIT Emerging Talent program. + - Each member must solve and review problems within the agreed-upon timeframes. +- **Tools and Resources:** + - GitHub must be used for version control, communication, and documentation. + - The team must rely on publicly available resources (e.g., online tutorials and documentation) to enhance learning. + + + +## Internal Constraints: Involuntary +**These are limitations or challenges within the team that we need to navigate effectively.** + - **Experience Levels:** + - Team members have varying levels of experience in programming, unit testing, and documentation. + - Some members may require more time or support to complete tasks. +- **Availability:** + - Team members may have different schedules and commitments, limiting synchronous collaboration opportunities. +- Technical Skills: + - Limited familiarity with tools like Git, GitHub workflows, or unit testing frameworks. + -## Internal: Voluntary +## Internal Constraints: Voluntary +These are self-imposed rules or boundaries designed to improve collaboration and learning outcomes. +- **Unit Testing:** + - All submitted solutions must include unit tests to verify correctness and edge cases. + - Use Python’s unittest module (or equivalent) for testing. +- **Documentation Standards:** + - All code must include meaningful comments explaining the logic. + - Problem solutions must include documentation with: + - Problem description. + - Approach and thought process. + - Test cases used. +- **Communication Protocols:** + - Use GitHub Issues to discuss problems and tasks. + - At least one other member must review pull requests before merging. + - Constructive feedback is required for all reviews. +- **Collaborative Learning:** + - Each member must share insights or challenges they faced during problem-solving to help others learn. + - Regular check-ins (via GitHub comments or virtual meetings) to ensure alignment. From 21646dbedd66fc13c3cee076b611a08a2209fc6a Mon Sep 17 00:00:00 2001 From: Muhammad Shahroz Date: Wed, 25 Dec 2024 04:53:40 +0500 Subject: [PATCH 012/133] Updated communications.md --- collaboration/communication.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/collaboration/communication.md b/collaboration/communication.md index 02c0a1841..60ab49de5 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -23,7 +23,7 @@ how often will we get in touch on each channel, and what we will discuss there: - **Issues**: Adding availability to the schedule - **Pull Requests**: Reviewing each other's code and giving feedback - **Slack/Discord**: Email, Slack, and WhatsApp -- **Video Calls**: Zoom and Google Meet +- **Video Calls**: Zoom and Google Meet ______________________________________________________________________ @@ -35,9 +35,11 @@ ______________________________________________________________________ ------ | :----: | :-----: | :-------: | :------: | :----: | :------: | :----: | **Madiha**| Monday ✓| Tuesday ✓| Wednesday ✓| Thursday ✓| Friday ✓| Saturday ✓| Sunday ✓| | +**Shahroz**| Monday ✓| Tuesday ✓| Wednesday ✓| Thursday ✓| Sunday ✓| | + ### How many hours everyone has per day -- name: _5h_; +- Shahroz: _4h_; - name: _6h_; - Madiha: _5h_; - name: _4h_; From 231aad635dbd4f92393012c231044eeab8b21485 Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Wed, 25 Dec 2024 12:07:56 +0500 Subject: [PATCH 013/133] updated meeting agendas --- collaboration/communication.md | 117 ++++++++++++++++++++++++++------- 1 file changed, 94 insertions(+), 23 deletions(-) diff --git a/collaboration/communication.md b/collaboration/communication.md index 02c0a1841..b4ded30bb 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -7,41 +7,112 @@ you can share the rest in confidence with you group by another channel --> -# Communication - -______________________________________________________________________ +# Communication Plan ## Communication Schedule +This is the schedule for each week, it'll be changed every week. + +| Day | How | The topic of discussion | +|-----------|:----:|-------------------------| +|Monday |Zoom | | +|Tuesday |Zoom | | +|Wednesday |Zoom |GitHub Issues and Pull requests + Discuss and choose problems. | +|Thursday |Zoom | | +|Friday |Zoom | | +|Saturday |Zoom | | +|Sunday |Zoom | | -| Day | How | The topic of discussion | | --- | :-: | ----------------------- | -| | | | +--- ## Communication Channels -how often will we get in touch on each channel, and what we will discuss there: +All the technical disussions will be done on slack. But for general discussions we will use Whtsapp -- **Issues**: Adding availability to the schedule -- **Pull Requests**: Reviewing each other's code and giving feedback -- **Slack/Discord**: Email, Slack, and WhatsApp -- **Video Calls**: Zoom and Google Meet +- **Issues**: Adding availability to the schedule +- **Pull Requests**: Reviewing each other's code and giving feedback +- **Slack/Discord**: Email, Slack, and WhatsApp +- **Video Calls**: Zoom and Google Meet -______________________________________________________________________ +--- ## Availability -### Availability for calling/messaging - -| Day | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday | | ------- | :----: | :-----: | :-------: | :------: | :----: | :------: | :----: | -**Madiha**| Monday ✓| Tuesday ✓| Wednesday ✓| Thursday ✓| Friday ✓| Saturday ✓| Sunday ✓| | - -### How many hours everyone has per day +### Availability for Calling/Messaging + +| Day | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday | +|----------|:------:|:-------:|:---------:|:--------:|:------:|:--------:|:------:| +| **Madiha** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| **Fatima** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | + +### How Many Hours Everyone Has Per Day + +- Fatima: _5h_ +- Name: _6h_ +- Madiha: _5h_ +- Name: _4h_ +- Name: _3h_ + +--- + +## Meeting Agendas and Records + +### Previous Meetings + +#### Meeting 1 +- **Date:** 20-12-2024 +- **Discussion Topics:** + - Introduction + - Team Norms + - Strategies for tackeling project + +- **Decisions Made:** + - Decided 7 team norms. + - Study google documents. + +#### Meeting 2 +- **Date:** 21-12-2024 +- **Discussion Topics:** + - Finalising group norms. + - Team name +- **Decisions Made:** + - Finalised 10 norms + - Git it Done- team name decided + - First commit made on github + +#### Meeting 3 +- **Date:** 22-12-2024 +- **Discussion Topics:** + - Discussion on assigned Google docs + - Guiding new members of team +- **Decisions Made:** + - Official work will be started from tomorrow. + +#### Meeting 4 +- **Date:** 23-12-2024 +- **Discussion Topics:** + - Pull requests + - Branches +- **Decisions Made:** + - Tasks assigned to each team member. + - Explore more about pull requests and branches + - Explore issues on github. + +--- + +### Upcoming Meetings + +#### Meeting 5 +- **Date:** 25-12-2024 +- **Discussion Topics:** + - [Point 1] + - [Point 2] +- **Decisions Made:** + - [Decision 1] + - [Decision 2] +- **Action Items:** + - [Action 1] + - [Action 2] -- name: _5h_; -- name: _6h_; -- Madiha: _5h_; -- name: _4h_; -- name: _3h_; ## Asking for Help From 5f63132072add5da6d4973d12d04f617b701837f Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Wed, 25 Dec 2024 12:25:00 +0500 Subject: [PATCH 014/133] Fix markdown linter errors --- collaboration/communication.md | 108 ++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 49 deletions(-) diff --git a/collaboration/communication.md b/collaboration/communication.md index b4ded30bb..cd644f5c6 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -1,32 +1,33 @@ # Communication Plan ## Communication Schedule -This is the schedule for each week, it'll be changed every week. - -| Day | How | The topic of discussion | -|-----------|:----:|-------------------------| -|Monday |Zoom | | -|Tuesday |Zoom | | -|Wednesday |Zoom |GitHub Issues and Pull requests + Discuss and choose problems. | -|Thursday |Zoom | | -|Friday |Zoom | | -|Saturday |Zoom | | -|Sunday |Zoom | | + +This is the schedule for each week, and it will be updated weekly. + +| Day | How | The topic of discussion | +|-----------|:----:|-------------------------------------| +| Monday | Zoom | | +| Tuesday | Zoom | | +| Wednesday | Zoom | GitHub Issues and Pull Requests + Discuss and choose problems | +| Thursday | Zoom | | +| Friday | Zoom | | +| Saturday | Zoom | | +| Sunday | Zoom | | --- ## Communication Channels -All the technical disussions will be done on slack. But for general discussions we will use Whtsapp +All technical discussions will be conducted on Slack. General discussions will use WhatsApp. - **Issues**: Adding availability to the schedule - **Pull Requests**: Reviewing each other's code and giving feedback @@ -39,18 +40,18 @@ All the technical disussions will be done on slack. But for general discussions ### Availability for Calling/Messaging -| Day | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday | -|----------|:------:|:-------:|:---------:|:--------:|:------:|:--------:|:------:| -| **Madiha** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| **Fatima** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Day | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday | +|-----------|:------:|:-------:|:---------:|:--------:|:------:|:--------:|:------:| +| **Madiha** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| **Fatima** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -### How Many Hours Everyone Has Per Day +### Hours Available Per Day - Fatima: _5h_ -- Name: _6h_ - Madiha: _5h_ -- Name: _4h_ -- Name: _3h_ +- Member 1: _6h_ +- Member 2: _4h_ +- Member 3: _3h_ --- @@ -59,67 +60,76 @@ All the technical disussions will be done on slack. But for general discussions ### Previous Meetings #### Meeting 1 + - **Date:** 20-12-2024 - **Discussion Topics:** - - Introduction - - Team Norms - - Strategies for tackeling project + - Introduction + - Team Norms + - Strategies for tackling the project - **Decisions Made:** - - Decided 7 team norms. - - Study google documents. + - Decided on 7 team norms. + - Study Google Documents. #### Meeting 2 + - **Date:** 21-12-2024 - **Discussion Topics:** - - Finalising group norms. + - Finalizing group norms - Team name + - **Decisions Made:** - - Finalised 10 norms - - Git it Done- team name decided - - First commit made on github + - Finalized 10 norms. + - Decided on the team name: "Git it Done." + - First commit made on GitHub. #### Meeting 3 + - **Date:** 22-12-2024 - **Discussion Topics:** - - Discussion on assigned Google docs - - Guiding new members of team + - Discussion on assigned Google Docs + - Guiding new team members + - **Decisions Made:** - - Official work will be started from tomorrow. + - Official work to start tomorrow. #### Meeting 4 + - **Date:** 23-12-2024 - **Discussion Topics:** - - Pull requests - - Branches + - Pull requests + - Branches + - **Decisions Made:** - - Tasks assigned to each team member. - - Explore more about pull requests and branches - - Explore issues on github. + - Tasks assigned to each team member. + - Explore more about pull requests and branches. + - Explore issues on GitHub. --- ### Upcoming Meetings #### Meeting 5 -- **Date:** 25-12-2024 + +- **Date:** 25-12-2024 - **Discussion Topics:** - [Point 1] - [Point 2] + - **Decisions Made:** - [Decision 1] - [Decision 2] + - **Action Items:** - [Action 1] - [Action 2] +--- ## Asking for Help -There's a fine line between confidently learning from your mistakes, and -stubbornly getting nowhere. Here is a general guide for when to ask for help -based on how long you've been stuck on the same problem: +There's a fine line between confidently learning from your mistakes and stubbornly getting nowhere. Here is a general guide for when to ask for help based on how long you've been stuck on the same problem: -1. _0 -> 30 min_: Try on your own -1. _30 -> 60 min_: Ask your group for help -1. _60+ min_: Tag your coaches in Slack or GitHub +1. _0 -> 30 min_: Try on your own +2. _30 -> 60 min_: Ask your group for help +3. _60+ min_: Tag your coaches in Slack or GitHub From d4e85ff15e34c29d7f221be9ebda5f28f61c98ca Mon Sep 17 00:00:00 2001 From: Muhammad Shahroz <114472614+Shahroz657@users.noreply.github.com> Date: Fri, 27 Dec 2024 02:33:03 +0500 Subject: [PATCH 015/133] Update communication.md --- collaboration/communication.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collaboration/communication.md b/collaboration/communication.md index cd644f5c6..002ec9492 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -44,12 +44,13 @@ All technical discussions will be conducted on Slack. General discussions will u |-----------|:------:|:-------:|:---------:|:--------:|:------:|:--------:|:------:| | **Madiha** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | **Fatima** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| **Shahroz** | ✓ | ✓ | ✓ | ✓ | | | ✓ | ### Hours Available Per Day - Fatima: _5h_ - Madiha: _5h_ -- Member 1: _6h_ +- M Shahroz: _4h_ - Member 2: _4h_ - Member 3: _3h_ From c1692692db35792dbd4f422a654a9b3a3b317fc4 Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Sat, 28 Dec 2024 02:20:45 +0530 Subject: [PATCH 016/133] Fix CI errors by addressing linting and formatting issues --- collaboration/communication.md | 55 ++++++++++----------- collaboration/constraints.md | 89 +++++++++++++++++++++------------- 2 files changed, 82 insertions(+), 62 deletions(-) diff --git a/collaboration/communication.md b/collaboration/communication.md index 002ec9492..f03f5feaa 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -2,9 +2,9 @@ This template is for inspiration. Feel free to change it however you like! Careful! Be sure to protect your privacy when filling out this document. - Everything you write here will be public, - so share only what you are comfortable sharing online. - You can share the rest in confidence with your group by another channel. + Everything you write here will be public, so share only what you are + comfortable sharing online. You can share the rest in confidence with your + group by another channel. --> # Communication Plan @@ -13,21 +13,22 @@ This is the schedule for each week, and it will be updated weekly. -| Day | How | The topic of discussion | -|-----------|:----:|-------------------------------------| -| Monday | Zoom | | -| Tuesday | Zoom | | -| Wednesday | Zoom | GitHub Issues and Pull Requests + Discuss and choose problems | -| Thursday | Zoom | | -| Friday | Zoom | | -| Saturday | Zoom | | -| Sunday | Zoom | | +| Day | How | The topic of discussion | +|-----------|:----:|-------------------------------------------| +| Monday | Zoom | | +| Tuesday | Zoom | | +| Wednesday | Zoom | GitHub Issues and Pull Request Discussion | +| Thursday | Zoom | | +| Friday | Zoom | | +| Saturday | Zoom | | +| Sunday | Zoom | | --- ## Communication Channels -All technical discussions will be conducted on Slack. General discussions will use WhatsApp. +All technical discussions will be conducted on Slack. General discussions will +use WhatsApp. - **Issues**: Adding availability to the schedule - **Pull Requests**: Reviewing each other's code and giving feedback @@ -40,19 +41,19 @@ All technical discussions will be conducted on Slack. General discussions will u ### Availability for Calling/Messaging -| Day | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday | -|-----------|:------:|:-------:|:---------:|:--------:|:------:|:--------:|:------:| +| Day | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday | +|------------|:------:|:-------:|:---------:|:--------:|:------:|:--------:|:------:| | **Madiha** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | **Fatima** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| **Shahroz** | ✓ | ✓ | ✓ | ✓ | | | ✓ | +| **Shahroz**| ✓ | ✓ | ✓ | ✓ | | | ✓ | ### Hours Available Per Day -- Fatima: _5h_ -- Madiha: _5h_ -- M Shahroz: _4h_ -- Member 2: _4h_ -- Member 3: _3h_ +- **Fatima**: _5h_ +- **Madiha**: _5h_ +- **M Shahroz**: _4h_ +- **Member 2**: _4h_ +- **Member 3**: _3h_ --- @@ -67,7 +68,6 @@ All technical discussions will be conducted on Slack. General discussions will u - Introduction - Team Norms - Strategies for tackling the project - - **Decisions Made:** - Decided on 7 team norms. - Study Google Documents. @@ -78,7 +78,6 @@ All technical discussions will be conducted on Slack. General discussions will u - **Discussion Topics:** - Finalizing group norms - Team name - - **Decisions Made:** - Finalized 10 norms. - Decided on the team name: "Git it Done." @@ -90,7 +89,6 @@ All technical discussions will be conducted on Slack. General discussions will u - **Discussion Topics:** - Discussion on assigned Google Docs - Guiding new team members - - **Decisions Made:** - Official work to start tomorrow. @@ -100,7 +98,6 @@ All technical discussions will be conducted on Slack. General discussions will u - **Discussion Topics:** - Pull requests - Branches - - **Decisions Made:** - Tasks assigned to each team member. - Explore more about pull requests and branches. @@ -116,11 +113,9 @@ All technical discussions will be conducted on Slack. General discussions will u - **Discussion Topics:** - [Point 1] - [Point 2] - - **Decisions Made:** - [Decision 1] - [Decision 2] - - **Action Items:** - [Action 1] - [Action 2] @@ -129,8 +124,10 @@ All technical discussions will be conducted on Slack. General discussions will u ## Asking for Help -There's a fine line between confidently learning from your mistakes and stubbornly getting nowhere. Here is a general guide for when to ask for help based on how long you've been stuck on the same problem: +There's a fine line between confidently learning from your mistakes and +stubbornly getting nowhere. Here is a general guide for when to ask for help +based on how long you've been stuck on the same problem: 1. _0 -> 30 min_: Try on your own 2. _30 -> 60 min_: Ask your group for help -3. _60+ min_: Tag your coaches in Slack or GitHub +3. _60+ min_: Tag your coaches in Slack or GitHub diff --git a/collaboration/constraints.md b/collaboration/constraints.md index a6c028932..065e7b4a5 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -2,72 +2,95 @@ # Constraints -This section outlines the boundaries and considerations for our project to ensure smooth collaboration, efficient learning, and effective task completion. +This section outlines the boundaries and considerations for our project to ensure +smooth collaboration, efficient learning, and effective task completion. ## External Constraints **These factors outside our control influence how we work on this project.** + - **Platform Requirements:** - - Problems must be selected from the workshop's exercises, CodeWars, LeetCode, or similar coding platforms. - - Solutions must comply with the workshop's requirements (e.g., unittest, documentation, and clear variable name). -- **Deadlines:** - - Projects must be finished at the timeline set by the MIT Emerging Talent program. - - Each member must solve and review problems within the agreed-upon timeframes. -- **Tools and Resources:** - - GitHub must be used for version control, communication, and documentation. - - The team must rely on publicly available resources (e.g., online tutorials and documentation) to enhance learning. + - Problems must be selected from the workshop's exercises, CodeWars, LeetCode, + or similar coding platforms. + - Solutions must comply with the workshop's requirements (e.g., unittest, + documentation, and clear variable names). +- **Deadlines:** + - Projects must be completed within the timeline set by the MIT Emerging Talent + program. + - Each member must solve and review problems within the agreed-upon time frames. +- **Tools and Resources:** + - GitHub must be used for version control, communication, and documentation. + - The team must rely on publicly available resources (e.g., online tutorials + and documentation) to enhance learning. ## Internal Constraints: Involuntary -**These are limitations or challenges within the team that we need to navigate effectively.** - - **Experience Levels:** - - Team members have varying levels of experience in programming, unit testing, and documentation. - - Some members may require more time or support to complete tasks. + +**These are limitations or challenges within the team that we need to navigate +effectively.** + +- **Experience Levels:** + - Team members have varying levels of experience in programming, unit testing, + and documentation. + - Some members may require more time or support to complete tasks. + - **Availability:** - - Team members may have different schedules and commitments, limiting synchronous collaboration opportunities. -- Technical Skills: - - Limited familiarity with tools like Git, GitHub workflows, or unit testing frameworks. + - Team members may have different schedules and commitments, limiting + synchronous collaboration opportunities. +- **Technical Skills:** + - Limited familiarity with tools like Git, GitHub workflows, or unit testing + frameworks. ## Internal Constraints: Voluntary -These are self-imposed rules or boundaries designed to improve collaboration and learning outcomes. + +**These are self-imposed rules or boundaries designed to improve collaboration and +learning outcomes.** + - **Unit Testing:** - - All submitted solutions must include unit tests to verify correctness and edge cases. + - All submitted solutions must include unit tests to verify correctness and + edge cases. - Use Python’s unittest module (or equivalent) for testing. + - **Documentation Standards:** - All code must include meaningful comments explaining the logic. - Problem solutions must include documentation with: - Problem description. - Approach and thought process. - Test cases used. + - **Communication Protocols:** - Use GitHub Issues to discuss problems and tasks. - At least one other member must review pull requests before merging. - Constructive feedback is required for all reviews. + - **Collaborative Learning:** - - Each member must share insights or challenges they faced during problem-solving to help others learn. - - Regular check-ins (via GitHub comments or virtual meetings) to ensure alignment. + - Each member must share insights or challenges they faced during problem-solving + to help others learn. + - Regular check-ins (via GitHub comments or virtual meetings) to ensure + alignment. From 52e0b896c6dd5078ace54503889757018c4a7486 Mon Sep 17 00:00:00 2001 From: Muhammad Shahroz Date: Sat, 28 Dec 2024 04:56:48 +0500 Subject: [PATCH 017/133] Fixed mardown formatting issues --- collaboration/README.md | 48 +++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/collaboration/README.md b/collaboration/README.md index 6abd0d6ed..09a13cce6 100644 --- a/collaboration/README.md +++ b/collaboration/README.md @@ -3,48 +3,68 @@ ## Summary of Norms -Our goal is to create a collaborative environment where everyone feels comfortable asking questions and working together. We will start with the basics, progress toward project goals, and remain respectful, helpful, and connected throughout the journey. + +Our goal is to create a collaborative environment where everyone feels + comfortable asking questions and working together. We will start with the basics, + progress toward project goals, and remain respectful, helpful, and connected + throughout the journey. ### 1. Encourage Open and Respectful Communication + - Ensure all members feel heard and valued in discussions. -- Prioritize clear and constructive communication, encouraging everyone to share their ideas and perspectives without fear of judgment or interruption. +- Prioritize clear and constructive communication, encouraging everyone to share + their ideas and perspectives without fear of judgment or interruption. ### 2. Balance Discussion and Debate + - Promote productive collaboration through thoughtful discourse. -- Use discussions to generate ideas and debates to critically evaluate them while maintaining respect and focusing on project goals. +- Use discussions to generate ideas and debates to critically evaluate them while + maintaining respect and focusing on project goals. ### 3. Technical Meetings + - Use **Slack** for technical discussions and project updates. - Use **WhatsApp** for urgent matters and quick clarifications. ### 4. Reminders for Code Review -- To ensure timely code reviews, feel free to send a friendly reminder on Slack or WhatsApp when necessary. -- Encourage team members to notify the requester once the code review is completed. + +- To ensure timely code reviews, feel free to send a friendly reminder on Slack + or WhatsApp when necessary. +- Encourage team members to notify the requester once the code review is completed. ### 5. Handling Delays and Meeting Attendance -- Meetings will start as scheduled to respect everyone's time. -- If unable to attend, members should share their situation in advance and catch up via recordings. +- Meetings will start as scheduled to respect everyone's time. +- If unable to attend, members should share their situation in advance and catch + up via recordings. ### 6. Maintain a Positive Team Environment + - Avoid rude or mean behavior. -- If any interaction causes discomfort, address it respectfully to resolve the issue and foster understanding. +- If any interaction causes discomfort, address it respectfully to resolve the + issue and foster understanding. ### 7. Create a Safe Feedback Culture + - Encourage constructive feedback to improve team performance. - Focus on solutions rather than blame when giving or receiving feedback. ### 8. Clear Handoffs When Required -- If there are delays in completing tasks, inform the team promptly to prevent further delays. -- Minimize dependency issues by clearly communicating expectations and timelines when tasks require input or dependencies from another member. + +- If there are delays in completing tasks, inform the team promptly to prevent +further delays. +- Minimize dependency issues by clearly communicating expectations and timelines + when tasks require input or dependencies from another member. ### 9. Respect for Different Work Styles + - Foster individuality while ensuring progress. -- Respect that everyone has a unique working style, provided deliverables are submitted on time and meet agreed standards. +- Respect that everyone has a unique working style, provided deliverables are + submitted on time and meet agreed standards. ### 10. Responsiveness and Accountability -- While everyone has different schedules, acknowledging messages on Slack or WhatsApp—even with a brief reply—helps keep the team informed and connected. -- This ensures smooth collaboration and demonstrates respect for everyone’s efforts. - +- While everyone has different schedules, acknowledging messages on Slack or +WhatsApp—even with a brief reply—helps keep the team informed and connected. +- This ensures smooth collaboration and demonstrates respect for everyone’s efforts. From 11e3cb360532072f66583b5963e3dd3d17ff6663 Mon Sep 17 00:00:00 2001 From: Muhammad Shahroz Date: Sat, 28 Dec 2024 05:12:39 +0500 Subject: [PATCH 018/133] Upadated with markdown errors fixed --- .github/ISSUE_TEMPLATE/help_wanted.md | 2 +- .github/ISSUE_TEMPLATE/new_challenge.md | 3 ++- .github/PULL_REQUEST_TEMPLATE.md | 4 ++-- LICENSE | 2 +- README.md | 13 ++++++++++--- collaboration/communication.md | 6 ++++-- collaboration/guide/0_repository_setup.md | 3 ++- solutions/abcd.py | 2 -- 8 files changed, 22 insertions(+), 13 deletions(-) delete mode 100644 solutions/abcd.py diff --git a/.github/ISSUE_TEMPLATE/help_wanted.md b/.github/ISSUE_TEMPLATE/help_wanted.md index 2ee010f2e..134efead0 100644 --- a/.github/ISSUE_TEMPLATE/help_wanted.md +++ b/.github/ISSUE_TEMPLATE/help_wanted.md @@ -14,7 +14,7 @@ labels: "help wanted" - assign: anyone you would like help from --> -## The Code +# The Code diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 330a04cbc..7d9ab3bef 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -12,9 +12,9 @@ about: A template PR for code review with a checklist -## Behavior +# Behavior -### Files +## Files - [ ] The file name describes the function's behavior - [ ] There is a module docstring in the function file diff --git a/LICENSE b/LICENSE index 6e628e40e..d04b03511 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -MIT License +# MIT License Copyright (c) 2024 MIT Emerging Talent diff --git a/README.md b/README.md index 3807226f0..7be079914 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,19 @@ # Git it Done ## Overview + Welcome to the **Git it Done** repository! -This is a collaborative learning project where our team works together to solve problems and learn new skills. Each teammate will: +This is a collaborative learning project where our team works together to solve +problems and learn new skills. Each teammate will: + - Solve 2 problems. - Help resolve 2 problems contributed by others. -Our team is made up of people with different levels of experience—some of us are complete beginners, while others have a little experience. But one thing we all share is a strong eagerness to learn. By the end of this project, we will no longer be complete beginners. +Our team is made up of people with different levels of experience—some of us are +complete beginners, while others have a little experience. But one thing we all +share is a strong eagerness to learn. By the end of this project, we will no longer + be complete beginners. -We are learning collaboratively, growing through our mistakes, and working as a team to improve. . +We are learning collaboratively, growing through our mistakes, and working as a +team to improve. . diff --git a/collaboration/communication.md b/collaboration/communication.md index 60ab49de5..e98c57a90 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -33,9 +33,11 @@ ______________________________________________________________________ | Day | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday | | ------ | :----: | :-----: | :-------: | :------: | :----: | :------: | :----: | -**Madiha**| Monday ✓| Tuesday ✓| Wednesday ✓| Thursday ✓| Friday ✓| Saturday ✓| Sunday ✓| | +**Madiha**| Monday ✓| Tuesday ✓| Wednesday ✓| Thursday ✓ +| Friday ✓| Saturday ✓| Sunday ✓| | -**Shahroz**| Monday ✓| Tuesday ✓| Wednesday ✓| Thursday ✓| Sunday ✓| | +**Shahroz**| Monday ✓| Tuesday ✓| Wednesday ✓| Thursday ✓| +Sunday ✓| | ### How many hours everyone has per day diff --git a/collaboration/guide/0_repository_setup.md b/collaboration/guide/0_repository_setup.md index 4044fe979..4b968900a 100644 --- a/collaboration/guide/0_repository_setup.md +++ b/collaboration/guide/0_repository_setup.md @@ -14,7 +14,8 @@ repository and configure it for collaboration: - Change your [repository description](https://stackoverflow.com/questions/7757751/how-do-you-change-a-repository-description-on-github) - Add or remove topics from your repository - - Update your main README with your group name and an initial overview of your project. (You can change this as much as you want.) + - Update your main README with your group name and an initial overview of your + project. (You can change this as much as you want.) - Under settings in your repository select: - _Issues_ - _Discussions_ diff --git a/solutions/abcd.py b/solutions/abcd.py deleted file mode 100644 index 739dfd80f..000000000 --- a/solutions/abcd.py +++ /dev/null @@ -1,2 +0,0 @@ -# this is an example file -print("example") From c723797a478c961846d4318f9da9c3bc55fbf01e Mon Sep 17 00:00:00 2001 From: Muhammad Shahroz Date: Sat, 28 Dec 2024 05:21:07 +0500 Subject: [PATCH 019/133] Add placeholder test --- solutions/tests/test_placeholder.py | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 solutions/tests/test_placeholder.py diff --git a/solutions/tests/test_placeholder.py b/solutions/tests/test_placeholder.py new file mode 100644 index 000000000..7dca2c232 --- /dev/null +++ b/solutions/tests/test_placeholder.py @@ -0,0 +1,8 @@ +import unittest + +class PlaceholderTest(unittest.TestCase): + def test_placeholder(self): + self.assertTrue(True) + +if __name__ == "__main__": + unittest.main() From d86da5369d7dacc93cecdcd6e13e88c4701453b0 Mon Sep 17 00:00:00 2001 From: Muhammad Shahroz Date: Sat, 28 Dec 2024 05:33:15 +0500 Subject: [PATCH 020/133] Fixed formatting erorrs --- solutions/tests/test_placeholder.py | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 solutions/tests/test_placeholder.py diff --git a/solutions/tests/test_placeholder.py b/solutions/tests/test_placeholder.py deleted file mode 100644 index 7dca2c232..000000000 --- a/solutions/tests/test_placeholder.py +++ /dev/null @@ -1,8 +0,0 @@ -import unittest - -class PlaceholderTest(unittest.TestCase): - def test_placeholder(self): - self.assertTrue(True) - -if __name__ == "__main__": - unittest.main() From e3605faa56292d9d726888e07b2560ab40719954 Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Sat, 28 Dec 2024 22:42:17 +0500 Subject: [PATCH 021/133] Fixed some failing CI checks for #23 --- solutions/count_vowels.py | 36 +++++---- solutions/tests/test_count_vowels.py | 106 +++++++++++++-------------- 2 files changed, 71 insertions(+), 71 deletions(-) diff --git a/solutions/count_vowels.py b/solutions/count_vowels.py index 08f782d24..38800c45e 100644 --- a/solutions/count_vowels.py +++ b/solutions/count_vowels.py @@ -14,7 +14,7 @@ ''' def count_vowels(text: str) -> int: - """Count the number of vowels (A,E,I,O,U,a,e,i,o,u) in a string. + """Count the number of vowels (a,e,i,o,u) in a string. Parameters: text: str, the input string to check @@ -24,25 +24,29 @@ def count_vowels(text: str) -> int: Raises: AssertionError: if the argument is not a string - >>> count_vowels("FATIMA") - 3 - >>> count_vowels("Helloworld") - 3 - >>> count_vowels("Madiha") - 3 + >>> count_vowels("hello") + 2 + >>> count_vowels("APPLE") + 2 + >>> count_vowels("why") + 0 """ - assert isinstance(text, str), "input must be a string" - vowels = "aeiouAEIOU" - count = 0 - for letter in text: - if letter in vowels: - count += 1 - return count - + assert isinstance(text, str), "input must be a string" + vowels = "aeiouAEIOU" + count = 0 + for letter in text: + if letter in vowels: + count += 1 + return count +#call the function # print(count_vowels("hello")) - +# print(count_vowels("fly")) +# print(count_vowels("AEIOU")) +# print(count_vowels("")) +# print(count_vowels("high")) +# print(count_vowels("hellO World")) # if vowels== "": # return 0 diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index a7a5b2928..b4ad91df1 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -1,59 +1,55 @@ +"""Unit tests for the count_vowels function.""" + import unittest +from solutions.count_vowels import count_vowels + +class TestCountVowels(unittest.TestCase): + """Test cases for count_vowels function.""" + + def test_empty_string(self): + """It should return 0 for an empty string.""" + self.assertEqual(count_vowels(""), 0) + + def test_no_vowels(self): + """It should return 0 for a string with no vowels.""" + self.assertEqual(count_vowels("fly"), 0) + + def test_all_vowels(self): + """It should handle all uppercase and lowercase vowels.""" + self.assertEqual(count_vowels("aeiouAEIOU"), 10) + + def test_uppercase_vowels(self): + """It should count uppercase vowels in the string.""" + self.assertEqual(count_vowels("SMALL"), 1) + + def test_lowercase_vowels(self): + """It should count lowercase vowels in the string.""" + self.assertEqual(count_vowels("small"), 1) + + def test_mixed_case_vowels(self): + """It should count both uppercase and lowercase vowels in a string.""" + self.assertEqual(count_vowels("hellOWorld"), 3) + + def test_repeated_vowels(self): + """It should count all repeated vowels in a string.""" + self.assertEqual(count_vowels("aaeeiioouuAAEEIIOOUU"), 20) + + def test_alphanumeric_string(self): + """It should count vowels in alphanumeric strings, ignoring digits.""" + self.assertEqual(count_vowels("fatima123Malik"), 5) + + def test_special_characters(self): + """It should ignore special characters and only count vowels.""" + self.assertEqual(count_vowels("!@#$%^&*()aeiOu"), 5) + + def test_string_with_whitespace(self): + """It should count vowels even if the string contains spaces.""" + self.assertEqual(count_vowels("hello world"), 3) + + def test_invalid_input(self): + """Test that raises assertion error for non-string input.""" + with self.assertRaises(AssertionError): + count_vowels(None) -from ..count_vowels import count_vowels - -class Test_Count_Vowels(unittest.TestCase): - """ Test cases for count_vowels function""" - - def test_empty_string(self): - """It should return 0 for an empty string""" - self.assertEqual(count_vowels(""), 0) - - def test_no_vowels(self): - """It should return 0 for a string with no vowels""" - self.assertEqual(count_vowels("fly"), 0) - - def test_all_vowels(self): - """It should handle all uppercase and lowercase vowels""" - self.assertEqual(count_vowels("aeiouAEIOU"), 10) - - def test_uppercase_vowels(self): - """It should count uppercase vowels in the string""" - self.assertEqual(count_vowels("SMALL"), 1) - - def test_lowecase_vowels(self): - """It should count lowercase vowels in the string""" - self.assertEqual(count_vowels("small"), 1) - - def test_mixed_case_vowels(self): - """It should count both uppercase and lowecase vowels in a string""" - self.assertEqual(count_vowels("hellOWorld"), 3) - - def test_repeated_vowels(self): - """It should count all repeated vowels in a string.""" - self.assertEqual(count_vowels("aaeeiioouuAAEEIIOOUU"), 20) - - def test_alphanumeric_string(self): - """It should count vowels in alphanumeric strings, ignoring digits.""" - self.assertEqual(count_vowels("fatima123Malik"), 5) - - def test_special_characters(self): - """It should ignore special characters and only count vowels.""" - self.assertEqual(count_vowels("!@#$%^&*()aeiOu"), 5) - - def test_string_with_whitespace(self): - """It should count vowels even if the string contains spaces.""" - self.assertEqual(count_vowels("hello world"), 3) - - def test_invalid_input(self): - """ Test that raises assertion error for non-string input""" - with self.assertRaises(AssertionError): - count_vowels(None) - - # def test_not_string(self): - # """It should raise AssertionError for non-string input""" - # with self.assertRaises(AssertionError): - # count_vowels(123) - if __name__ == '__main__': unittest.main() From e77b0be5819baefdbf847ed135c4b4c52c381c7c Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Sat, 28 Dec 2024 23:36:46 +0500 Subject: [PATCH 022/133] fixed issues with linting rules of #23 --- solutions/tests/test_count_vowels.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index b4ad91df1..de3b1fa8a 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -1,4 +1,4 @@ -"""Unit tests for the count_vowels function.""" +"""Unit tests for the count_vowels function""" import unittest from solutions.count_vowels import count_vowels From 7314c01374acea91483d820a039072c46a251b00 Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Sun, 29 Dec 2024 11:23:40 +0500 Subject: [PATCH 023/133] Fixed Ruff formatting issues of #23 --- solutions/tests/test_count_vowels.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index de3b1fa8a..b4ad91df1 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -1,4 +1,4 @@ -"""Unit tests for the count_vowels function""" +"""Unit tests for the count_vowels function.""" import unittest from solutions.count_vowels import count_vowels From c256d4079152105df3a8d70399c6e7031ff1080b Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Sun, 29 Dec 2024 11:39:20 +0500 Subject: [PATCH 024/133] Fix Ruff formatting issues of #23 --- solutions/count_vowels.py | 31 ++++++++++++++-------------- solutions/tests/test_count_vowels.py | 4 +++- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/solutions/count_vowels.py b/solutions/count_vowels.py index 38800c45e..e12281c47 100644 --- a/solutions/count_vowels.py +++ b/solutions/count_vowels.py @@ -1,4 +1,4 @@ -''' +""" Write a function count_vowels(s) that returns the number of vowels in a given string. Examples @@ -11,19 +11,20 @@ Take a single string s as input. Identify and count the vowels (both uppercase and lowercase) in the string. Return the total count of vowels as an integer. -''' +""" + def count_vowels(text: str) -> int: """Count the number of vowels (a,e,i,o,u) in a string. - + Parameters: text: str, the input string to check - + Returns -> int: number of vowels in the text Raises: AssertionError: if the argument is not a string - + >>> count_vowels("hello") 2 >>> count_vowels("APPLE") @@ -40,7 +41,7 @@ def count_vowels(text: str) -> int: return count -#call the function +# call the function # print(count_vowels("hello")) # print(count_vowels("fly")) # print(count_vowels("AEIOU")) @@ -48,12 +49,12 @@ def count_vowels(text: str) -> int: # print(count_vowels("high")) # print(count_vowels("hellO World")) - # if vowels== "": - # return 0 - # if vowels== "aeiouAEIOU": - # return 5 - # if vowels== "fly": - # return 0 - # if vowels== "hellO World": - # return 3 - # return 0 +# if vowels== "": +# return 0 +# if vowels== "aeiouAEIOU": +# return 5 +# if vowels== "fly": +# return 0 +# if vowels== "hellO World": +# return 3 +# return 0 diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index b4ad91df1..404d33c6e 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -3,6 +3,7 @@ import unittest from solutions.count_vowels import count_vowels + class TestCountVowels(unittest.TestCase): """Test cases for count_vowels function.""" @@ -51,5 +52,6 @@ def test_invalid_input(self): with self.assertRaises(AssertionError): count_vowels(None) -if __name__ == '__main__': + +if __name__ == "__main__": unittest.main() From b157a1ea56f0754f225dc4abcd4d2b4051188723 Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Sun, 29 Dec 2024 23:55:48 +0500 Subject: [PATCH 025/133] Resolve communication.md errors for #36 --- collaboration/communication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collaboration/communication.md b/collaboration/communication.md index 14bfd81ea..d9e13ab3f 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -132,4 +132,4 @@ based on how long you've been stuck on the same problem: 1. _0 -> 30 min_: Try on your own 2. _30 -> 60 min_: Ask your group for help -3. _60+ min_: Tag your coaches in Slack or GitHub +3. _60+ min_: Tag your coaches in Slack or GitHub \ No newline at end of file From 72a104109d15228ef419021bed58922aa6957691 Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Mon, 30 Dec 2024 00:02:12 +0500 Subject: [PATCH 026/133] fix MD047 in communication.md --- collaboration/communication.md | 100 +++++++++++++++++++++++++-------- 1 file changed, 77 insertions(+), 23 deletions(-) diff --git a/collaboration/communication.md b/collaboration/communication.md index d9e13ab3f..ab099193f 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -13,15 +13,15 @@ This is the schedule for each week, and it will be updated weekly. -| Day | How | The topic of discussion | +| Day | How | The topic of discussion | |-----------|:----:|-------------------------------------------| -| Monday | Zoom | | -| Tuesday | Zoom | | +| Monday | Zoom | N/A | +| Tuesday | Zoom | N/A | | Wednesday | Zoom | GitHub Issues and Pull Request Discussion | -| Thursday | Zoom | | -| Friday | Zoom | | -| Saturday | Zoom | | -| Sunday | Zoom | | +| Thursday | Zoom | Discuss documentation and testing | +| Friday | Zoom | Continuous Integration (CI) Checks | +| Saturday | Zoom | No Meeting | +| Sunday | Zoom | Conflicts and CI checks discussion. | --- @@ -54,8 +54,8 @@ use WhatsApp. - **Fatima**: _5h_ - **Madiha**: _5h_ - **M Shahroz**: _4h_ -- **Member 2**: _4h_ -- **Member 3**: _3h_ +- **Member 4**: _4h_ +- **Member 5**: _3h_ --- @@ -105,22 +105,76 @@ use WhatsApp. - Explore more about pull requests and branches. - Explore issues on GitHub. ---- +#### Meeting 5 -### Upcoming Meetings + +- **Date:** 25-12-2024 +- **Time:** 10:00 PM PKT +- **Location:** Zoom + + +1. **Discuss GitHub Issues and Pull Requests** + - Topic: How and when to use GitHub Issues and Pull Requests (Important). + - Resource: Watch this [video](https://www.youtube.com/watch?v=TKJ4RdhyB5Y) + to learn about GitHub issues. + - Reference: [communication.md](https://github.com/MIT-Emerging-Talent/ET6-foundations-group-30/blob/main/collaboration/communication.md) + +2. **Discuss and Assign the Chosen Problems** + - Discuss and choose problems to work on. + - Assign specific problems to each team member. + +#### Meeting 6 + + +- **Date:** 25-12-2024 +- **Time:** 10:00 PM PKT +- **Location:** Zoom + + +1. **Discuss documentation and testing** + - Topic: Documentation and testing. + - Resource: Watch this [Repository to study](https://github.com/MIT-Emerging-Talent/ET6-Programming-With-Python/tree/main/3_documenting_and_testing) + +2. **Solve a Simple Problem** + - Collaboratively solve a simple problem. + - Discuss different approaches and finalize the solution. + +3. **Write Unit Tests** + - Write unit tests for the solved problem. + - Discuss the importance of unit testing and share best practices. + +4. **Write Documentation** + - Create documentation for the solved problem and its tests. + - Discuss the format and tools for writing clear and concise documentation. + +#### Meeting 7 + +- **Date:** 27-12-2024 +- **Time:** 10:00 PM PKT +- **Location:** Zoom + + +### 1. Continuous Integration (CI) Checks + +- **Discussion Points:** + - What is Continuous Integration (CI), and why is it important for the project? + - Benefits of CI: + - Early detection of issues. + - Maintaining code quality through automated checks. +- **Resource:** + [Watch this CI Overview Video](https://www.youtube.com/watch?v=mFFXuXjVgkU) + +### 2. Discuss the Issues + +- **Discussion Points:** + - Review the list of unresolved issues in the repository. + - Prioritize the most critical issues. + - Brainstorm solutions and assign responsibilities. + - Identify any additional tools or resources needed to resolve the issues. -#### Meeting 5 +--- -- **Date:** 25-12-2024 -- **Discussion Topics:** - - [Point 1] - - [Point 2] -- **Decisions Made:** - - [Decision 1] - - [Decision 2] - **Action Items:** - - [Action 1] - - [Action 2] +### Upcoming Meetings --- @@ -132,4 +186,4 @@ based on how long you've been stuck on the same problem: 1. _0 -> 30 min_: Try on your own 2. _30 -> 60 min_: Ask your group for help -3. _60+ min_: Tag your coaches in Slack or GitHub \ No newline at end of file +3. _60+ min_: Tag your coaches in Slack or GitHub. From 6992ecc711ea613b49dfa17d6cd69de20ef95f12 Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Mon, 30 Dec 2024 00:36:24 +0500 Subject: [PATCH 027/133] Fix formatting errors and add new constraints in constraints.md #36 --- collaboration/constraints.md | 143 +++++++++++++++-------------------- 1 file changed, 61 insertions(+), 82 deletions(-) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 065e7b4a5..67c413633 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -1,96 +1,75 @@ - - # Constraints -This section outlines the boundaries and considerations for our project to ensure -smooth collaboration, efficient learning, and effective task completion. - ## External Constraints - - **These factors outside our control influence how we work on this project.** -- **Platform Requirements:** - - Problems must be selected from the workshop's exercises, CodeWars, LeetCode, - or similar coding platforms. - - Solutions must comply with the workshop's requirements (e.g., unittest, - documentation, and clear variable names). - -- **Deadlines:** - - Projects must be completed within the timeline set by the MIT Emerging Talent - program. - - Each member must solve and review problems within the agreed-upon time frames. - -- **Tools and Resources:** - - GitHub must be used for version control, communication, and documentation. - - The team must rely on publicly available resources (e.g., online tutorials - and documentation) to enhance learning. - -## Internal Constraints: Involuntary +### Platform Requirements - +- Problems must be selected from the workshop's exercises, CodeWars, LeetCode, or +similar coding platforms. +- Solutions must comply with the workshop's requirements (e.g., unit tests, documentation, + and clear variable names). -**These are limitations or challenges within the team that we need to navigate -effectively.** +### Deadlines -- **Experience Levels:** - - Team members have varying levels of experience in programming, unit testing, - and documentation. - - Some members may require more time or support to complete tasks. +- Projects must be completed according to the timeline set by the +MIT Emerging Talent program. +- Each member must solve and review problems within the agreed-upon timeframes. -- **Availability:** - - Team members may have different schedules and commitments, limiting - synchronous collaboration opportunities. +### Tools and Resources -- **Technical Skills:** - - Limited familiarity with tools like Git, GitHub workflows, or unit testing - frameworks. +- GitHub must be used for version control, communication, and documentation. +- The team must rely on publicly available resources (e.g., online tutorials +and documentation) to enhance learning. ## Internal Constraints: Voluntary - - -**These are self-imposed rules or boundaries designed to improve collaboration and -learning outcomes.** - -- **Unit Testing:** - - All submitted solutions must include unit tests to verify correctness and - edge cases. - - Use Python’s unittest module (or equivalent) for testing. - -- **Documentation Standards:** - - All code must include meaningful comments explaining the logic. - - Problem solutions must include documentation with: - - Problem description. - - Approach and thought process. - - Test cases used. - -- **Communication Protocols:** - - Use GitHub Issues to discuss problems and tasks. - - At least one other member must review pull requests before merging. - - Constructive feedback is required for all reviews. - -- **Collaborative Learning:** - - Each member must share insights or challenges they faced during problem-solving - to help others learn. - - Regular check-ins (via GitHub comments or virtual meetings) to ensure - alignment. +These are self-imposed rules or boundaries designed to improve collaboration and +learning outcomes. + +### Documentation Standards + +- All code must include meaningful comments explaining the logic. +- Problem solutions must include documentation with: + - Problem description. + - Approach and thought process. + - Test cases used. + +### Communication Protocols + +- Use GitHub Issues to discuss problems and tasks. +- At least one other member must review pull requests before merging. +- Constructive feedback is required for all reviews. + +### Collaborative Learning + +- Each member must share insights or challenges they faced during problem-solving + to help others learn. +- Regular check-ins (via GitHub comments or virtual meetings) to ensure alignment. + +## New Internal Constraints: Voluntary + +These are new rules designed to improve the workflow and mitigate issues we've +encountered recently. + +### Pull Request and Branching Practices + +- **Pull Requests**: Each template file must be worked on in a separate branch and +added to the TODO list of the project board. +- **Branch Management**: When creating a new branch, ensure it is synchronized and +updated with the main branch using the following commands: + - `git fetch` to fetch updates. + - `git merge main` to merge the latest main branch changes into the current branch. +- **Selective `git add`**: Only add files on which changes have been made. +**Do not use `git add .`**. This ensures only relevant changes are committed. +- **Template File Changes**: For all template file modifications, work exclusively +in the `update_template_files` branch. +Create an issue for any changes you wish to make, and only submit a pull request +if you plan to merge the changes into the main file. +- **Branch Closure**: Once a new branch is created and used, the previous branches +will not be used further. Always start from the latest main branch or an appropriate +updated branch. +- **Pull Request Review**: Pull requests must be reviewed promptly upon submission +to avoid delays and conflicts. Reviews should be completed as soon as possible to +ensure efficient merging. From 246631d866665009d3a0ffd70935e197302a162f Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Mon, 30 Dec 2024 14:47:46 +0500 Subject: [PATCH 028/133] Fixed table format in communication.md --- collaboration/communication.md | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/collaboration/communication.md b/collaboration/communication.md index ab099193f..eb39aca4f 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -40,14 +40,12 @@ use WhatsApp. ## Availability ### Availability for Calling/Messaging - -| Day | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday| -|------------|:------:|:-------:|:---------:|:--------:|:------:|:--------:|:------:| -| **Madiha** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | - -| **Fatima** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | - -| **Shahroz**| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | + +| Day | Mon | Tue | Wed | Thu | Fri | Sat | Sun | +|------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:| +| **Madiha** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| **Fatima** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| **Shahroz**| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ### Hours Available Per Day @@ -164,13 +162,13 @@ use WhatsApp. - **Resource:** [Watch this CI Overview Video](https://www.youtube.com/watch?v=mFFXuXjVgkU) -### 2. Discuss the Issues +#### Meeting 8 + +- **Date:** 29-12-2024 +- **Time:** 08:00 PM PKT +- **Location:** Zoom -- **Discussion Points:** - - Review the list of unresolved issues in the repository. - - Prioritize the most critical issues. - - Brainstorm solutions and assign responsibilities. - - Identify any additional tools or resources needed to resolve the issues. + --- From d09edb3775b901ca4b07b9dde25be72c9d3b326a Mon Sep 17 00:00:00 2001 From: Muhammad Shahroz Date: Tue, 31 Dec 2024 03:55:06 +0500 Subject: [PATCH 029/133] Add solution and unit tests for Remove Duplicates from Sorted List --- .../remove_duplicates_from_sorted_list.py | 58 +++++++++++++++++++ ...test_remove_duplicates_from_sorted_list.py | 57 ++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 solutions/remove_duplicates_from_sorted_list.py create mode 100644 solutions/tests/test_remove_duplicates_from_sorted_list.py diff --git a/solutions/remove_duplicates_from_sorted_list.py b/solutions/remove_duplicates_from_sorted_list.py new file mode 100644 index 000000000..52518a0fa --- /dev/null +++ b/solutions/remove_duplicates_from_sorted_list.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Module: remove_duplicates_from_sorted_list +Description: This module provides a function to remove duplicates from a sorted linked list. +The function ensures each element appears only once while maintaining the sorted order. + +Created on: XX XX XX +@author: Your Name +""" + +from typing import Optional + + +class ListNode: + """A node in a singly linked list.""" + + def __init__(self, val=0, next_node=None): + self.val = val + self.next = next_node + + +def remove_duplicates(head: Optional[ListNode]) -> Optional[ListNode]: + """ + Removes duplicates from a sorted linked list. + + Parameters: + head (Optional[ListNode]): The head node of the sorted linked list. + + Returns: + Optional[ListNode]: The head node of the modified linked list with duplicates removed. + + Raises: + AssertionError: If the argument is not of type ListNode or None. + + Examples: + >>> head = ListNode(1, ListNode(1, ListNode(2))) + >>> result = remove_duplicates(head) + >>> result.val, result.next.val, result.next.next is None + (1, 2, True) + + >>> head = ListNode(1, ListNode(1, ListNode(2, ListNode(3, ListNode(3))))) + >>> result = remove_duplicates(head) + >>> result.val, result.next.val, result.next.next.val + (1, 2, 3) + """ + assert head is None or isinstance( + head, ListNode + ), "Input must be a ListNode or None." + + current = head + while current and current.next: + if current.val == current.next.val: + current.next = current.next.next + else: + current = current.next + + return head diff --git a/solutions/tests/test_remove_duplicates_from_sorted_list.py b/solutions/tests/test_remove_duplicates_from_sorted_list.py new file mode 100644 index 000000000..04de72e95 --- /dev/null +++ b/solutions/tests/test_remove_duplicates_from_sorted_list.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Test module for the remove_duplicates_from_sorted_list function. + +Created on: XX XX XX +@author: Your Name +""" + +import unittest +from ..remove_duplicates_from_sorted_list import ListNode, remove_duplicates + + + +class TestRemoveDuplicatesFromSortedList(unittest.TestCase): + """ + Unit tests for the remove_duplicates function. + Ensures that duplicates are removed from a sorted linked list. + """ + + def test_empty_list(self): + """It should evaluate None to None.""" + self.assertIsNone(remove_duplicates(None)) + + def test_single_node(self): + """It should evaluate a single-node list as unchanged.""" + head = ListNode(1) + result = remove_duplicates(head) + self.assertEqual(result.val, 1) + self.assertIsNone(result.next) + + def test_list_with_duplicates(self): + """It should remove duplicates from a sorted linked list.""" + head = ListNode(1, ListNode(1, ListNode(2, ListNode(3, ListNode(3))))) + result = remove_duplicates(head) + self.assertEqual(result.val, 1) + self.assertEqual(result.next.val, 2) + self.assertEqual(result.next.next.val, 3) + self.assertIsNone(result.next.next.next) + + def test_list_without_duplicates(self): + """It should evaluate a list with no duplicates as unchanged.""" + head = ListNode(1, ListNode(2, ListNode(3))) + result = remove_duplicates(head) + self.assertEqual(result.val, 1) + self.assertEqual(result.next.val, 2) + self.assertEqual(result.next.next.val, 3) + self.assertIsNone(result.next.next.next) + + def test_invalid_input(self): + """It should raise an assertion error for invalid input.""" + with self.assertRaises(AssertionError): + remove_duplicates("invalid_input") + + +if __name__ == "__main__": + unittest.main() From 00353e4a1bf2d2eb0b74066413924d2dacdceb04 Mon Sep 17 00:00:00 2001 From: Muhammad Shahroz Date: Tue, 31 Dec 2024 04:04:05 +0500 Subject: [PATCH 030/133] Fix formatting issues for solution and test files using Ruff and Black --- solutions/remove_duplicates_from_sorted_list.py | 4 ++-- solutions/tests/test_remove_duplicates_from_sorted_list.py | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/solutions/remove_duplicates_from_sorted_list.py b/solutions/remove_duplicates_from_sorted_list.py index 52518a0fa..fc2a685d1 100644 --- a/solutions/remove_duplicates_from_sorted_list.py +++ b/solutions/remove_duplicates_from_sorted_list.py @@ -5,8 +5,8 @@ Description: This module provides a function to remove duplicates from a sorted linked list. The function ensures each element appears only once while maintaining the sorted order. -Created on: XX XX XX -@author: Your Name +Created on: 31 12 24 +@author: Muhammad Shahroz """ from typing import Optional diff --git a/solutions/tests/test_remove_duplicates_from_sorted_list.py b/solutions/tests/test_remove_duplicates_from_sorted_list.py index 04de72e95..366440112 100644 --- a/solutions/tests/test_remove_duplicates_from_sorted_list.py +++ b/solutions/tests/test_remove_duplicates_from_sorted_list.py @@ -11,7 +11,6 @@ from ..remove_duplicates_from_sorted_list import ListNode, remove_duplicates - class TestRemoveDuplicatesFromSortedList(unittest.TestCase): """ Unit tests for the remove_duplicates function. From ca58382492bc95534ab73d0282ac9feb55584cf9 Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Tue, 31 Dec 2024 16:03:59 +0530 Subject: [PATCH 031/133] implemented function and unittest without docs --- solutions/remove_triplets.py | 22 +++++++++++++++++++++ solutions/tests/test_remove_triplets.py | 26 +++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 solutions/remove_triplets.py create mode 100644 solutions/tests/test_remove_triplets.py diff --git a/solutions/remove_triplets.py b/solutions/remove_triplets.py new file mode 100644 index 000000000..db45778d5 --- /dev/null +++ b/solutions/remove_triplets.py @@ -0,0 +1,22 @@ +def remove_triplets(text: str): + if text == "": + return "" + + prev = text[0] + frequency = 1 + + ans = text[0] + + for i in range(1, len(text)): + if text[i] == prev: + frequency += 1 + else: + prev = text[i] + frequency = 1 + if frequency < 3: + ans += text[i] + + return ans + + +print(remove_triplets("aaabbb")) diff --git a/solutions/tests/test_remove_triplets.py b/solutions/tests/test_remove_triplets.py new file mode 100644 index 000000000..d2583d7c0 --- /dev/null +++ b/solutions/tests/test_remove_triplets.py @@ -0,0 +1,26 @@ +import unittest + +from solutions.remove_triplets import remove_triplets + + +class test_remove_triplets(unittest.TestCase): + def test_empty_input(self): + """Test when input is empty""" + self.assertEqual(remove_triplets(""), "") + + def test_input_without_consecutive(self): + """Test input without consecutive characters""" + self.assertEqual(remove_triplets("abc"), "abc") + + def test_input_with_one_consecutive(self): + """Test input with one consecutive character""" + self.assertEqual(remove_triplets("helllo"), "hello") + self.assertEqual(remove_triplets("leeetcode"), "leetcode") + + def test_input_with_two_consecutive(self): + """Test input with two consecutive characters""" + self.assertEqual(remove_triplets("aaabaaaa"), "aabaa") + + +if __name__ == "__main__": + unittest.main() From 35b895230caba32cebd475b24b5ff50fbabb59e3 Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Tue, 31 Dec 2024 20:48:01 +0530 Subject: [PATCH 032/133] input vadition --- .vscode/settings.json | 4 ++-- solutions/remove_triplets.py | 7 +++++-- solutions/tests/test_remove_triplets.py | 5 +++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index bbda5188d..252022b48 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -119,8 +119,8 @@ "editor.defaultFormatter": "charliermarsh.ruff", "editor.formatOnSave": true, "editor.codeActionsOnSave": { - "source.fixAll.ruff": true, - "source.organizeImports.ruff": true + "source.fixAll.ruff": "explicit", + "source.organizeImports.ruff": "explicit" } } } diff --git a/solutions/remove_triplets.py b/solutions/remove_triplets.py index db45778d5..854a65011 100644 --- a/solutions/remove_triplets.py +++ b/solutions/remove_triplets.py @@ -1,10 +1,13 @@ def remove_triplets(text: str): + """Validate input type""" + assert isinstance(text, str), "Input must be a string type" + + """Handle empty input""" if text == "": return "" prev = text[0] frequency = 1 - ans = text[0] for i in range(1, len(text)): @@ -19,4 +22,4 @@ def remove_triplets(text: str): return ans -print(remove_triplets("aaabbb")) +print(remove_triplets("")) diff --git a/solutions/tests/test_remove_triplets.py b/solutions/tests/test_remove_triplets.py index d2583d7c0..9f0ed1c02 100644 --- a/solutions/tests/test_remove_triplets.py +++ b/solutions/tests/test_remove_triplets.py @@ -21,6 +21,11 @@ def test_input_with_two_consecutive(self): """Test input with two consecutive characters""" self.assertEqual(remove_triplets("aaabaaaa"), "aabaa") + def test_invalid_input_type(self): + """Test invalid input type""" + with self.assertRaises(AssertionError): + remove_triplets(123) # Passing an integer instead of a string + if __name__ == "__main__": unittest.main() From 4b704673c5e241c7a4f60240149e39d20b8d7402 Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Tue, 31 Dec 2024 21:30:51 +0530 Subject: [PATCH 033/133] this commit resove #31 --- solutions/remove_triplets.py | 31 +++++++++++++++++++++++-- solutions/tests/test_remove_triplets.py | 1 + 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/solutions/remove_triplets.py b/solutions/remove_triplets.py index 854a65011..509f906b2 100644 --- a/solutions/remove_triplets.py +++ b/solutions/remove_triplets.py @@ -1,8 +1,35 @@ def remove_triplets(text: str): - """Validate input type""" + """ + This function remove triplets from a string. A triplet is a sequence of 3 consecutive characters. + + Args: + text (str): The input string to process. It can be empty or contain any characters. + + Returns: + _type_: The processed string where no three consecutive characters are the same. + + Raises: + AssertionError: If input is not of type string. + + Example: + >>> remove_triplets("aaabaaaa") + "aabaa" + + >>> remove_triplets("helllo") + "hello" + + >>> remove_triplets("leeetcode") + "leetcode" + + edge case: + - If input is an empty string, return an empty string. + - If input has no three consecutive characters, return the input string. + - If the input contains higher than 3 consecutive characters, the function limits the repetitions to 2 chars + """ + # Validate input type assert isinstance(text, str), "Input must be a string type" - """Handle empty input""" + # Handle empty input if text == "": return "" diff --git a/solutions/tests/test_remove_triplets.py b/solutions/tests/test_remove_triplets.py index 9f0ed1c02..72341318b 100644 --- a/solutions/tests/test_remove_triplets.py +++ b/solutions/tests/test_remove_triplets.py @@ -3,6 +3,7 @@ from solutions.remove_triplets import remove_triplets +# Test cases for remove_triplets function class test_remove_triplets(unittest.TestCase): def test_empty_input(self): """Test when input is empty""" From 5c06cdf6d7d99e8e88b1bc025089bb709368971f Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Tue, 31 Dec 2024 21:39:00 +0530 Subject: [PATCH 034/133] this commit resove #31 --- .vscode/settings.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 252022b48..bbda5188d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -119,8 +119,8 @@ "editor.defaultFormatter": "charliermarsh.ruff", "editor.formatOnSave": true, "editor.codeActionsOnSave": { - "source.fixAll.ruff": "explicit", - "source.organizeImports.ruff": "explicit" + "source.fixAll.ruff": true, + "source.organizeImports.ruff": true } } } From 539e10c05f43ef700bd68c642a5ed9a0f78ade32 Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Wed, 1 Jan 2025 02:32:51 +0530 Subject: [PATCH 035/133] add more test cases to resolve #31 --- solutions/remove_triplets.py | 37 +++++++++++++------------ solutions/tests/test_remove_triplets.py | 21 ++++++++++++-- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/solutions/remove_triplets.py b/solutions/remove_triplets.py index 509f906b2..57a5f8f7d 100644 --- a/solutions/remove_triplets.py +++ b/solutions/remove_triplets.py @@ -1,30 +1,34 @@ -def remove_triplets(text: str): +def remove_triplets(text: str) -> str: """ - This function remove triplets from a string. A triplet is a sequence of 3 consecutive characters. + Removes triplets from string, a triplet is a sequence of three consecutive identical characters. + + This function processes the input string and ensures no three consecutive characters are the + same by removing the minimum number of characters required. Args: text (str): The input string to process. It can be empty or contain any characters. Returns: - _type_: The processed string where no three consecutive characters are the same. + str: The processed string where no three consecutive characters are the same. Raises: - AssertionError: If input is not of type string. + AssertionError: If the input is not of type string. - Example: - >>> remove_triplets("aaabaaaa") - "aabaa" + Examples: + >>> remove_triplets("aaabaaaa") + 'aabaa' - >>> remove_triplets("helllo") - "hello" + >>> remove_triplets("helllo") + 'hello' - >>> remove_triplets("leeetcode") - "leetcode" + >>> remove_triplets("leeetcode") + 'leetcode' - edge case: - - If input is an empty string, return an empty string. - - If input has no three consecutive characters, return the input string. - - If the input contains higher than 3 consecutive characters, the function limits the repetitions to 2 chars + Edge Cases: + - If the input is an empty string, return an empty string. + - If the input has no three consecutive characters, return the input string unchanged. + - If the input contains more than three consecutive identical + characters, the function limits the repetitions to two. """ # Validate input type assert isinstance(text, str), "Input must be a string type" @@ -47,6 +51,3 @@ def remove_triplets(text: str): ans += text[i] return ans - - -print(remove_triplets("")) diff --git a/solutions/tests/test_remove_triplets.py b/solutions/tests/test_remove_triplets.py index 72341318b..dec48400f 100644 --- a/solutions/tests/test_remove_triplets.py +++ b/solutions/tests/test_remove_triplets.py @@ -1,14 +1,27 @@ import unittest - from solutions.remove_triplets import remove_triplets # Test cases for remove_triplets function -class test_remove_triplets(unittest.TestCase): +class TestRemoveTriplets(unittest.TestCase): + """Unit tests for the remove_triplets function""" + def test_empty_input(self): """Test when input is empty""" self.assertEqual(remove_triplets(""), "") + def test_single_character_input(self): + """Test input with a single character""" + self.assertEqual(remove_triplets("a"), "a") + + def test_two_identical_characters(self): + """Test input with two identical characters""" + self.assertEqual(remove_triplets("aa"), "aa") + + def test_three_identical_characters(self): + """Test input with three identical characters""" + self.assertEqual(remove_triplets("aaa"), "aa") + def test_input_without_consecutive(self): """Test input without consecutive characters""" self.assertEqual(remove_triplets("abc"), "abc") @@ -22,6 +35,10 @@ def test_input_with_two_consecutive(self): """Test input with two consecutive characters""" self.assertEqual(remove_triplets("aaabaaaa"), "aabaa") + def test_mixed_triplets(self): + """Test input with multiple groups of triplets""" + self.assertEqual(remove_triplets("aaabbbcccaaa"), "aabbccaa") + def test_invalid_input_type(self): """Test invalid input type""" with self.assertRaises(AssertionError): From 5bc8fcd7bcf1ce0e6803334c2f8ada3cf9d9d52f Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Wed, 1 Jan 2025 02:40:02 +0530 Subject: [PATCH 036/133] add more test cases to resolve #31 --- solutions/tests/test_remove_triplets.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/solutions/tests/test_remove_triplets.py b/solutions/tests/test_remove_triplets.py index dec48400f..b872d81f8 100644 --- a/solutions/tests/test_remove_triplets.py +++ b/solutions/tests/test_remove_triplets.py @@ -4,7 +4,23 @@ # Test cases for remove_triplets function class TestRemoveTriplets(unittest.TestCase): - """Unit tests for the remove_triplets function""" + """ + Unit tests for the remove_triplets function. + + This module contains a set of test cases for the remove_triplets function + from the solutions package. The function ensures no three consecutive + characters remain in a string by removing the minimum number of characters + required. + + The tests cover various scenarios, including: + - Empty string input + - Strings without consecutive characters + - Strings with one or more groups of consecutive characters + - Boundary cases such as single characters or long sequences + - Defensive checks for invalid input types + + Test cases are implemented using Python's unittest framework. + """ def test_empty_input(self): """Test when input is empty""" From d298b4a8cec0b74760ee0447f97c8c4e8989e7c2 Mon Sep 17 00:00:00 2001 From: Muhammad Shahroz Date: Wed, 1 Jan 2025 03:31:37 +0500 Subject: [PATCH 037/133] Solution and unit test for filter_odd_numbers --- solutions/filter_odd_numbers.py | 41 ++++++++++++++++++++ solutions/tests/test_filter_odd_numbers.py | 45 ++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 solutions/filter_odd_numbers.py create mode 100644 solutions/tests/test_filter_odd_numbers.py diff --git a/solutions/filter_odd_numbers.py b/solutions/filter_odd_numbers.py new file mode 100644 index 000000000..30ccafd8a --- /dev/null +++ b/solutions/filter_odd_numbers.py @@ -0,0 +1,41 @@ +""" +Module: print_odd_numbers_in_list + +Description: This module provides a function to filter odd numbers from a given list. +The function handles various types of inputs, adheres to constraints, and returns a list +containing only odd integers. + +Created on: 01 01 25 +@author: Muhammad Shahroz +""" + +from typing import List, Union + + +def filter_odd_numbers(input_list: List[Union[int, float, str, None]]) -> List[int]: + """ + Filters and returns a list of odd integers from the given input list. + + Parameters: + input_list (List[Union[int, float, str, None]]): A list containing elements of various types. + + Returns: + List[int]: A list containing only the odd integers from the input. + + Raises: + AssertionError: If the input is not a list. + + Examples: + >>> filter_odd_numbers([1, 2, -3, 4.5, 5]) + [1, -3, 5] + + >>> filter_odd_numbers([1, 2, "three", 4.5, None]) + [1] + + >>> filter_odd_numbers([]) + [] + """ + assert isinstance(input_list, list), "Input must be a list." + + # Filter and return only odd integers + return [x for x in input_list if isinstance(x, int) and x % 2 != 0] diff --git a/solutions/tests/test_filter_odd_numbers.py b/solutions/tests/test_filter_odd_numbers.py new file mode 100644 index 000000000..42973af67 --- /dev/null +++ b/solutions/tests/test_filter_odd_numbers.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Test module for the print_odd_numbers_in_list function. + +Created on: 01 01 25 +@author: Muhammad Shahroz +""" + +import unittest +from ..filter_odd_numbers import filter_odd_numbers + + +class TestFilterOddNumbers(unittest.TestCase): + """ + Unit tests for the filter_odd_numbers function. + """ + + def test_empty_list(self): + """It should return an empty list for an empty input.""" + self.assertEqual(filter_odd_numbers([]), []) + + def test_all_integers(self): + """It should filter odd numbers from a list of integers.""" + self.assertEqual(filter_odd_numbers([1, 2, 3, 4, 5]), [1, 3, 5]) + + def test_negative_integers(self): + """It should handle negative integers correctly.""" + self.assertEqual(filter_odd_numbers([-1, -2, -3, -4, -5]), [-1, -3, -5]) + + def test_mixed_types(self): + """It should ignore non-integer inputs.""" + self.assertEqual(filter_odd_numbers([1, 2, "three", 4.5, None]), [1]) + + def test_all_floats(self): + """It should return an empty list if all elements are floats.""" + self.assertEqual(filter_odd_numbers([1.1, 2.2, 3.3]), []) + + def test_all_strings(self): + """It should return an empty list if all elements are strings.""" + self.assertEqual(filter_odd_numbers(["one", "two", "three"]), []) + + +if __name__ == "__main__": + unittest.main() From c2bfde577dd85e0573ace4d0738ad00e414b95f0 Mon Sep 17 00:00:00 2001 From: Muhammad Shahroz Date: Thu, 2 Jan 2025 01:23:17 +0500 Subject: [PATCH 038/133] Simplified the filter_odd_numbers function --- solutions/filter_odd_numbers.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/solutions/filter_odd_numbers.py b/solutions/filter_odd_numbers.py index 30ccafd8a..a00fd6196 100644 --- a/solutions/filter_odd_numbers.py +++ b/solutions/filter_odd_numbers.py @@ -35,7 +35,19 @@ def filter_odd_numbers(input_list: List[Union[int, float, str, None]]) -> List[i >>> filter_odd_numbers([]) [] """ + # Ensure the input is a list assert isinstance(input_list, list), "Input must be a list." - # Filter and return only odd integers - return [x for x in input_list if isinstance(x, int) and x % 2 != 0] + # Step 1: Filter only integers + integer_list = [] + for element in input_list: + if isinstance(element, int): + integer_list.append(element) + + # Step 2: Filter only odd numbers from the integers + odd_number_list = [] + for number in integer_list: + if number % 2 != 0: + odd_number_list.append(number) + + return odd_number_list From a71d720f25755e5c88d8ab245fcb4d1a1ed7062a Mon Sep 17 00:00:00 2001 From: jola-ds Date: Thu, 2 Jan 2025 10:16:02 +0100 Subject: [PATCH 039/133] Added Collective Learning Goals --- collaboration/learning_goals.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 11c583d2b..4e32d235b 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -2,4 +2,37 @@ ## Collective +1. **Cultivate Collaboration & Communication** + - Use GitHub tools (issues, pull requests, project boards) for structured teamwork. + - Write actionable, clear issues with helpful resources. + - Continuously update project board to reflect progress and support problem-solving. + - Develop and maintain a clear communication plan for effective collaboration. + - Use branches strategically to organize tasks and streamline development, + for smooth collaboration and progress. + +2. **Manage GitHub Workflows** + - Configure repositories, collaboration features, and best practices for team + workflows. + +3. **Nurture Team Synergy** + - Build cognitive and emotional trust, and repair trust when needed. + - Balance discussion and debate effectively. + - Prioritize idea generation and critical evaluation. + +4. **Enhance Tool Proficiency** + - Improve understanding of VSCode, CLI, Git, and GitHub for development, + debugging, and collaboration. + +5. **Improve Python Skills** + - Write clean, modular, and well-documented Python code, adhering to best practices. + - Debug and optimize code for efficiency. + - Write and implement relevant unit test cases using Python’s for + code reliability and maintenance + - Practice Test-Driven Development (TDD). + +6. **Improve Collaboration Through Feedback and Reflection** + - Focus on actionable and constructive feedback for team behaviour. + - Reflect on team experiences and iterate collaboration processes for + continuous improvement. + ## Individual From 106c0d886077c85520b48481b22ef0d3a37cdfcf Mon Sep 17 00:00:00 2001 From: jola-ds Date: Thu, 2 Jan 2025 14:00:37 +0100 Subject: [PATCH 040/133] added 'unittest' --- collaboration/learning_goals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 4e32d235b..03a0318b0 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -26,7 +26,7 @@ 5. **Improve Python Skills** - Write clean, modular, and well-documented Python code, adhering to best practices. - Debug and optimize code for efficiency. - - Write and implement relevant unit test cases using Python’s for + - Write and implement relevant unit test cases using Python’s unittest for code reliability and maintenance - Practice Test-Driven Development (TDD). From bf93229966d02e604f4e1bf11585fe7cad8fcc87 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Thu, 2 Jan 2025 14:09:17 +0100 Subject: [PATCH 041/133] added 'atomic commits' learning goal --- collaboration/learning_goals.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 03a0318b0..b86d3017a 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -22,6 +22,8 @@ 4. **Enhance Tool Proficiency** - Improve understanding of VSCode, CLI, Git, and GitHub for development, debugging, and collaboration. + - Practice making atomic, focused commits with clear commit messages + for better code history and easier code review. 5. **Improve Python Skills** - Write clean, modular, and well-documented Python code, adhering to best practices. From cc7b0104eb638a1df51af83038bbf8a0337475f9 Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Thu, 2 Jan 2025 21:05:00 +0530 Subject: [PATCH 042/133] added the date and author info to resolve #31 --- solutions/remove_triplets.py | 2 ++ solutions/tests/test_remove_triplets.py | 27 ++++++++++++++----------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/solutions/remove_triplets.py b/solutions/remove_triplets.py index 57a5f8f7d..3add32047 100644 --- a/solutions/remove_triplets.py +++ b/solutions/remove_triplets.py @@ -29,6 +29,8 @@ def remove_triplets(text: str) -> str: - If the input has no three consecutive characters, return the input string unchanged. - If the input contains more than three consecutive identical characters, the function limits the repetitions to two. + Created on: 02/01/25 + @author: Madiha Malikzada """ # Validate input type assert isinstance(text, str), "Input must be a string type" diff --git a/solutions/tests/test_remove_triplets.py b/solutions/tests/test_remove_triplets.py index b872d81f8..da4b9902a 100644 --- a/solutions/tests/test_remove_triplets.py +++ b/solutions/tests/test_remove_triplets.py @@ -5,21 +5,24 @@ # Test cases for remove_triplets function class TestRemoveTriplets(unittest.TestCase): """ - Unit tests for the remove_triplets function. + Unit tests for the remove_triplets function. - This module contains a set of test cases for the remove_triplets function - from the solutions package. The function ensures no three consecutive - characters remain in a string by removing the minimum number of characters - required. + This module contains a set of test cases for the remove_triplets function + from the solutions package. The function ensures no three consecutive + characters remain in a string by removing the minimum number of characters + required. - The tests cover various scenarios, including: - - Empty string input - - Strings without consecutive characters - - Strings with one or more groups of consecutive characters - - Boundary cases such as single characters or long sequences - - Defensive checks for invalid input types + The tests cover various scenarios, including: + - Empty string input + - Strings without consecutive characters + - Strings with one or more groups of consecutive characters + - Boundary cases such as single characters or long sequences + - Defensive checks for invalid input types - Test cases are implemented using Python's unittest framework. + Test cases are implemented using Python's unittest framework. + + Created on: 02/01/25 + @author: Madiha Malikzada """ def test_empty_input(self): From 69f22324fd6c04f42cf7759c86132d8c4ac08319 Mon Sep 17 00:00:00 2001 From: Muhammad Shahroz Date: Fri, 3 Jan 2025 02:14:53 +0500 Subject: [PATCH 043/133] Refactored tests and added improvements for remove_duplicates function. Resolves issue #9 --- ...test_remove_duplicates_from_sorted_list.py | 52 +++++++++++++++---- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/solutions/tests/test_remove_duplicates_from_sorted_list.py b/solutions/tests/test_remove_duplicates_from_sorted_list.py index 366440112..51eaa21c5 100644 --- a/solutions/tests/test_remove_duplicates_from_sorted_list.py +++ b/solutions/tests/test_remove_duplicates_from_sorted_list.py @@ -3,8 +3,8 @@ """ Test module for the remove_duplicates_from_sorted_list function. -Created on: XX XX XX -@author: Your Name +Created on: 31 12 24 +@author: Muhammad Shahroz """ import unittest @@ -19,31 +19,61 @@ class TestRemoveDuplicatesFromSortedList(unittest.TestCase): def test_empty_list(self): """It should evaluate None to None.""" - self.assertIsNone(remove_duplicates(None)) + result = remove_duplicates(None) + self.assertIsNone(result) - def test_single_node(self): - """It should evaluate a single-node list as unchanged.""" + def test_single_node_value(self): + """It should evaluate the value of a single-node list.""" head = ListNode(1) result = remove_duplicates(head) self.assertEqual(result.val, 1) + + def test_single_node_next(self): + """It should evaluate the next node of a single-node list as None.""" + head = ListNode(1) + result = remove_duplicates(head) self.assertIsNone(result.next) - def test_list_with_duplicates(self): - """It should remove duplicates from a sorted linked list.""" - head = ListNode(1, ListNode(1, ListNode(2, ListNode(3, ListNode(3))))) + def test_duplicate_first_node(self): + """It should remove duplicates at the first node.""" + head = ListNode(1, ListNode(1, ListNode(2))) result = remove_duplicates(head) self.assertEqual(result.val, 1) + + def test_duplicate_second_node(self): + """It should remove duplicates at the second node.""" + head = ListNode(1, ListNode(1, ListNode(2))) + result = remove_duplicates(head) self.assertEqual(result.next.val, 2) - self.assertEqual(result.next.next.val, 3) + + def test_duplicate_list_ends(self): + """It should evaluate the end of a list with duplicates as None.""" + head = ListNode(1, ListNode(1, ListNode(2, ListNode(3, ListNode(3))))) + result = remove_duplicates(head) self.assertIsNone(result.next.next.next) - def test_list_without_duplicates(self): - """It should evaluate a list with no duplicates as unchanged.""" + def test_list_without_duplicates_first_node(self): + """It should evaluate the first node of a list without duplicates.""" head = ListNode(1, ListNode(2, ListNode(3))) result = remove_duplicates(head) self.assertEqual(result.val, 1) + + def test_list_without_duplicates_second_node(self): + """It should evaluate the second node of a list without duplicates.""" + head = ListNode(1, ListNode(2, ListNode(3))) + result = remove_duplicates(head) self.assertEqual(result.next.val, 2) + + def test_list_without_duplicates_third_node(self): + """It should evaluate the third node of a list without duplicates.""" + head = ListNode(1, ListNode(2, ListNode(3))) + result = remove_duplicates(head) self.assertEqual(result.next.next.val, 3) + + def test_list_without_duplicates_end(self): + """It should evaluate the end of a list without duplicates as None.""" + head = ListNode(1, ListNode(2, ListNode(3))) + result = remove_duplicates(head) self.assertIsNone(result.next.next.next) def test_invalid_input(self): From 18da0da664f484d38f86a4972239c5916b14f7e0 Mon Sep 17 00:00:00 2001 From: Mojtaba Fayyaz Date: Fri, 3 Jan 2025 15:11:29 +0500 Subject: [PATCH 044/133] Restore remove_every_other.py and test_remove_every_other.py --- solutions/remove_every_other.py | 44 +++++++++++++++++++ solutions/tests/test_remove_every_other.py | 51 ++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 solutions/remove_every_other.py create mode 100644 solutions/tests/test_remove_every_other.py diff --git a/solutions/remove_every_other.py b/solutions/remove_every_other.py new file mode 100644 index 000000000..9d1064ffa --- /dev/null +++ b/solutions/remove_every_other.py @@ -0,0 +1,44 @@ +# remove_every_other.py + +""" +Module: remove_every_other +Author: Mojtaba Fayyaz +Date: 2024-12-29 + +This module provides a utility function to remove every second element from a list. +""" + + +def remove_every_other(arr: list) -> list: + """ + Removes every second element from the input list. + + Parameters: + arr (list): A list of elements from which every second element will be removed. + + Returns: + list: A new list containing only every other element starting with the first. + + Assumptions: + - The input is always a non-empty list. + + Doctests: + >>> remove_every_other(["Keep", "Remove", "Keep", "Remove", "Keep"]) + ['Keep', 'Keep', 'Keep'] + + >>> remove_every_other([1, 2, 3, 4, 5]) + [1, 3, 5] + + >>> remove_every_other(["A"]) + ['A'] + + Example: + arr = ["Apple", "Banana", "Cherry"] + print(remove_every_other(arr)) + # Output: ['Apple', 'Cherry'] + + Defensive Assertions: + - Ensures the input is a list. + """ + assert isinstance(arr, list), "Input must be a list" + return arr[::2] diff --git a/solutions/tests/test_remove_every_other.py b/solutions/tests/test_remove_every_other.py new file mode 100644 index 000000000..787e3f885 --- /dev/null +++ b/solutions/tests/test_remove_every_other.py @@ -0,0 +1,51 @@ +# tests/test_remove_every_other.py + +""" +Tests for the remove_every_other function. +""" +import unittest +from solutions.remove_every_other import remove_every_other # Updated import + + +class TestRemoveEveryOther(unittest.TestCase): + """ + Unit tests for remove_every_other function. + """ + + def test_removes_every_second_element(self): + """ + Test that it correctly removes every second element. + """ + self.assertEqual( + remove_every_other(["Keep", "Remove", "Keep", "Remove", "Keep"]), + ["Keep", "Keep", "Keep"], + ) + + def test_single_element_list(self): + """ + Test that a single-element list remains unchanged. + """ + self.assertEqual(remove_every_other(["OnlyOne"]), ["OnlyOne"]) + + def test_mixed_type_list(self): + """ + Test that it works with mixed-type lists. + """ + self.assertEqual(remove_every_other([1, "Two", 3, "Four", 5]), [1, 3, 5]) + + def test_large_list(self): + """ + Test with a large list. + """ + self.assertEqual(remove_every_other(list(range(10))), [0, 2, 4, 6, 8]) + + def test_defensive_assertion(self): + """ + Test that the function raises an assertion error for invalid input. + """ + with self.assertRaises(AssertionError): + remove_every_other("Not a list") + + +if __name__ == "__main__": + unittest.main() From 2d6aaa0e92124ad6f1d5a8e5d0e25749d4485951 Mon Sep 17 00:00:00 2001 From: Mojtaba Fayyaz Date: Fri, 3 Jan 2025 17:30:25 +0500 Subject: [PATCH 045/133] Formatted test_remove_every_other.py with Black --- solutions/tests/test_remove_every_other.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solutions/tests/test_remove_every_other.py b/solutions/tests/test_remove_every_other.py index 787e3f885..283374ed6 100644 --- a/solutions/tests/test_remove_every_other.py +++ b/solutions/tests/test_remove_every_other.py @@ -3,7 +3,9 @@ """ Tests for the remove_every_other function. """ + import unittest + from solutions.remove_every_other import remove_every_other # Updated import From 7ef6b9f82779e1fcbc753b7b5caa5901d185bc20 Mon Sep 17 00:00:00 2001 From: Mojtaba Fayyaz Date: Fri, 3 Jan 2025 17:40:08 +0500 Subject: [PATCH 046/133] Added test cases for empty list and list with duplicates --- solutions/tests/test_remove_every_other.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/solutions/tests/test_remove_every_other.py b/solutions/tests/test_remove_every_other.py index 283374ed6..b8deca551 100644 --- a/solutions/tests/test_remove_every_other.py +++ b/solutions/tests/test_remove_every_other.py @@ -1,9 +1,3 @@ -# tests/test_remove_every_other.py - -""" -Tests for the remove_every_other function. -""" - import unittest from solutions.remove_every_other import remove_every_other # Updated import @@ -48,6 +42,20 @@ def test_defensive_assertion(self): with self.assertRaises(AssertionError): remove_every_other("Not a list") + # New test case for empty list + def test_empty_list(self): + """ + Test that an empty list returns an empty list. + """ + self.assertEqual(remove_every_other([]), []) + + # New test case for list with duplicates + def test_list_with_duplicates(self): + """ + Test that the function handles duplicate values correctly. + """ + self.assertEqual(remove_every_other([1, 2, 2, 3, 3, 4]), [1, 2, 3, 4]) + if __name__ == "__main__": unittest.main() From 74aa35f7cf29263ca92913d4d15da34e41843130 Mon Sep 17 00:00:00 2001 From: Mojtaba Fayyaz Date: Fri, 3 Jan 2025 17:46:47 +0500 Subject: [PATCH 047/133] Updated test case for handling duplicates in remove_every_other function --- solutions/tests/test_remove_every_other.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solutions/tests/test_remove_every_other.py b/solutions/tests/test_remove_every_other.py index b8deca551..ad71018aa 100644 --- a/solutions/tests/test_remove_every_other.py +++ b/solutions/tests/test_remove_every_other.py @@ -49,12 +49,12 @@ def test_empty_list(self): """ self.assertEqual(remove_every_other([]), []) - # New test case for list with duplicates + # Updated test case for list with duplicates def test_list_with_duplicates(self): """ Test that the function handles duplicate values correctly. """ - self.assertEqual(remove_every_other([1, 2, 2, 3, 3, 4]), [1, 2, 3, 4]) + self.assertEqual(remove_every_other([1, 2, 2, 3, 3, 4]), [1, 2, 3]) if __name__ == "__main__": From 20355fa59917105729726c436b6a421a0d927ea4 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 14:56:35 +0100 Subject: [PATCH 048/133] created length_longest_substring.py --- solutions/length_longest_substring.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/length_longest_substring.py diff --git a/solutions/length_longest_substring.py b/solutions/length_longest_substring.py new file mode 100644 index 000000000..e69de29bb From acfb8b07fef4ecd9060811b865270acb07b56212 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 15:03:42 +0100 Subject: [PATCH 049/133] Added module docstring --- solutions/length_longest_substring.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/solutions/length_longest_substring.py b/solutions/length_longest_substring.py index e69de29bb..d157ff22d 100644 --- a/solutions/length_longest_substring.py +++ b/solutions/length_longest_substring.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +A module to find the length of the longest substring in a given string without repeating characters. + +Module Contents: + + - length_longest_substring(s: str) -> int: + Finds the length of the longest substring without repeating characters. + +Created on: 2025-01-03 +Author: Jola-Moses +""" \ No newline at end of file From 3ce001f28b74769096d357193037af40ad405d72 Mon Sep 17 00:00:00 2001 From: Mojtaba Fayyaz Date: Fri, 3 Jan 2025 19:47:27 +0500 Subject: [PATCH 050/133] Add reverse_string.py & test_reverse_string.py --- solutions/reverse_string.py | 55 ++++++++++++++++++++++ solutions/tests/test_reverse_string.py | 64 ++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 solutions/reverse_string.py create mode 100644 solutions/tests/test_reverse_string.py diff --git a/solutions/reverse_string.py b/solutions/reverse_string.py new file mode 100644 index 000000000..4341ef240 --- /dev/null +++ b/solutions/reverse_string.py @@ -0,0 +1,55 @@ +""" +Module: reverse_string +Author: Mojtaba Fayyaz +Date: 2024-01-02 + +This module provides a utility function to reverse an array of characters in-place. +""" + + +def reverse_string(s: list) -> None: + """ + Reverses the input array of characters in-place. + + Parameters: + s (list): A list of characters to be reversed. + + Returns: + None: The input list is modified in-place. + + Assumptions: + - The input is always a list of characters. + + Doctests: + >>> s = ['h', 'e', 'l', 'l', 'o'] + >>> reverse_string(s) + >>> s + ['o', 'l', 'l', 'e', 'h'] + + >>> s = ['H', 'a', 'n', 'n', 'a', 'h'] + >>> reverse_string(s) + >>> s + ['h', 'a', 'n', 'n', 'a', 'H'] + + >>> s = ['A'] + >>> reverse_string(s) + >>> s + ['A'] + + Example: + s = ['c', 'a', 't'] + reverse_string(s) + print(s) + # Output: ['t', 'a', 'c'] + + Defensive Assertions: + - Ensures the input is a list. + """ + assert isinstance(s, list), "Input must be a list" + left, right = 0, len(s) - 1 + + while left < right: + # Swap the characters at the left and right indices + s[left], s[right] = s[right], s[left] + left += 1 + right -= 1 diff --git a/solutions/tests/test_reverse_string.py b/solutions/tests/test_reverse_string.py new file mode 100644 index 000000000..70657a9f3 --- /dev/null +++ b/solutions/tests/test_reverse_string.py @@ -0,0 +1,64 @@ +""" +Tests for the reverse_string function. +""" + +import unittest + +from solutions.reverse_string import reverse_string + + +class TestReverseString(unittest.TestCase): + """ + Unit tests for the reverse_string function. + """ + + def test_reverse_simple_string(self): + """ + Test that it correctly reverses a simple string. + """ + s = ["h", "e", "l", "l", "o"] + reverse_string(s) + self.assertEqual(s, ["o", "l", "l", "e", "h"]) + + def test_reverse_palindrome(self): + """ + Test that a palindrome remains unchanged after reversal. + """ + s = ["m", "a", "d", "a", "m"] + reverse_string(s) + self.assertEqual(s, ["m", "a", "d", "a", "m"]) + + def test_single_character_string(self): + """ + Test that a single-character string remains unchanged. + """ + s = ["A"] + reverse_string(s) + self.assertEqual(s, ["A"]) + + def test_empty_string(self): + """ + Test that an empty list remains unchanged. + """ + s = [] + reverse_string(s) + self.assertEqual(s, []) + + def test_mixed_characters_string(self): + """ + Test that it correctly reverses a string with mixed characters. + """ + s = ["1", "2", "!", "@", "a", "b"] + reverse_string(s) + self.assertEqual(s, ["b", "a", "@", "!", "2", "1"]) + + def test_defensive_assertion(self): + """ + Test that the function raises an assertion error for invalid input. + """ + with self.assertRaises(AssertionError): + reverse_string("Not a list") + + +if __name__ == "__main__": + unittest.main() From 08ea6f372d00d9ac6660ab89ebf9dc0dc2b8df12 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 15:50:59 +0100 Subject: [PATCH 051/133] created function --- solutions/length_longest_substring.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/solutions/length_longest_substring.py b/solutions/length_longest_substring.py index d157ff22d..695d7b853 100644 --- a/solutions/length_longest_substring.py +++ b/solutions/length_longest_substring.py @@ -11,4 +11,5 @@ Created on: 2025-01-03 Author: Jola-Moses -""" \ No newline at end of file +""" +def length_longest_substring(s: str) -> int: \ No newline at end of file From 759f41c97bc862d93fb99665249a753a9b67d48c Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 16:02:36 +0100 Subject: [PATCH 052/133] added function docstring and doctests --- solutions/length_longest_substring.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/solutions/length_longest_substring.py b/solutions/length_longest_substring.py index 695d7b853..e40da45e5 100644 --- a/solutions/length_longest_substring.py +++ b/solutions/length_longest_substring.py @@ -12,4 +12,24 @@ Created on: 2025-01-03 Author: Jola-Moses """ -def length_longest_substring(s: str) -> int: \ No newline at end of file +def length_longest_substring(s: str) -> int: + """ + Returns the length of the longest substring without repeating characters. + + Parameters: + s: str, the input string for which to find the longest substring + + Returns -> int, the length of the longest substring without repeating characters + + Raises: + AssertionError: if s is not a string + + >>> length_longest_substring("abcabcbb") + 3 + + >>> length_longest_substring("abcdef") + 6 + + >>> length_longest_substring("aaaaaa") + 1 + """ From bc1691eaccb8d69b38f4f15ae575a4f394810b34 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 16:04:49 +0100 Subject: [PATCH 053/133] created test_length_longest_substring.py --- solutions/tests/test_length_longest_substring.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/tests/test_length_longest_substring.py diff --git a/solutions/tests/test_length_longest_substring.py b/solutions/tests/test_length_longest_substring.py new file mode 100644 index 000000000..e69de29bb From 0c6c231b60803d439e5ebbcc010b7d8f7c8921eb Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 16:12:15 +0100 Subject: [PATCH 054/133] added test module --- .../tests/test_length_longest_substring.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/solutions/tests/test_length_longest_substring.py b/solutions/tests/test_length_longest_substring.py index e69de29bb..3e65d0ed1 100644 --- a/solutions/tests/test_length_longest_substring.py +++ b/solutions/tests/test_length_longest_substring.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +This module contains unit tests to validate the functionality of the +`length_longest_substring` function. +It checks the length of the longest substring without repeating characters in a string. + +Created on: 2025-01-03 +Author: Jola-Moses +""" + +import unittest +from solutions.length_longest_substring import length_longest_substring + +class TestLengthLongestSubstring(unittest.TestCase): + """Tests for length_longest_substring""" \ No newline at end of file From 8f1f4627cf505c5cedd78fd90fd7fd103145727a Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 16:20:16 +0100 Subject: [PATCH 055/133] fail-first test --- solutions/tests/test_length_longest_substring.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/solutions/tests/test_length_longest_substring.py b/solutions/tests/test_length_longest_substring.py index 3e65d0ed1..22c451871 100644 --- a/solutions/tests/test_length_longest_substring.py +++ b/solutions/tests/test_length_longest_substring.py @@ -14,4 +14,8 @@ from solutions.length_longest_substring import length_longest_substring class TestLengthLongestSubstring(unittest.TestCase): - """Tests for length_longest_substring""" \ No newline at end of file + """Tests for length_longest_substring""" + + def test_basic_case(self): + """Should return 3 for 'abcabcbb'.""" + self.assertEqual(length_longest_substring('abcabcbb'), 3) From 60e5052fd38980b40772993212e6100e4f43796d Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 16:40:06 +0100 Subject: [PATCH 056/133] Initialise variables to track the longest substring and the current substring --- solutions/length_longest_substring.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/solutions/length_longest_substring.py b/solutions/length_longest_substring.py index e40da45e5..2359612a9 100644 --- a/solutions/length_longest_substring.py +++ b/solutions/length_longest_substring.py @@ -33,3 +33,6 @@ def length_longest_substring(s: str) -> int: >>> length_longest_substring("aaaaaa") 1 """ + + longest = 0 + current = "" From db8eae0087361cdd54ed3127f6252a80e221ac35 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 17:04:20 +0100 Subject: [PATCH 057/133] Add a loop to iterate through characters in the input string. --- solutions/length_longest_substring.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/solutions/length_longest_substring.py b/solutions/length_longest_substring.py index 2359612a9..0d96e5a22 100644 --- a/solutions/length_longest_substring.py +++ b/solutions/length_longest_substring.py @@ -34,5 +34,13 @@ def length_longest_substring(s: str) -> int: 1 """ + # Track the length of the longest substring without repeating characters longest = 0 + + # Store the substring being evaluated current = "" + + # Iterate through each character to find substrings + for char in s: + if char in current: + pass From 04e292db305964db7f436bed6a9b4cb53b559c36 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 17:07:58 +0100 Subject: [PATCH 058/133] Remove characters from the current substring until the repeating character is gone. --- solutions/length_longest_substring.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/solutions/length_longest_substring.py b/solutions/length_longest_substring.py index 0d96e5a22..c58474053 100644 --- a/solutions/length_longest_substring.py +++ b/solutions/length_longest_substring.py @@ -43,4 +43,6 @@ def length_longest_substring(s: str) -> int: # Iterate through each character to find substrings for char in s: if char in current: - pass + # Remove characters until the repeating one is eliminated + while char in current: + current = current[1:] From 990bf6000b0181bd3719e826a15d396c1396eca4 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 17:11:20 +0100 Subject: [PATCH 059/133] Add the current character to the substring. --- solutions/length_longest_substring.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solutions/length_longest_substring.py b/solutions/length_longest_substring.py index c58474053..cd6326698 100644 --- a/solutions/length_longest_substring.py +++ b/solutions/length_longest_substring.py @@ -46,3 +46,5 @@ def length_longest_substring(s: str) -> int: # Remove characters until the repeating one is eliminated while char in current: current = current[1:] + + current += char # Expand the substring with the current character From f7183652eee7f0b1d1439588880306954a5cc8b9 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 17:13:19 +0100 Subject: [PATCH 060/133] Update the longest substring length based on the current substring. --- solutions/length_longest_substring.py | 1 + 1 file changed, 1 insertion(+) diff --git a/solutions/length_longest_substring.py b/solutions/length_longest_substring.py index cd6326698..f05021300 100644 --- a/solutions/length_longest_substring.py +++ b/solutions/length_longest_substring.py @@ -48,3 +48,4 @@ def length_longest_substring(s: str) -> int: current = current[1:] current += char # Expand the substring with the current character + longest = max(longest, len(current)) # Update longest if needed From b39ff53d76e3e48efdf35bcc615d491dd253b514 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 17:16:13 +0100 Subject: [PATCH 061/133] Return the length of the longest substring. --- solutions/length_longest_substring.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solutions/length_longest_substring.py b/solutions/length_longest_substring.py index f05021300..d38211c23 100644 --- a/solutions/length_longest_substring.py +++ b/solutions/length_longest_substring.py @@ -49,3 +49,5 @@ def length_longest_substring(s: str) -> int: current += char # Expand the substring with the current character longest = max(longest, len(current)) # Update longest if needed + + return longest From eb357e4b1b5ed5070ac36a3f70a7f0292321aec0 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 17:23:54 +0100 Subject: [PATCH 062/133] fix bug: ensure substring and length updates occur within for loop --- solutions/length_longest_substring.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solutions/length_longest_substring.py b/solutions/length_longest_substring.py index d38211c23..020d3ed98 100644 --- a/solutions/length_longest_substring.py +++ b/solutions/length_longest_substring.py @@ -47,7 +47,7 @@ def length_longest_substring(s: str) -> int: while char in current: current = current[1:] - current += char # Expand the substring with the current character - longest = max(longest, len(current)) # Update longest if needed + current += char # Expand the substring with the current character + longest = max(longest, len(current)) # Update longest if needed return longest From e7400493835c7f4d1af99489e0a752bb54ef2812 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 18:33:36 +0100 Subject: [PATCH 063/133] Add comprehensive test suite for length_longest_substring function --- .../tests/test_length_longest_substring.py | 79 ++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/solutions/tests/test_length_longest_substring.py b/solutions/tests/test_length_longest_substring.py index 22c451871..1aceebc70 100644 --- a/solutions/tests/test_length_longest_substring.py +++ b/solutions/tests/test_length_longest_substring.py @@ -17,5 +17,82 @@ class TestLengthLongestSubstring(unittest.TestCase): """Tests for length_longest_substring""" def test_basic_case(self): - """Should return 3 for 'abcabcbb'.""" + """It should return 3 for 'abcabcbb'.""" self.assertEqual(length_longest_substring('abcabcbb'), 3) + + def test_all_unique_characters(self): + """It should return the length of the string with all unique characters.""" + self.assertEqual(length_longest_substring('abcdef'), 6) + + def test_all_identical_characters(self): + """It should return 1 for strings with all identical characters.""" + self.assertEqual(length_longest_substring('aaaaaa'), 1) + + def test_single_character(self): + """lt should return 1 for a string with a single character.""" + self.assertEqual(length_longest_substring('a'), 1) + + def test_alternating_characters(self): + """lt should return 2 for 'abababab'.""" + self.assertEqual(length_longest_substring('abababab'), 2) + + def test_substring_at_the_end(self): + """lt should return 5 for 'abcdabcde'.""" + self.assertEqual(length_longest_substring('abcdabcde'), 5) + + def test_substring_at_the_beginning(self): + """lt should return 5 for 'abcdeabcd'.""" + self.assertEqual(length_longest_substring('abcdeabcd'), 5) + + def test_repeating_characters_in_between(self): + """lt should return 3 for 'abccba'.""" + self.assertEqual(length_longest_substring('abccba'), 3) + + def test_leading_repeated_characters(self): + """lt should return 6 for 'aaabcdef'.""" + self.assertEqual(length_longest_substring('aaabcdef'), 6) + + def test_long_string_with_single_repeated_character(self): + """lt should return 6 for 'abcdeeeeeeeefghij'.""" + self.assertEqual(length_longest_substring('abcdeeeeeeeefghij'), 6) + + def test_mixed_case_sensitivity(self): + """lt should handle characters with different cases uniquely.""" + self.assertEqual(length_longest_substring('AaBbCcDd'), 8) + + def test_numeric_string(self): + """lt should handle numeric-string characters.""" + self.assertEqual(length_longest_substring('123412345'), 5) + + def test_special_characters(self): + """lt should handle symbols as characters.""" + self.assertEqual(length_longest_substring('!@#$%^&*()'), 10) + + def test_mixed_characters(self): + """It should handle strings containing alphanumeric and symbol characters.""" + self.assertEqual(length_longest_substring('a1b#2c$3d4'), 10) + + def test_spaces_included(self): + """lt should handle spaces as characters.""" + self.assertEqual(length_longest_substring('abc abc'), 4) + + def test_empty_string(self): + """It should return 0 for an empty string.""" + self.assertEqual(length_longest_substring(''), 0) + + def test_long_string(self): + """lt should return 1 for 'a' repeated 1 million times.""" + self.assertEqual(length_longest_substring('a' * 10**6), 1) + + def test_invalid_input_integer(self): + """lt should raise an error for non-string input.""" + with self.assertRaises(AssertionError): + length_longest_substring(30) + + def test_invalid_input_none(self): + """lt should raise an error for non-string input.""" + with self.assertRaises(AssertionError): + length_longest_substring(None) + +# if __name__ == "__main__": +# unittest.main() From 439f958fce2333274468820b488f091e01422f85 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 18:36:56 +0100 Subject: [PATCH 064/133] Update test module --- solutions/tests/test_length_longest_substring.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/solutions/tests/test_length_longest_substring.py b/solutions/tests/test_length_longest_substring.py index 1aceebc70..1587dbcfa 100644 --- a/solutions/tests/test_length_longest_substring.py +++ b/solutions/tests/test_length_longest_substring.py @@ -6,6 +6,11 @@ `length_longest_substring` function. It checks the length of the longest substring without repeating characters in a string. +Test categories: + - Standard cases: Typical strings with and without repeating characters. + - Edge cases: Empty strings, single-character strings, and strings with special characters. + - Defensive tests: Non-string inputs to ensure proper assertion handling. + Created on: 2025-01-03 Author: Jola-Moses """ From fab77eaa7692f02f0f62a685ed6b9b6b2b66c4a5 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 18:39:56 +0100 Subject: [PATCH 065/133] Add input type validation with assert isinstance --- solutions/length_longest_substring.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solutions/length_longest_substring.py b/solutions/length_longest_substring.py index 020d3ed98..65d74f4bd 100644 --- a/solutions/length_longest_substring.py +++ b/solutions/length_longest_substring.py @@ -34,6 +34,8 @@ def length_longest_substring(s: str) -> int: 1 """ + assert isinstance(s, str), "s input should be a string" + # Track the length of the longest substring without repeating characters longest = 0 From 50b55ce029c86d834ca7afa8b2f6dc8e5461faf6 Mon Sep 17 00:00:00 2001 From: Mojtaba Fayyaz Date: Fri, 3 Jan 2025 23:03:12 +0500 Subject: [PATCH 066/133] Add module docstring to test_remove_every_other.py --- solutions/tests/test_remove_every_other.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/solutions/tests/test_remove_every_other.py b/solutions/tests/test_remove_every_other.py index ad71018aa..2b7c79109 100644 --- a/solutions/tests/test_remove_every_other.py +++ b/solutions/tests/test_remove_every_other.py @@ -1,3 +1,11 @@ +""" +This module contains unit tests for the `remove_every_other` function. + +The tests cover various scenarios to ensure the function behaves correctly, +including edge cases (e.g., empty lists, single-element lists), +lists with mixed data types, large inputs, and handling of invalid inputs. +""" + import unittest from solutions.remove_every_other import remove_every_other # Updated import @@ -42,14 +50,12 @@ def test_defensive_assertion(self): with self.assertRaises(AssertionError): remove_every_other("Not a list") - # New test case for empty list def test_empty_list(self): """ Test that an empty list returns an empty list. """ self.assertEqual(remove_every_other([]), []) - # Updated test case for list with duplicates def test_list_with_duplicates(self): """ Test that the function handles duplicate values correctly. From 1204b76a6003fab359ead5275940c879fcf605c8 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 19:05:13 +0100 Subject: [PATCH 067/133] Fix code formatting --- solutions/length_longest_substring.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/solutions/length_longest_substring.py b/solutions/length_longest_substring.py index 65d74f4bd..788aa54c5 100644 --- a/solutions/length_longest_substring.py +++ b/solutions/length_longest_substring.py @@ -12,6 +12,8 @@ Created on: 2025-01-03 Author: Jola-Moses """ + + def length_longest_substring(s: str) -> int: """ Returns the length of the longest substring without repeating characters. @@ -26,10 +28,10 @@ def length_longest_substring(s: str) -> int: >>> length_longest_substring("abcabcbb") 3 - + >>> length_longest_substring("abcdef") 6 - + >>> length_longest_substring("aaaaaa") 1 """ From 475456aee39c8640d168f715b472211cf7e2cd7a Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 3 Jan 2025 19:08:53 +0100 Subject: [PATCH 068/133] Refactor test case strings to use double quotes for consistency --- .../tests/test_length_longest_substring.py | 48 ++++++++++--------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/solutions/tests/test_length_longest_substring.py b/solutions/tests/test_length_longest_substring.py index 1587dbcfa..8878743bb 100644 --- a/solutions/tests/test_length_longest_substring.py +++ b/solutions/tests/test_length_longest_substring.py @@ -18,76 +18,77 @@ import unittest from solutions.length_longest_substring import length_longest_substring + class TestLengthLongestSubstring(unittest.TestCase): """Tests for length_longest_substring""" def test_basic_case(self): """It should return 3 for 'abcabcbb'.""" - self.assertEqual(length_longest_substring('abcabcbb'), 3) + self.assertEqual(length_longest_substring("abcabcbb"), 3) def test_all_unique_characters(self): - """It should return the length of the string with all unique characters.""" - self.assertEqual(length_longest_substring('abcdef'), 6) + """It should return the length of the string with all unique characters.""" + self.assertEqual(length_longest_substring("abcdef"), 6) def test_all_identical_characters(self): - """It should return 1 for strings with all identical characters.""" - self.assertEqual(length_longest_substring('aaaaaa'), 1) + """It should return 1 for strings with all identical characters.""" + self.assertEqual(length_longest_substring("aaaaaa"), 1) def test_single_character(self): """lt should return 1 for a string with a single character.""" - self.assertEqual(length_longest_substring('a'), 1) + self.assertEqual(length_longest_substring("a"), 1) def test_alternating_characters(self): """lt should return 2 for 'abababab'.""" - self.assertEqual(length_longest_substring('abababab'), 2) + self.assertEqual(length_longest_substring("abababab"), 2) def test_substring_at_the_end(self): """lt should return 5 for 'abcdabcde'.""" - self.assertEqual(length_longest_substring('abcdabcde'), 5) + self.assertEqual(length_longest_substring("abcdabcde"), 5) def test_substring_at_the_beginning(self): """lt should return 5 for 'abcdeabcd'.""" - self.assertEqual(length_longest_substring('abcdeabcd'), 5) + self.assertEqual(length_longest_substring("abcdeabcd"), 5) def test_repeating_characters_in_between(self): - """lt should return 3 for 'abccba'.""" - self.assertEqual(length_longest_substring('abccba'), 3) + """lt should return 3 for 'abccba'.""" + self.assertEqual(length_longest_substring("abccba"), 3) def test_leading_repeated_characters(self): - """lt should return 6 for 'aaabcdef'.""" - self.assertEqual(length_longest_substring('aaabcdef'), 6) + """lt should return 6 for 'aaabcdef'.""" + self.assertEqual(length_longest_substring("aaabcdef"), 6) def test_long_string_with_single_repeated_character(self): """lt should return 6 for 'abcdeeeeeeeefghij'.""" - self.assertEqual(length_longest_substring('abcdeeeeeeeefghij'), 6) + self.assertEqual(length_longest_substring("abcdeeeeeeeefghij"), 6) def test_mixed_case_sensitivity(self): """lt should handle characters with different cases uniquely.""" - self.assertEqual(length_longest_substring('AaBbCcDd'), 8) + self.assertEqual(length_longest_substring("AaBbCcDd"), 8) def test_numeric_string(self): """lt should handle numeric-string characters.""" - self.assertEqual(length_longest_substring('123412345'), 5) + self.assertEqual(length_longest_substring("123412345"), 5) def test_special_characters(self): """lt should handle symbols as characters.""" - self.assertEqual(length_longest_substring('!@#$%^&*()'), 10) + self.assertEqual(length_longest_substring("!@#$%^&*()"), 10) def test_mixed_characters(self): """It should handle strings containing alphanumeric and symbol characters.""" - self.assertEqual(length_longest_substring('a1b#2c$3d4'), 10) + self.assertEqual(length_longest_substring("a1b#2c$3d4"), 10) def test_spaces_included(self): """lt should handle spaces as characters.""" - self.assertEqual(length_longest_substring('abc abc'), 4) + self.assertEqual(length_longest_substring("abc abc"), 4) def test_empty_string(self): - """It should return 0 for an empty string.""" - self.assertEqual(length_longest_substring(''), 0) + """It should return 0 for an empty string.""" + self.assertEqual(length_longest_substring(""), 0) def test_long_string(self): """lt should return 1 for 'a' repeated 1 million times.""" - self.assertEqual(length_longest_substring('a' * 10**6), 1) + self.assertEqual(length_longest_substring("a" * 10**6), 1) def test_invalid_input_integer(self): """lt should raise an error for non-string input.""" @@ -95,9 +96,10 @@ def test_invalid_input_integer(self): length_longest_substring(30) def test_invalid_input_none(self): - """lt should raise an error for non-string input.""" + """lt should raise an error for non-string input.""" with self.assertRaises(AssertionError): length_longest_substring(None) + # if __name__ == "__main__": # unittest.main() From b0f64aa5c74b5fa2d7706422af07686d3a5428e8 Mon Sep 17 00:00:00 2001 From: Mojtaba Fayyaz Date: Fri, 3 Jan 2025 23:43:31 +0500 Subject: [PATCH 069/133] Add module docstring to the test file. --- solutions/tests/test_reverse_string.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/solutions/tests/test_reverse_string.py b/solutions/tests/test_reverse_string.py index 70657a9f3..ba0f0d3fc 100644 --- a/solutions/tests/test_reverse_string.py +++ b/solutions/tests/test_reverse_string.py @@ -1,5 +1,12 @@ """ -Tests for the reverse_string function. +Module: reverse_string +Author: Mojtaba Fayyaz +Date: 2024-01-02 + +This module contains unit tests for the `reverse_string` function. +The tests verify the function's behavior with various input scenarios, +including edge cases such as empty strings, single-character strings, +palindromes, and mixed characters, as well as invalid input handling. """ import unittest From 9c173102f15408da410e1295a3129d16a7b6a117 Mon Sep 17 00:00:00 2001 From: Mojtaba Fayyaz Date: Fri, 3 Jan 2025 23:50:14 +0500 Subject: [PATCH 070/133] Add module docstring to the test file --- solutions/tests/test_reverse_string.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_reverse_string.py b/solutions/tests/test_reverse_string.py index ba0f0d3fc..6767972b9 100644 --- a/solutions/tests/test_reverse_string.py +++ b/solutions/tests/test_reverse_string.py @@ -1,5 +1,5 @@ """ -Module: reverse_string +Module: test_reverse_string Author: Mojtaba Fayyaz Date: 2024-01-02 From cf44752eb1c0d9e38554c8d8e695dd72228aee42 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sat, 4 Jan 2025 12:39:11 +0100 Subject: [PATCH 071/133] Refactor: Rename fucntion 'length_longest_substring' to 'longest_substring_length' for clarity --- solutions/length_longest_substring.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/solutions/length_longest_substring.py b/solutions/length_longest_substring.py index 788aa54c5..980a3a97b 100644 --- a/solutions/length_longest_substring.py +++ b/solutions/length_longest_substring.py @@ -6,7 +6,7 @@ Module Contents: - - length_longest_substring(s: str) -> int: + - longest_substring_length(s: str) -> int: Finds the length of the longest substring without repeating characters. Created on: 2025-01-03 @@ -14,7 +14,7 @@ """ -def length_longest_substring(s: str) -> int: +def longest_substring_length(s: str) -> int: """ Returns the length of the longest substring without repeating characters. @@ -26,13 +26,13 @@ def length_longest_substring(s: str) -> int: Raises: AssertionError: if s is not a string - >>> length_longest_substring("abcabcbb") + >>> longest_substring_length("abcabcbb") 3 - >>> length_longest_substring("abcdef") + >>> longest_substring_length("abcdef") 6 - >>> length_longest_substring("aaaaaa") + >>> longest_substring_length("aaaaaa") 1 """ From 4b28f736f999e4c637de7102248b1c1bff165784 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sat, 4 Jan 2025 15:16:57 +0100 Subject: [PATCH 072/133] Rename files to reflect updated function --- .../{length_longest_substring.py => longest_substring_length.py} | 0 ...ngth_longest_substring.py => test_longest_substring_length.py} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename solutions/{length_longest_substring.py => longest_substring_length.py} (100%) rename solutions/tests/{test_length_longest_substring.py => test_longest_substring_length.py} (100%) diff --git a/solutions/length_longest_substring.py b/solutions/longest_substring_length.py similarity index 100% rename from solutions/length_longest_substring.py rename to solutions/longest_substring_length.py diff --git a/solutions/tests/test_length_longest_substring.py b/solutions/tests/test_longest_substring_length.py similarity index 100% rename from solutions/tests/test_length_longest_substring.py rename to solutions/tests/test_longest_substring_length.py From 961e65ff01050e3b96f0dd64a6d4e1c7affa4b85 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sat, 4 Jan 2025 15:19:56 +0100 Subject: [PATCH 073/133] Remove redundant comments --- solutions/longest_substring_length.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/solutions/longest_substring_length.py b/solutions/longest_substring_length.py index 980a3a97b..51fd93b62 100644 --- a/solutions/longest_substring_length.py +++ b/solutions/longest_substring_length.py @@ -38,20 +38,16 @@ def longest_substring_length(s: str) -> int: assert isinstance(s, str), "s input should be a string" - # Track the length of the longest substring without repeating characters longest = 0 - - # Store the substring being evaluated current = "" - # Iterate through each character to find substrings for char in s: if char in current: - # Remove characters until the repeating one is eliminated + # Remove repeating characters from the substring while char in current: current = current[1:] - current += char # Expand the substring with the current character - longest = max(longest, len(current)) # Update longest if needed + current += char + longest = max(longest, len(current)) return longest From 45f436195934caea9de1ae6d2c77a7bdba874e93 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sat, 4 Jan 2025 15:21:21 +0100 Subject: [PATCH 074/133] Refactor: Update function name --- .../tests/test_longest_substring_length.py | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/solutions/tests/test_longest_substring_length.py b/solutions/tests/test_longest_substring_length.py index 8878743bb..6d06729a0 100644 --- a/solutions/tests/test_longest_substring_length.py +++ b/solutions/tests/test_longest_substring_length.py @@ -3,7 +3,7 @@ """ This module contains unit tests to validate the functionality of the -`length_longest_substring` function. +`longest_substring_length` function. It checks the length of the longest substring without repeating characters in a string. Test categories: @@ -16,90 +16,90 @@ """ import unittest -from solutions.length_longest_substring import length_longest_substring +from solutions.longest_substring_length import longest_substring_length -class TestLengthLongestSubstring(unittest.TestCase): - """Tests for length_longest_substring""" +class TestLongestSubstringLength(unittest.TestCase): + """Tests for longest_substring_length""" def test_basic_case(self): """It should return 3 for 'abcabcbb'.""" - self.assertEqual(length_longest_substring("abcabcbb"), 3) + self.assertEqual(longest_substring_length("abcabcbb"), 3) def test_all_unique_characters(self): """It should return the length of the string with all unique characters.""" - self.assertEqual(length_longest_substring("abcdef"), 6) + self.assertEqual(longest_substring_length("abcdef"), 6) def test_all_identical_characters(self): """It should return 1 for strings with all identical characters.""" - self.assertEqual(length_longest_substring("aaaaaa"), 1) + self.assertEqual(longest_substring_length("aaaaaa"), 1) def test_single_character(self): """lt should return 1 for a string with a single character.""" - self.assertEqual(length_longest_substring("a"), 1) + self.assertEqual(longest_substring_length("a"), 1) def test_alternating_characters(self): """lt should return 2 for 'abababab'.""" - self.assertEqual(length_longest_substring("abababab"), 2) + self.assertEqual(longest_substring_length("abababab"), 2) def test_substring_at_the_end(self): """lt should return 5 for 'abcdabcde'.""" - self.assertEqual(length_longest_substring("abcdabcde"), 5) + self.assertEqual(longest_substring_length("abcdabcde"), 5) def test_substring_at_the_beginning(self): """lt should return 5 for 'abcdeabcd'.""" - self.assertEqual(length_longest_substring("abcdeabcd"), 5) + self.assertEqual(longest_substring_length("abcdeabcd"), 5) def test_repeating_characters_in_between(self): """lt should return 3 for 'abccba'.""" - self.assertEqual(length_longest_substring("abccba"), 3) + self.assertEqual(longest_substring_length("abccba"), 3) def test_leading_repeated_characters(self): """lt should return 6 for 'aaabcdef'.""" - self.assertEqual(length_longest_substring("aaabcdef"), 6) + self.assertEqual(longest_substring_length("aaabcdef"), 6) def test_long_string_with_single_repeated_character(self): """lt should return 6 for 'abcdeeeeeeeefghij'.""" - self.assertEqual(length_longest_substring("abcdeeeeeeeefghij"), 6) + self.assertEqual(longest_substring_length("abcdeeeeeeeefghij"), 6) def test_mixed_case_sensitivity(self): """lt should handle characters with different cases uniquely.""" - self.assertEqual(length_longest_substring("AaBbCcDd"), 8) + self.assertEqual(longest_substring_length("AaBbCcDd"), 8) def test_numeric_string(self): """lt should handle numeric-string characters.""" - self.assertEqual(length_longest_substring("123412345"), 5) + self.assertEqual(longest_substring_length("123412345"), 5) def test_special_characters(self): """lt should handle symbols as characters.""" - self.assertEqual(length_longest_substring("!@#$%^&*()"), 10) + self.assertEqual(longest_substring_length("!@#$%^&*()"), 10) def test_mixed_characters(self): """It should handle strings containing alphanumeric and symbol characters.""" - self.assertEqual(length_longest_substring("a1b#2c$3d4"), 10) + self.assertEqual(longest_substring_length("a1b#2c$3d4"), 10) def test_spaces_included(self): """lt should handle spaces as characters.""" - self.assertEqual(length_longest_substring("abc abc"), 4) + self.assertEqual(longest_substring_length("abc abc"), 4) def test_empty_string(self): """It should return 0 for an empty string.""" - self.assertEqual(length_longest_substring(""), 0) + self.assertEqual(longest_substring_length(""), 0) def test_long_string(self): """lt should return 1 for 'a' repeated 1 million times.""" - self.assertEqual(length_longest_substring("a" * 10**6), 1) + self.assertEqual(longest_substring_length("a" * 10**6), 1) def test_invalid_input_integer(self): """lt should raise an error for non-string input.""" with self.assertRaises(AssertionError): - length_longest_substring(30) + longest_substring_length(30) def test_invalid_input_none(self): """lt should raise an error for non-string input.""" with self.assertRaises(AssertionError): - length_longest_substring(None) + longest_substring_length(None) -# if __name__ == "__main__": -# unittest.main() +if __name__ == "__main__": + unittest.main() From 5165a2f11313d982412bd444a803d10dd0ceb76e Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 07:29:30 +0100 Subject: [PATCH 075/133] Refactor tests: Remove redundancy, rename, and update docstring --- .../tests/test_longest_substring_length.py | 30 ++----------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/solutions/tests/test_longest_substring_length.py b/solutions/tests/test_longest_substring_length.py index 6d06729a0..87d83aac2 100644 --- a/solutions/tests/test_longest_substring_length.py +++ b/solutions/tests/test_longest_substring_length.py @@ -42,23 +42,7 @@ def test_alternating_characters(self): """lt should return 2 for 'abababab'.""" self.assertEqual(longest_substring_length("abababab"), 2) - def test_substring_at_the_end(self): - """lt should return 5 for 'abcdabcde'.""" - self.assertEqual(longest_substring_length("abcdabcde"), 5) - - def test_substring_at_the_beginning(self): - """lt should return 5 for 'abcdeabcd'.""" - self.assertEqual(longest_substring_length("abcdeabcd"), 5) - - def test_repeating_characters_in_between(self): - """lt should return 3 for 'abccba'.""" - self.assertEqual(longest_substring_length("abccba"), 3) - - def test_leading_repeated_characters(self): - """lt should return 6 for 'aaabcdef'.""" - self.assertEqual(longest_substring_length("aaabcdef"), 6) - - def test_long_string_with_single_repeated_character(self): + def test_long_repetition(self): """lt should return 6 for 'abcdeeeeeeeefghij'.""" self.assertEqual(longest_substring_length("abcdeeeeeeeefghij"), 6) @@ -66,20 +50,12 @@ def test_mixed_case_sensitivity(self): """lt should handle characters with different cases uniquely.""" self.assertEqual(longest_substring_length("AaBbCcDd"), 8) - def test_numeric_string(self): - """lt should handle numeric-string characters.""" - self.assertEqual(longest_substring_length("123412345"), 5) - - def test_special_characters(self): - """lt should handle symbols as characters.""" - self.assertEqual(longest_substring_length("!@#$%^&*()"), 10) - def test_mixed_characters(self): """It should handle strings containing alphanumeric and symbol characters.""" self.assertEqual(longest_substring_length("a1b#2c$3d4"), 10) - def test_spaces_included(self): - """lt should handle spaces as characters.""" + def test_space(self): + """lt should handle a space as a character.""" self.assertEqual(longest_substring_length("abc abc"), 4) def test_empty_string(self): From f9c343b9f39572b7ee6d8e0b2aacb226e61caf30 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 09:33:10 +0100 Subject: [PATCH 076/133] Create function and test files --- solutions/maximum_profit.py | 0 solutions/tests/test_maximum_profit.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/maximum_profit.py create mode 100644 solutions/tests/test_maximum_profit.py diff --git a/solutions/maximum_profit.py b/solutions/maximum_profit.py new file mode 100644 index 000000000..e69de29bb diff --git a/solutions/tests/test_maximum_profit.py b/solutions/tests/test_maximum_profit.py new file mode 100644 index 000000000..e69de29bb From 0bbc8499b84ad3549f742bc352c59e575b5be02b Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 10:12:13 +0100 Subject: [PATCH 077/133] Add function with docstring and doctests --- solutions/maximum_profit.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/solutions/maximum_profit.py b/solutions/maximum_profit.py index e69de29bb..61ee6c526 100644 --- a/solutions/maximum_profit.py +++ b/solutions/maximum_profit.py @@ -0,0 +1,22 @@ + +def max_profit(prices: list[int]) -> int: + """ + Returns the maximum profit from as many stock transactions as possible. + + Parameters: + prices (list[int]): A list of integers representing the stock prices on different days. + + Returns: + int: The maximum profit that can be achieved by making as many transactions as possible. + + Raises: + AssertionError: If `prices` is not a list of integers. + + Examples: + >>> max_profit([7, 1, 5, 3, 6, 4]) + 7 + >>> max_profit([1, 2, 3, 4, 5]) + 4 + >>> max_profit([7, 6, 4, 3, 1]) + 0 + """ From 24e04bb96a3c915f567bc9b4294804282db861ca Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 10:29:52 +0100 Subject: [PATCH 078/133] Add module docstring --- solutions/maximum_profit.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/solutions/maximum_profit.py b/solutions/maximum_profit.py index 61ee6c526..2a87be2ba 100644 --- a/solutions/maximum_profit.py +++ b/solutions/maximum_profit.py @@ -1,3 +1,15 @@ +""" +A module to calculate the maximum profit from stock trading. + +Module Contents: + + - max_profit(prices: list[int]) -> int: + Computes the maximum profit that can be made by completing as many transactions as possible + (buy one and sell one share of stock multiple times). + +Created on: 2025-01-05 +Author: Jola-Moses +""" def max_profit(prices: list[int]) -> int: """ From 90fb9882c8e8d9ff3871ba68be3720d6a99f9afa Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 10:42:38 +0100 Subject: [PATCH 079/133] Rename files to match fucntion --- solutions/{maximum_profit.py => max_profit.py} | 0 solutions/tests/{test_maximum_profit.py => test_max_profit.py} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename solutions/{maximum_profit.py => max_profit.py} (100%) rename solutions/tests/{test_maximum_profit.py => test_max_profit.py} (100%) diff --git a/solutions/maximum_profit.py b/solutions/max_profit.py similarity index 100% rename from solutions/maximum_profit.py rename to solutions/max_profit.py diff --git a/solutions/tests/test_maximum_profit.py b/solutions/tests/test_max_profit.py similarity index 100% rename from solutions/tests/test_maximum_profit.py rename to solutions/tests/test_max_profit.py From 8e3a3d662113e982cea4b82a822c4fbd7843f6fd Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 10:53:28 +0100 Subject: [PATCH 080/133] Fail first test --- solutions/tests/test_max_profit.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/solutions/tests/test_max_profit.py b/solutions/tests/test_max_profit.py index e69de29bb..3de8e0c64 100644 --- a/solutions/tests/test_max_profit.py +++ b/solutions/tests/test_max_profit.py @@ -0,0 +1,11 @@ +import unittest + +from solutions.max_profit import max_profit + + +class MaxProfit(unittest.TestCase): + """Tests for max_profit function""" + + def test_basic_case(self): + """Buy at 1 and sell at 5, then buy at 3 and sell at 6, for a total profit of 7.""" + self.assertEqual(max_profit([7,1,5,3,6,4]), 7) \ No newline at end of file From f6160aefb7f58f476b97f58180680ff454befb9f Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 11:12:04 +0100 Subject: [PATCH 081/133] Add function implementation --- solutions/max_profit.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/solutions/max_profit.py b/solutions/max_profit.py index 2a87be2ba..cc42a68fd 100644 --- a/solutions/max_profit.py +++ b/solutions/max_profit.py @@ -32,3 +32,13 @@ def max_profit(prices: list[int]) -> int: >>> max_profit([7, 6, 4, 3, 1]) 0 """ + + max_profit = 0 + + # Compare each day's price with the previous day's, starting from the second day + for i in range(1, len(prices)): + # Add profit if today's price is higher than yesterday's. + if prices[i] > prices[i - 1]: + max_profit += prices[i] - prices[i - 1] + + return max_profit From c5fead37edfe3100eb5c87acf3687f755820ba1c Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 11:13:16 +0100 Subject: [PATCH 082/133] Update implementation --- solutions/max_profit.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solutions/max_profit.py b/solutions/max_profit.py index cc42a68fd..5ed114d9f 100644 --- a/solutions/max_profit.py +++ b/solutions/max_profit.py @@ -33,12 +33,12 @@ def max_profit(prices: list[int]) -> int: 0 """ - max_profit = 0 + maximum_profit = 0 # Compare each day's price with the previous day's, starting from the second day for i in range(1, len(prices)): # Add profit if today's price is higher than yesterday's. if prices[i] > prices[i - 1]: - max_profit += prices[i] - prices[i - 1] + maximum_profit += prices[i] - prices[i - 1] - return max_profit + return maximum_profit From 3def6ba76c715c89eb0d42c5a10c5adc1bc4b338 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 12:07:56 +0100 Subject: [PATCH 083/133] Add defensive assertions --- solutions/max_profit.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/solutions/max_profit.py b/solutions/max_profit.py index 5ed114d9f..d9fc66bba 100644 --- a/solutions/max_profit.py +++ b/solutions/max_profit.py @@ -33,6 +33,10 @@ def max_profit(prices: list[int]) -> int: 0 """ + assert isinstance(prices, list), "Input should be a list." + assert all(isinstance(price, (int, float)) for price in prices), "Prices should be numeric." + assert all(price >= 0 for price in prices), "Prices should not be negative." + maximum_profit = 0 # Compare each day's price with the previous day's, starting from the second day From eddbc04832654d8a256ca2d3c31825b7bb9c5be5 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 12:23:39 +0100 Subject: [PATCH 084/133] Update fucntion docstring --- solutions/max_profit.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/solutions/max_profit.py b/solutions/max_profit.py index d9fc66bba..a9f667788 100644 --- a/solutions/max_profit.py +++ b/solutions/max_profit.py @@ -22,7 +22,9 @@ def max_profit(prices: list[int]) -> int: int: The maximum profit that can be achieved by making as many transactions as possible. Raises: - AssertionError: If `prices` is not a list of integers. + AssertionError: If `prices` is not a list. + AssertionError: If any element in `prices` is not a numeric type (either int or float). + AssertionError: If any price in `prices` is less than zero. Examples: >>> max_profit([7, 1, 5, 3, 6, 4]) From 81539f1e98394b7e36aad9de8106a8e32da06ec1 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 13:01:49 +0100 Subject: [PATCH 085/133] Refactor defensive assertions and docstring --- solutions/max_profit.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/solutions/max_profit.py b/solutions/max_profit.py index a9f667788..e2700b70c 100644 --- a/solutions/max_profit.py +++ b/solutions/max_profit.py @@ -11,15 +11,16 @@ Author: Jola-Moses """ -def max_profit(prices: list[int]) -> int: +def max_profit(prices: list) -> int: """ Returns the maximum profit from as many stock transactions as possible. Parameters: - prices (list[int]): A list of integers representing the stock prices on different days. + prices (list): A list of positive integers or floats representing the stock prices + on different days. Returns: - int: The maximum profit that can be achieved by making as many transactions as possible. + int, float: The maximum profit that can be made from as many transactions as possible. Raises: AssertionError: If `prices` is not a list. @@ -36,8 +37,10 @@ def max_profit(prices: list[int]) -> int: """ assert isinstance(prices, list), "Input should be a list." - assert all(isinstance(price, (int, float)) for price in prices), "Prices should be numeric." - assert all(price >= 0 for price in prices), "Prices should not be negative." + assert all( + isinstance(price, (int, float)) for price in prices + ), "Prices should be integers or floats." + assert all(price >= 0 for price in prices), "Prices should be non-negative integers or floats." maximum_profit = 0 From 8bcb68bdf0ffdfaa29828ba658b0b13efcf14acc Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 13:04:46 +0100 Subject: [PATCH 086/133] Add comprehensive test suite --- solutions/tests/test_max_profit.py | 53 ++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/solutions/tests/test_max_profit.py b/solutions/tests/test_max_profit.py index 3de8e0c64..4822530ee 100644 --- a/solutions/tests/test_max_profit.py +++ b/solutions/tests/test_max_profit.py @@ -5,7 +5,54 @@ class MaxProfit(unittest.TestCase): """Tests for max_profit function""" - + def test_basic_case(self): - """Buy at 1 and sell at 5, then buy at 3 and sell at 6, for a total profit of 7.""" - self.assertEqual(max_profit([7,1,5,3,6,4]), 7) \ No newline at end of file + """Buys at 1 and sells at 5, then buys at 3 and sells at 6, for a total profit of 7.""" + self.assertEqual(max_profit([7,1,5,3,6,4]), 7) + + def test_all_increasing_prices(self): + """Buys at 1 and sells at 5, for a total profit of 4.""" + self.assertEqual(max_profit([1,2,3,4,5]), 4) + + def test_decreasing_prices(self): + """Returns 0 when prices only decrease, as no profit can be made.""" + self.assertEqual(max_profit([7,6,4,3,1]), 0) + + def test_constant_prices(self): + """Returns 0 for constant prices, as no profit can be made.""" + self.assertEqual(max_profit([5,5,5,5,5]), 0) + + def test_single_day_price(self): + """Returns 0 for single day prices, as no profit can be made.""" + self.assertEqual(max_profit([10]), 0) + + def test_alternating_prices(self): + """Buys at 10 and sells at 20, three times, for a total profit of 30.""" + self.assertEqual(max_profit([10,20,10,20,10,20]), 30) + + def test_float_prices(self): + """Returns a total profit of 35.0.""" + self.assertEqual(max_profit([5.5,10.5,20.5,10.5,30.5]), 35.0) + + def test_large_price_difference(self): + """Buys at 1 and sells at 30001 for a profit of 30000.""" + self.assertEqual(max_profit([1, 30001]), 30000) + + def test_empty_prices(self): + """Returns 0 for an empty list of prices.""" + self.assertEqual(max_profit([]), 0) + + def test_negative_prices(self): + """Raises an AssertionError for negative price values.""" + with self.assertRaises(AssertionError): + max_profit([10, -5, 2, 3]) + + def test_non_list_input(self): + """Raises an AssertionError for non_list inputs.""" + with self.assertRaises(AssertionError): + max_profit(None) + + def test_non_numeric_values(self): + """Raises an AssertionError for non_numeric_values.""" + with self.assertRaises(AssertionError): + max_profit([1.5, "2", 3]) From 8cb8bd8f05785941a5e1bfa0f806766429304f76 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 13:09:40 +0100 Subject: [PATCH 087/133] Add test module docstring --- solutions/tests/test_max_profit.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/solutions/tests/test_max_profit.py b/solutions/tests/test_max_profit.py index 4822530ee..470685fd1 100644 --- a/solutions/tests/test_max_profit.py +++ b/solutions/tests/test_max_profit.py @@ -1,3 +1,19 @@ +""" +This module contains unit tests to validate the functionality of the +`max_profit` function. +It calculates the maximum profit from stock prices over several days, +allowing for multiple transactions. + +Test categories: + - Standard cases: Typical lists of stock prices with varying price patterns. + - Edge cases: Empty lists, single price day, and large price differences. + - Defensive tests: Non-list inputs, non-numeric prices, and negative prices + to ensure proper assertion handling. + +Created on: 2025-01-05 +Author: Jola-Moses +""" + import unittest from solutions.max_profit import max_profit From 08bba40b8eb5a0540d3d7f15d198a9f7097962f1 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 19:27:36 +0100 Subject: [PATCH 088/133] Rename files to match function --- solutions/{max_profit.py => calculate_max_profit.py} | 0 .../tests/{test_max_profit.py => test_calculate_max_profit.py} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename solutions/{max_profit.py => calculate_max_profit.py} (100%) rename solutions/tests/{test_max_profit.py => test_calculate_max_profit.py} (100%) diff --git a/solutions/max_profit.py b/solutions/calculate_max_profit.py similarity index 100% rename from solutions/max_profit.py rename to solutions/calculate_max_profit.py diff --git a/solutions/tests/test_max_profit.py b/solutions/tests/test_calculate_max_profit.py similarity index 100% rename from solutions/tests/test_max_profit.py rename to solutions/tests/test_calculate_max_profit.py From ca23c9db9159f3aa7ed4385d1ae899ebe7511271 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 19:29:44 +0100 Subject: [PATCH 089/133] Refactor: Rename function to reflect behaviour --- solutions/calculate_max_profit.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/solutions/calculate_max_profit.py b/solutions/calculate_max_profit.py index e2700b70c..031642b5e 100644 --- a/solutions/calculate_max_profit.py +++ b/solutions/calculate_max_profit.py @@ -3,7 +3,7 @@ Module Contents: - - max_profit(prices: list[int]) -> int: + - calculate_max_profit(prices: list[int]) -> int: Computes the maximum profit that can be made by completing as many transactions as possible (buy one and sell one share of stock multiple times). @@ -11,13 +11,13 @@ Author: Jola-Moses """ -def max_profit(prices: list) -> int: +def calculate_max_profit(prices: list) -> int: """ Returns the maximum profit from as many stock transactions as possible. Parameters: - prices (list): A list of positive integers or floats representing the stock prices - on different days. + prices (list): A list of non-negative integers or floats representing the stock prices + on different days. Each price is greater than or equal to zero." Returns: int, float: The maximum profit that can be made from as many transactions as possible. @@ -28,11 +28,11 @@ def max_profit(prices: list) -> int: AssertionError: If any price in `prices` is less than zero. Examples: - >>> max_profit([7, 1, 5, 3, 6, 4]) + >>> calculate_max_profit([7, 1, 5, 3, 6, 4]) 7 - >>> max_profit([1, 2, 3, 4, 5]) + >>> calculate_max_profit([1, 2, 3, 4, 5]) 4 - >>> max_profit([7, 6, 4, 3, 1]) + >>> calculate_max_profit([7, 6, 4, 3, 1]) 0 """ From 30685de7d58282e1484ca48aae18a53d7a679f57 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 19:31:40 +0100 Subject: [PATCH 090/133] Refactor: Update test suite with renamed function --- solutions/tests/test_calculate_max_profit.py | 32 ++++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/solutions/tests/test_calculate_max_profit.py b/solutions/tests/test_calculate_max_profit.py index 470685fd1..e2d246ed1 100644 --- a/solutions/tests/test_calculate_max_profit.py +++ b/solutions/tests/test_calculate_max_profit.py @@ -1,6 +1,6 @@ """ This module contains unit tests to validate the functionality of the -`max_profit` function. +`calculate_max_profit` function. It calculates the maximum profit from stock prices over several days, allowing for multiple transactions. @@ -16,59 +16,59 @@ import unittest -from solutions.max_profit import max_profit +from solutions.calculate_max_profit import calculate_max_profit -class MaxProfit(unittest.TestCase): - """Tests for max_profit function""" +class CalculateMaxProfit(unittest.TestCase): + """Tests for calculate_max_profit function""" def test_basic_case(self): """Buys at 1 and sells at 5, then buys at 3 and sells at 6, for a total profit of 7.""" - self.assertEqual(max_profit([7,1,5,3,6,4]), 7) + self.assertEqual(calculate_max_profit([7,1,5,3,6,4]), 7) def test_all_increasing_prices(self): """Buys at 1 and sells at 5, for a total profit of 4.""" - self.assertEqual(max_profit([1,2,3,4,5]), 4) + self.assertEqual(calculate_max_profit([1,2,3,4,5]), 4) def test_decreasing_prices(self): """Returns 0 when prices only decrease, as no profit can be made.""" - self.assertEqual(max_profit([7,6,4,3,1]), 0) + self.assertEqual(calculate_max_profit([7,6,4,3,1]), 0) def test_constant_prices(self): """Returns 0 for constant prices, as no profit can be made.""" - self.assertEqual(max_profit([5,5,5,5,5]), 0) + self.assertEqual(calculate_max_profit([5,5,5,5,5]), 0) def test_single_day_price(self): """Returns 0 for single day prices, as no profit can be made.""" - self.assertEqual(max_profit([10]), 0) + self.assertEqual(calculate_max_profit([10]), 0) def test_alternating_prices(self): """Buys at 10 and sells at 20, three times, for a total profit of 30.""" - self.assertEqual(max_profit([10,20,10,20,10,20]), 30) + self.assertEqual(calculate_max_profit([10,20,10,20,10,20]), 30) def test_float_prices(self): """Returns a total profit of 35.0.""" - self.assertEqual(max_profit([5.5,10.5,20.5,10.5,30.5]), 35.0) + self.assertEqual(calculate_max_profit([5.5,10.5,20.5,10.5,30.5]), 35.0) def test_large_price_difference(self): """Buys at 1 and sells at 30001 for a profit of 30000.""" - self.assertEqual(max_profit([1, 30001]), 30000) + self.assertEqual(calculate_max_profit([1, 30001]), 30000) def test_empty_prices(self): """Returns 0 for an empty list of prices.""" - self.assertEqual(max_profit([]), 0) + self.assertEqual(calculate_max_profit([]), 0) def test_negative_prices(self): """Raises an AssertionError for negative price values.""" with self.assertRaises(AssertionError): - max_profit([10, -5, 2, 3]) + calculate_max_profit([10, -5, 2, 3]) def test_non_list_input(self): """Raises an AssertionError for non_list inputs.""" with self.assertRaises(AssertionError): - max_profit(None) + calculate_max_profit(None) def test_non_numeric_values(self): """Raises an AssertionError for non_numeric_values.""" with self.assertRaises(AssertionError): - max_profit([1.5, "2", 3]) + calculate_max_profit([1.5, "2", 3]) From f4302911a290f4685aebac5a35e48bf7e7e0a101 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 19:33:55 +0100 Subject: [PATCH 091/133] Fix code format --- solutions/tests/test_calculate_max_profit.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/solutions/tests/test_calculate_max_profit.py b/solutions/tests/test_calculate_max_profit.py index e2d246ed1..01e3ef56e 100644 --- a/solutions/tests/test_calculate_max_profit.py +++ b/solutions/tests/test_calculate_max_profit.py @@ -7,7 +7,7 @@ Test categories: - Standard cases: Typical lists of stock prices with varying price patterns. - Edge cases: Empty lists, single price day, and large price differences. - - Defensive tests: Non-list inputs, non-numeric prices, and negative prices + - Defensive tests: Non-list inputs, non-numeric prices, and negative prices to ensure proper assertion handling. Created on: 2025-01-05 @@ -24,19 +24,19 @@ class CalculateMaxProfit(unittest.TestCase): def test_basic_case(self): """Buys at 1 and sells at 5, then buys at 3 and sells at 6, for a total profit of 7.""" - self.assertEqual(calculate_max_profit([7,1,5,3,6,4]), 7) + self.assertEqual(calculate_max_profit([7, 1, 5, 3, 6, 4]), 7) def test_all_increasing_prices(self): """Buys at 1 and sells at 5, for a total profit of 4.""" - self.assertEqual(calculate_max_profit([1,2,3,4,5]), 4) + self.assertEqual(calculate_max_profit([1, 2, 3, 4, 5]), 4) def test_decreasing_prices(self): """Returns 0 when prices only decrease, as no profit can be made.""" - self.assertEqual(calculate_max_profit([7,6,4,3,1]), 0) + self.assertEqual(calculate_max_profit([7, 6, 4, 3, 1]), 0) def test_constant_prices(self): """Returns 0 for constant prices, as no profit can be made.""" - self.assertEqual(calculate_max_profit([5,5,5,5,5]), 0) + self.assertEqual(calculate_max_profit([5, 5, 5, 5, 5]), 0) def test_single_day_price(self): """Returns 0 for single day prices, as no profit can be made.""" @@ -44,11 +44,11 @@ def test_single_day_price(self): def test_alternating_prices(self): """Buys at 10 and sells at 20, three times, for a total profit of 30.""" - self.assertEqual(calculate_max_profit([10,20,10,20,10,20]), 30) + self.assertEqual(calculate_max_profit([10, 20, 10, 20, 10, 20]), 30) def test_float_prices(self): """Returns a total profit of 35.0.""" - self.assertEqual(calculate_max_profit([5.5,10.5,20.5,10.5,30.5]), 35.0) + self.assertEqual(calculate_max_profit([5.5, 10.5, 20.5, 10.5, 30.5]), 35.0) def test_large_price_difference(self): """Buys at 1 and sells at 30001 for a profit of 30000.""" From c526fce834562da1b2e9b94c5c630738089ff793 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 19:34:33 +0100 Subject: [PATCH 092/133] Fix code format --- solutions/calculate_max_profit.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/solutions/calculate_max_profit.py b/solutions/calculate_max_profit.py index 031642b5e..17ae47c95 100644 --- a/solutions/calculate_max_profit.py +++ b/solutions/calculate_max_profit.py @@ -11,12 +11,13 @@ Author: Jola-Moses """ + def calculate_max_profit(prices: list) -> int: """ Returns the maximum profit from as many stock transactions as possible. Parameters: - prices (list): A list of non-negative integers or floats representing the stock prices + prices (list): A list of non-negative integers or floats representing the stock prices on different days. Each price is greater than or equal to zero." Returns: @@ -40,7 +41,9 @@ def calculate_max_profit(prices: list) -> int: assert all( isinstance(price, (int, float)) for price in prices ), "Prices should be integers or floats." - assert all(price >= 0 for price in prices), "Prices should be non-negative integers or floats." + assert all( + price >= 0 for price in prices + ), "Prices should be non-negative integers or floats." maximum_profit = 0 From eb1ee8b43f8c8107262174a5befde36e56b3ea41 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 19:42:15 +0100 Subject: [PATCH 093/133] Refactor --- solutions/calculate_max_profit.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/solutions/calculate_max_profit.py b/solutions/calculate_max_profit.py index 17ae47c95..04f842841 100644 --- a/solutions/calculate_max_profit.py +++ b/solutions/calculate_max_profit.py @@ -41,9 +41,7 @@ def calculate_max_profit(prices: list) -> int: assert all( isinstance(price, (int, float)) for price in prices ), "Prices should be integers or floats." - assert all( - price >= 0 for price in prices - ), "Prices should be non-negative integers or floats." + assert all(price >= 0 for price in prices), "Prices should be non-negative integers or floats." maximum_profit = 0 From 0cbecac8e735c9118b4e4c70c090751e23d72917 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 19:46:00 +0100 Subject: [PATCH 094/133] Fix code format --- solutions/calculate_max_profit.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/solutions/calculate_max_profit.py b/solutions/calculate_max_profit.py index 04f842841..17ae47c95 100644 --- a/solutions/calculate_max_profit.py +++ b/solutions/calculate_max_profit.py @@ -41,7 +41,9 @@ def calculate_max_profit(prices: list) -> int: assert all( isinstance(price, (int, float)) for price in prices ), "Prices should be integers or floats." - assert all(price >= 0 for price in prices), "Prices should be non-negative integers or floats." + assert all( + price >= 0 for price in prices + ), "Prices should be non-negative integers or floats." maximum_profit = 0 From a8fe44d7ad06667f630405f80165d848c3c341f4 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 21:25:16 +0100 Subject: [PATCH 095/133] Refactor for improved clarity --- solutions/longest_substring_length.py | 51 +++++++++++++++------------ 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/solutions/longest_substring_length.py b/solutions/longest_substring_length.py index 51fd93b62..3dca25163 100644 --- a/solutions/longest_substring_length.py +++ b/solutions/longest_substring_length.py @@ -19,35 +19,42 @@ def longest_substring_length(s: str) -> int: Returns the length of the longest substring without repeating characters. Parameters: - s: str, the input string for which to find the longest substring + s (str): The input string for which to find the longest substring. + An empty string is valid input. - Returns -> int, the length of the longest substring without repeating characters + Returns: + int: A non-negative integer representing the length of the longest substring + without repeating characters. Raises: - AssertionError: if s is not a string - - >>> longest_substring_length("abcabcbb") - 3 - - >>> longest_substring_length("abcdef") - 6 - - >>> longest_substring_length("aaaaaa") - 1 + AssertionError: If `s` is not a string. + + Examples: + >>> longest_substring_length("abcabcbb") + 3 + >>> longest_substring_length("abcdef") + 6 + >>> longest_substring_length("aaaaaa") + 1 + >>> longest_substring_length("") + 0 """ - assert isinstance(s, str), "s input should be a string" + assert isinstance(s, str), "Input should be a string" - longest = 0 - current = "" + max_length = 0 + current_substring = "" for char in s: - if char in current: - # Remove repeating characters from the substring - while char in current: - current = current[1:] + if char in current_substring: + # Remove repeating characters + while char in current_substring: + current_substring = current_substring[1:] + + # Add the current character to the substring + current_substring += char - current += char - longest = max(longest, len(current)) + # Update max_length + max_length = max(max_length, len(current_substring)) - return longest + return max_length From b26cb58440d332495b2e1fcb186676582eae71f0 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Sun, 5 Jan 2025 21:32:29 +0100 Subject: [PATCH 096/133] Add encoding --- solutions/calculate_max_profit.py | 3 +++ solutions/tests/test_calculate_max_profit.py | 3 +++ 2 files changed, 6 insertions(+) diff --git a/solutions/calculate_max_profit.py b/solutions/calculate_max_profit.py index 17ae47c95..3f84292de 100644 --- a/solutions/calculate_max_profit.py +++ b/solutions/calculate_max_profit.py @@ -1,3 +1,6 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + """ A module to calculate the maximum profit from stock trading. diff --git a/solutions/tests/test_calculate_max_profit.py b/solutions/tests/test_calculate_max_profit.py index 01e3ef56e..101990b4b 100644 --- a/solutions/tests/test_calculate_max_profit.py +++ b/solutions/tests/test_calculate_max_profit.py @@ -1,3 +1,6 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + """ This module contains unit tests to validate the functionality of the `calculate_max_profit` function. From f651b2a33166d6349b953f4395de1c8f4b9b75e9 Mon Sep 17 00:00:00 2001 From: Muhammad Shahroz Date: Mon, 6 Jan 2025 11:37:29 +0500 Subject: [PATCH 097/133] Refactored and improved remove_duplicates_from_sorted_list solution and tests. Resolves #9 --- .../remove_duplicates_from_sorted_list.py | 42 ++++++++++------ ...test_remove_duplicates_from_sorted_list.py | 49 +++++++++---------- 2 files changed, 50 insertions(+), 41 deletions(-) diff --git a/solutions/remove_duplicates_from_sorted_list.py b/solutions/remove_duplicates_from_sorted_list.py index fc2a685d1..84c745233 100644 --- a/solutions/remove_duplicates_from_sorted_list.py +++ b/solutions/remove_duplicates_from_sorted_list.py @@ -5,7 +5,7 @@ Description: This module provides a function to remove duplicates from a sorted linked list. The function ensures each element appears only once while maintaining the sorted order. -Created on: 31 12 24 +Created on: 01 01 25 @author: Muhammad Shahroz """ @@ -15,17 +15,19 @@ class ListNode: """A node in a singly linked list.""" - def __init__(self, val=0, next_node=None): - self.val = val + def __init__(self, value=0, next_node=None): + self.value = value self.next = next_node -def remove_duplicates(head: Optional[ListNode]) -> Optional[ListNode]: +def remove_duplicates_from_sorted_list(head: Optional[ListNode]) -> Optional[ListNode]: """ Removes duplicates from a sorted linked list. Parameters: head (Optional[ListNode]): The head node of the sorted linked list. + - The input is expected to be a valid ListNode or None. + - The list is assumed to be sorted in non-decreasing order. Returns: Optional[ListNode]: The head node of the modified linked list with duplicates removed. @@ -35,24 +37,34 @@ def remove_duplicates(head: Optional[ListNode]) -> Optional[ListNode]: Examples: >>> head = ListNode(1, ListNode(1, ListNode(2))) - >>> result = remove_duplicates(head) - >>> result.val, result.next.val, result.next.next is None - (1, 2, True) + >>> result = remove_duplicates_from_sorted_list(head) + >>> [result.value, result.next.value, result.next.next] + [1, 2, None] >>> head = ListNode(1, ListNode(1, ListNode(2, ListNode(3, ListNode(3))))) - >>> result = remove_duplicates(head) - >>> result.val, result.next.val, result.next.next.val - (1, 2, 3) + >>> result = remove_duplicates_from_sorted_list(head) + >>> [result.value, result.next.value, result.next.next.value] + [1, 2, 3] + + >>> result = remove_duplicates_from_sorted_list(None) + >>> result is None + True + + Example: + head = ListNode(1, ListNode(1, ListNode(2))) + result = remove_duplicates_from_sorted_list(head) + # result is now a list with values: [1, 2] """ + # Defensive Assertion assert head is None or isinstance( head, ListNode ), "Input must be a ListNode or None." - current = head - while current and current.next: - if current.val == current.next.val: - current.next = current.next.next + current_node = head + while current_node and current_node.next: + if current_node.value == current_node.next.value: + current_node.next = current_node.next.next # Remove duplicate else: - current = current.next + current_node = current_node.next # Move to next node return head diff --git a/solutions/tests/test_remove_duplicates_from_sorted_list.py b/solutions/tests/test_remove_duplicates_from_sorted_list.py index 51eaa21c5..9dfa16787 100644 --- a/solutions/tests/test_remove_duplicates_from_sorted_list.py +++ b/solutions/tests/test_remove_duplicates_from_sorted_list.py @@ -3,83 +3,80 @@ """ Test module for the remove_duplicates_from_sorted_list function. -Created on: 31 12 24 +Created on: 01 01 25 @author: Muhammad Shahroz """ import unittest -from ..remove_duplicates_from_sorted_list import ListNode, remove_duplicates +from ..remove_duplicates_from_sorted_list import ( + ListNode, + remove_duplicates_from_sorted_list, +) class TestRemoveDuplicatesFromSortedList(unittest.TestCase): """ - Unit tests for the remove_duplicates function. + Unit tests for the remove_duplicates_from_sorted_list function. Ensures that duplicates are removed from a sorted linked list. """ def test_empty_list(self): """It should evaluate None to None.""" - result = remove_duplicates(None) + result = remove_duplicates_from_sorted_list(None) self.assertIsNone(result) def test_single_node_value(self): """It should evaluate the value of a single-node list.""" head = ListNode(1) - result = remove_duplicates(head) - self.assertEqual(result.val, 1) + result = remove_duplicates_from_sorted_list(head) + self.assertEqual(result.value, 1) def test_single_node_next(self): """It should evaluate the next node of a single-node list as None.""" head = ListNode(1) - result = remove_duplicates(head) + result = remove_duplicates_from_sorted_list(head) self.assertIsNone(result.next) def test_duplicate_first_node(self): """It should remove duplicates at the first node.""" head = ListNode(1, ListNode(1, ListNode(2))) - result = remove_duplicates(head) - self.assertEqual(result.val, 1) + result = remove_duplicates_from_sorted_list(head) + self.assertEqual(result.value, 1) def test_duplicate_second_node(self): """It should remove duplicates at the second node.""" head = ListNode(1, ListNode(1, ListNode(2))) - result = remove_duplicates(head) - self.assertEqual(result.next.val, 2) + result = remove_duplicates_from_sorted_list(head) + self.assertEqual(result.next.value, 2) def test_duplicate_list_ends(self): - """It should evaluate the end of a list with duplicates as None.""" + """It should remove duplicates at the end of the list.""" head = ListNode(1, ListNode(1, ListNode(2, ListNode(3, ListNode(3))))) - result = remove_duplicates(head) + result = remove_duplicates_from_sorted_list(head) self.assertIsNone(result.next.next.next) def test_list_without_duplicates_first_node(self): """It should evaluate the first node of a list without duplicates.""" head = ListNode(1, ListNode(2, ListNode(3))) - result = remove_duplicates(head) - self.assertEqual(result.val, 1) + result = remove_duplicates_from_sorted_list(head) + self.assertEqual(result.value, 1) def test_list_without_duplicates_second_node(self): """It should evaluate the second node of a list without duplicates.""" head = ListNode(1, ListNode(2, ListNode(3))) - result = remove_duplicates(head) - self.assertEqual(result.next.val, 2) + result = remove_duplicates_from_sorted_list(head) + self.assertEqual(result.next.value, 2) def test_list_without_duplicates_third_node(self): """It should evaluate the third node of a list without duplicates.""" head = ListNode(1, ListNode(2, ListNode(3))) - result = remove_duplicates(head) - self.assertEqual(result.next.next.val, 3) - - def test_list_without_duplicates_end(self): - """It should evaluate the end of a list without duplicates as None.""" - head = ListNode(1, ListNode(2, ListNode(3))) - result = remove_duplicates(head) - self.assertIsNone(result.next.next.next) + result = remove_duplicates_from_sorted_list(head) + self.assertEqual(result.next.next.value, 3) def test_invalid_input(self): """It should raise an assertion error for invalid input.""" with self.assertRaises(AssertionError): - remove_duplicates("invalid_input") + remove_duplicates_from_sorted_list("invalid_input") if __name__ == "__main__": From dd005f2c5787f34bf6cafc2fddc2ab6d0fdfbbf7 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Mon, 6 Jan 2025 08:17:58 +0100 Subject: [PATCH 098/133] Update module contents --- solutions/calculate_max_profit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/calculate_max_profit.py b/solutions/calculate_max_profit.py index 3f84292de..b9242e1c7 100644 --- a/solutions/calculate_max_profit.py +++ b/solutions/calculate_max_profit.py @@ -6,7 +6,7 @@ Module Contents: - - calculate_max_profit(prices: list[int]) -> int: + - calculate_max_profit(prices: list) -> int: Computes the maximum profit that can be made by completing as many transactions as possible (buy one and sell one share of stock multiple times). From 354c04ab689392d857efcbd55435c7f6d4f9318f Mon Sep 17 00:00:00 2001 From: jola-ds Date: Mon, 6 Jan 2025 08:30:03 +0100 Subject: [PATCH 099/133] Add main entry point --- solutions/tests/test_calculate_max_profit.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/solutions/tests/test_calculate_max_profit.py b/solutions/tests/test_calculate_max_profit.py index 101990b4b..c5c7e2dcf 100644 --- a/solutions/tests/test_calculate_max_profit.py +++ b/solutions/tests/test_calculate_max_profit.py @@ -75,3 +75,7 @@ def test_non_numeric_values(self): """Raises an AssertionError for non_numeric_values.""" with self.assertRaises(AssertionError): calculate_max_profit([1.5, "2", 3]) + + +if __name__ == "__main__": + unittest.main() From 9b69d61fe246a499fb3c74764c2738c591936f86 Mon Sep 17 00:00:00 2001 From: Mojtaba Fayyaz Date: Mon, 6 Jan 2025 15:46:58 +0500 Subject: [PATCH 100/133] Reformat remove_every_other.py --- solutions/remove_every_other.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/solutions/remove_every_other.py b/solutions/remove_every_other.py index 9d1064ffa..a953fdb82 100644 --- a/solutions/remove_every_other.py +++ b/solutions/remove_every_other.py @@ -1,5 +1,3 @@ -# remove_every_other.py - """ Module: remove_every_other Author: Mojtaba Fayyaz From 97fe17b4e89108a4217e3bf088d30ad08eeb1bf3 Mon Sep 17 00:00:00 2001 From: Muhammad Shahroz Date: Mon, 6 Jan 2025 22:26:45 +0500 Subject: [PATCH 101/133] Improved comments to align with strategy-focused guidelines. Resolves #9 --- solutions/remove_duplicates_from_sorted_list.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/solutions/remove_duplicates_from_sorted_list.py b/solutions/remove_duplicates_from_sorted_list.py index 84c745233..58152c2d7 100644 --- a/solutions/remove_duplicates_from_sorted_list.py +++ b/solutions/remove_duplicates_from_sorted_list.py @@ -62,9 +62,10 @@ def remove_duplicates_from_sorted_list(head: Optional[ListNode]) -> Optional[Lis current_node = head while current_node and current_node.next: + # Traverse the list and remove consecutive duplicates by adjusting pointers. if current_node.value == current_node.next.value: - current_node.next = current_node.next.next # Remove duplicate + current_node.next = current_node.next.next # Skip the duplicate node else: - current_node = current_node.next # Move to next node + current_node = current_node.next # Move to the next unique node return head From 9435cf92be89f96ee65401ccf703856286e31545 Mon Sep 17 00:00:00 2001 From: Muhammad Shahroz Date: Mon, 6 Jan 2025 22:35:21 +0500 Subject: [PATCH 102/133] Applied black formatting and resolved pycheck failures to resolve #9 --- solutions/remove_duplicates_from_sorted_list.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/remove_duplicates_from_sorted_list.py b/solutions/remove_duplicates_from_sorted_list.py index 58152c2d7..74eef6e50 100644 --- a/solutions/remove_duplicates_from_sorted_list.py +++ b/solutions/remove_duplicates_from_sorted_list.py @@ -66,6 +66,6 @@ def remove_duplicates_from_sorted_list(head: Optional[ListNode]) -> Optional[Lis if current_node.value == current_node.next.value: current_node.next = current_node.next.next # Skip the duplicate node else: - current_node = current_node.next # Move to the next unique node + current_node = current_node.next # Move to the next unique node return head From ac0313ebcb7576b3a67b40d2e7b2c97d5fd0f6ae Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Tue, 7 Jan 2025 16:22:08 +0530 Subject: [PATCH 103/133] Add 'who_likes_it' function and its tests to resolve #61 --- solutions/tests/test_who_likes_it.py | 76 ++++++++++++++++++++++++++++ solutions/who_likes_it.py | 52 +++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 solutions/tests/test_who_likes_it.py create mode 100644 solutions/who_likes_it.py diff --git a/solutions/tests/test_who_likes_it.py b/solutions/tests/test_who_likes_it.py new file mode 100644 index 000000000..e7cd205a6 --- /dev/null +++ b/solutions/tests/test_who_likes_it.py @@ -0,0 +1,76 @@ +""" +Tests for the `who_likes_it` module + +Author: Madiha Malikzada +Date: 2025-01-06 + +This test suite verifies the correctness of the `who_likes_it` module by testing the function `who_likes_it` against various test cases. +- Different numbers of names in the input list. +- Defensive assertions for invalid inputs +- Boundary cases like empty and large lists. +""" +import unittest +from solutions.who_likes_it import who_likes_it + +class TestWhoLikesIt(unittest.TestCase): + """ + Unit tests for the `who_likes_it` function + """ + + def test_boundary_empty_list(self): + """ + Test boundary case for an empty list. + """ + self.assertEqual(who_likes_it([]), "no one likes this") + + def test_one_like(self): + """ + Test the case when one person likes the post + """ + self.assertEqual(who_likes_it(["Evan"]), "Evan likes this") + + def test_two_likes(self): + """ + Test the case when two people like the post + """ + self.assertEqual(who_likes_it(["Evan", "Madiha"]), "Evan and Madiha like this") + + def test_three_likes(self): + """ + Test the case when three people like the post + """ + self.assertEqual(who_likes_it(["Evan", "Madiha", "Megan"]), "Evan, Madiha and Megan like this") + + def test_more_than_three_likes(self): + """ + Test the case when more than three people like the post + """ + self.assertEqual(who_likes_it( + ["Evan", "Madiha", "Megan", "Camila"]), + "Evan, Madiha and 2 others like this") + + def test_invalid_input(self): + """ + Test the case when input is not a list + """ + with self.assertRaises(AssertionError): + who_likes_it("not a list") + + def test_defensive_non_string_elements(self): + """ + Test the case when input list contains non-string elements + """ + with self.assertRaises(AssertionError): + who_likes_it(["Evan", 1, "Megan"]) + + def test_boundary_large_list(self): + """ + Test boundary case for a large list. + """ + names = ["Name" + str(i) for i in range(100)] + self.assertEqual( + who_likes_it(names), + f"Name0, Name1 and {len(names) - 2} others like this") + +if __name__ == "__main__": + unittest.main() diff --git a/solutions/who_likes_it.py b/solutions/who_likes_it.py new file mode 100644 index 000000000..d3e8d5059 --- /dev/null +++ b/solutions/who_likes_it.py @@ -0,0 +1,52 @@ +""" +Module `who_likes_it` provides a function that takes a list of names and returns a string that describes how many people like a post. + +Module: who_likes_it +Author: Madiha Malikzada +Date: 2025-01-06 +""" + +from typing import List +def who_likes_it(names: List[str]) -> str: + """ + Generate a "like display message based on the input list of names + + Args: + names (List[str]): A list of names representing people who liked a an item (post) + + Returns: + str: A display message that describes how many people liked the post + + Raises: + - ValueError: If any name in the list is not a string + - The list itself is not of type `List` + + Examples: + >>> who_likes_it([]) + 'no one likes this' + >>> who_likes_it(["Evan"]) + 'Evan likes this' + >>> who_likes_it(["Evan", "Madiha"]) + 'Evan and Madiha like this' + >>> who_likes_it(["Evan", "Madiha", "Megan"]) + 'Evan, Madiha and Megan like this' + >>> who_likes_it(["Evan", "Madiha", "Megan", "Camila"]) + 'Evan, Madiha and 2 others like this' + """ + + # Defensive assertions + assert isinstance(names, List), "Input names should be of type List" + assert all(isinstance(name, str) for name in names), "All names should be of type string" + + names_length = len(names) + + if names_length == 0: + return "no one likes this" + elif names_length == 1: + return f"{names[0]} likes this" + elif names_length == 2: + return f"{names[0]} and {names[1]} like this" + elif names_length == 3: + return f"{names[0]}, {names[1]} and {names[2]} like this" + else: + return f"{names[0]}, {names[1]} and {names_length - 2} others like this" \ No newline at end of file From 2ef75998d0afc55d3226957a42d8cc22e4438cf1 Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Tue, 7 Jan 2025 16:32:59 +0530 Subject: [PATCH 104/133] Add 'who_likes_it' function and its tests to resolve #61 --- solutions/tests/test_who_likes_it.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_who_likes_it.py b/solutions/tests/test_who_likes_it.py index e7cd205a6..5120bd7b6 100644 --- a/solutions/tests/test_who_likes_it.py +++ b/solutions/tests/test_who_likes_it.py @@ -51,7 +51,7 @@ def test_more_than_three_likes(self): def test_invalid_input(self): """ - Test the case when input is not a list + Test the case when input is not a list type """ with self.assertRaises(AssertionError): who_likes_it("not a list") From 6fbc3cd5f8a1e7ce85a714da70e5f6710ae9560b Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Tue, 7 Jan 2025 17:00:16 +0530 Subject: [PATCH 105/133] Add some comments to resolve #61 --- solutions/tests/test_who_likes_it.py | 28 +++++++++++++++------------- solutions/who_likes_it.py | 9 +++++++++ 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/solutions/tests/test_who_likes_it.py b/solutions/tests/test_who_likes_it.py index 5120bd7b6..37996f4c7 100644 --- a/solutions/tests/test_who_likes_it.py +++ b/solutions/tests/test_who_likes_it.py @@ -4,43 +4,45 @@ Author: Madiha Malikzada Date: 2025-01-06 -This test suite verifies the correctness of the `who_likes_it` module by testing the function `who_likes_it` against various test cases. -- Different numbers of names in the input list. -- Defensive assertions for invalid inputs -- Boundary cases like empty and large lists. +This test suite verifies the correctness of the `who_likes_it` module by testing the function +`who_likes_it` against various test cases. + - Different numbers of names in the input list. + - Defensive assertions for invalid inputs + - Boundary cases like empty and large lists. """ -import unittest + +import unittest from solutions.who_likes_it import who_likes_it class TestWhoLikesIt(unittest.TestCase): """ Unit tests for the `who_likes_it` function """ - + def test_boundary_empty_list(self): """ Test boundary case for an empty list. """ self.assertEqual(who_likes_it([]), "no one likes this") - + def test_one_like(self): """ Test the case when one person likes the post """ self.assertEqual(who_likes_it(["Evan"]), "Evan likes this") - + def test_two_likes(self): """ Test the case when two people like the post """ self.assertEqual(who_likes_it(["Evan", "Madiha"]), "Evan and Madiha like this") - + def test_three_likes(self): """ Test the case when three people like the post """ self.assertEqual(who_likes_it(["Evan", "Madiha", "Megan"]), "Evan, Madiha and Megan like this") - + def test_more_than_three_likes(self): """ Test the case when more than three people like the post @@ -48,21 +50,21 @@ def test_more_than_three_likes(self): self.assertEqual(who_likes_it( ["Evan", "Madiha", "Megan", "Camila"]), "Evan, Madiha and 2 others like this") - + def test_invalid_input(self): """ Test the case when input is not a list type """ with self.assertRaises(AssertionError): who_likes_it("not a list") - + def test_defensive_non_string_elements(self): """ Test the case when input list contains non-string elements """ with self.assertRaises(AssertionError): who_likes_it(["Evan", 1, "Megan"]) - + def test_boundary_large_list(self): """ Test boundary case for a large list. diff --git a/solutions/who_likes_it.py b/solutions/who_likes_it.py index d3e8d5059..33be74622 100644 --- a/solutions/who_likes_it.py +++ b/solutions/who_likes_it.py @@ -7,6 +7,8 @@ """ from typing import List + +# ---- define function ---- def who_likes_it(names: List[str]) -> str: """ Generate a "like display message based on the input list of names @@ -40,13 +42,20 @@ def who_likes_it(names: List[str]) -> str: names_length = len(names) + # If the list is empty, return 'no one likes this'. if names_length == 0: return "no one likes this" + + # If the list has 1 to 3 names, format them directly in the message. elif names_length == 1: return f"{names[0]} likes this" + elif names_length == 2: return f"{names[0]} and {names[1]} like this" + elif names_length == 3: return f"{names[0]}, {names[1]} and {names[2]} like this" + + # For 4 or more names, summarize additional names as 'X others'. else: return f"{names[0]}, {names[1]} and {names_length - 2} others like this" \ No newline at end of file From b01d5822fa0aeaa09ef1d1eddb155695c18f2c2e Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Tue, 7 Jan 2025 17:03:24 +0530 Subject: [PATCH 106/133] remove spaces to pass ci checks --- solutions/who_likes_it.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/solutions/who_likes_it.py b/solutions/who_likes_it.py index 33be74622..8a22dfba3 100644 --- a/solutions/who_likes_it.py +++ b/solutions/who_likes_it.py @@ -35,27 +35,27 @@ def who_likes_it(names: List[str]) -> str: >>> who_likes_it(["Evan", "Madiha", "Megan", "Camila"]) 'Evan, Madiha and 2 others like this' """ - + # Defensive assertions assert isinstance(names, List), "Input names should be of type List" assert all(isinstance(name, str) for name in names), "All names should be of type string" names_length = len(names) - + # If the list is empty, return 'no one likes this'. if names_length == 0: return "no one likes this" - + # If the list has 1 to 3 names, format them directly in the message. elif names_length == 1: return f"{names[0]} likes this" - + elif names_length == 2: return f"{names[0]} and {names[1]} like this" - + elif names_length == 3: return f"{names[0]}, {names[1]} and {names[2]} like this" - + # For 4 or more names, summarize additional names as 'X others'. else: - return f"{names[0]}, {names[1]} and {names_length - 2} others like this" \ No newline at end of file + return f"{names[0]}, {names[1]} and {names_length - 2} others like this" From 32540e3aa4e0b5d715987850e4200edb544a6d31 Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Tue, 7 Jan 2025 17:08:07 +0530 Subject: [PATCH 107/133] remove spaces to pass ci checks --- solutions/tests/test_who_likes_it.py | 12 ++++++++---- solutions/who_likes_it.py | 3 ++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/solutions/tests/test_who_likes_it.py b/solutions/tests/test_who_likes_it.py index 37996f4c7..afc4c4629 100644 --- a/solutions/tests/test_who_likes_it.py +++ b/solutions/tests/test_who_likes_it.py @@ -4,8 +4,8 @@ Author: Madiha Malikzada Date: 2025-01-06 -This test suite verifies the correctness of the `who_likes_it` module by testing the function -`who_likes_it` against various test cases. +This test suite verifies the correctness of the `who_likes_it` module by testing the +function `who_likes_it` against various test cases. - Different numbers of names in the input list. - Defensive assertions for invalid inputs - Boundary cases like empty and large lists. @@ -35,13 +35,17 @@ def test_two_likes(self): """ Test the case when two people like the post """ - self.assertEqual(who_likes_it(["Evan", "Madiha"]), "Evan and Madiha like this") + self.assertEqual(who_likes_it( + ["Evan", "Madiha"]), + "Evan and Madiha like this") def test_three_likes(self): """ Test the case when three people like the post """ - self.assertEqual(who_likes_it(["Evan", "Madiha", "Megan"]), "Evan, Madiha and Megan like this") + self.assertEqual(who_likes_it( + ["Evan", "Madiha", "Megan"]), + "Evan, Madiha and Megan like this") def test_more_than_three_likes(self): """ diff --git a/solutions/who_likes_it.py b/solutions/who_likes_it.py index 8a22dfba3..1fa5be0a0 100644 --- a/solutions/who_likes_it.py +++ b/solutions/who_likes_it.py @@ -1,5 +1,6 @@ """ -Module `who_likes_it` provides a function that takes a list of names and returns a string that describes how many people like a post. +Module `who_likes_it` provides a function that takes a list of names and returns a +string that describes how many people like a post. Module: who_likes_it Author: Madiha Malikzada From ad4d6f9459aa89037640d197fe553aad6669d57a Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Tue, 7 Jan 2025 17:21:55 +0530 Subject: [PATCH 108/133] update the docstrings --- solutions/tests/test_who_likes_it.py | 11 +++++------ solutions/who_likes_it.py | 7 ++++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/solutions/tests/test_who_likes_it.py b/solutions/tests/test_who_likes_it.py index afc4c4629..5846dc274 100644 --- a/solutions/tests/test_who_likes_it.py +++ b/solutions/tests/test_who_likes_it.py @@ -1,14 +1,13 @@ """ -Tests for the `who_likes_it` module +Tests for the `who_likes_it` module. -Author: Madiha Malikzada -Date: 2025-01-06 - -This test suite verifies the correctness of the `who_likes_it` module by testing the -function `who_likes_it` against various test cases. +This tests the correctness of the function `who_likes_it`: - Different numbers of names in the input list. - Defensive assertions for invalid inputs - Boundary cases like empty and large lists. + +Author: Madiha Malikzada +Date: 2025-01-06 """ import unittest diff --git a/solutions/who_likes_it.py b/solutions/who_likes_it.py index 1fa5be0a0..cdc3f4e6d 100644 --- a/solutions/who_likes_it.py +++ b/solutions/who_likes_it.py @@ -1,8 +1,9 @@ """ -Module `who_likes_it` provides a function that takes a list of names and returns a -string that describes how many people like a post. +This Module provides like display message based on the input list of names. + +Module contents: + returns a string that describes how many people like a post. -Module: who_likes_it Author: Madiha Malikzada Date: 2025-01-06 """ From 667e6d0760cf77b1d3e77e94170741f3e441b12c Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Tue, 7 Jan 2025 17:31:20 +0530 Subject: [PATCH 109/133] Fix formatting issues flagged by Ruff --- solutions/who_likes_it.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/solutions/who_likes_it.py b/solutions/who_likes_it.py index cdc3f4e6d..fe7188140 100644 --- a/solutions/who_likes_it.py +++ b/solutions/who_likes_it.py @@ -1,11 +1,11 @@ """ -This Module provides like display message based on the input list of names. +This module provides a like display message based on the input list of names. -Module contents: - returns a string that describes how many people like a post. +Module contents: + Returns a string that describes how many people like a post. Author: Madiha Malikzada -Date: 2025-01-06 +Date: 2025-01-06 """ from typing import List @@ -13,10 +13,10 @@ # ---- define function ---- def who_likes_it(names: List[str]) -> str: """ - Generate a "like display message based on the input list of names + Generate a like display message based on the input list of names. Args: - names (List[str]): A list of names representing people who liked a an item (post) + names (List[str]): A list of names representing people who liked an item (post) Returns: str: A display message that describes how many people liked the post From 565da87c3047d2047b21c1857da0084b29931ea6 Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Tue, 7 Jan 2025 17:37:41 +0530 Subject: [PATCH 110/133] Fix formatting issues flagged by Ruff --- solutions/tests/test_who_likes_it.py | 20 ++++++++------------ solutions/who_likes_it.py | 9 ++++----- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/solutions/tests/test_who_likes_it.py b/solutions/tests/test_who_likes_it.py index 5846dc274..04e3596a7 100644 --- a/solutions/tests/test_who_likes_it.py +++ b/solutions/tests/test_who_likes_it.py @@ -34,25 +34,22 @@ def test_two_likes(self): """ Test the case when two people like the post """ - self.assertEqual(who_likes_it( - ["Evan", "Madiha"]), - "Evan and Madiha like this") + self.assertEqual(who_likes_it(["Evan", "Madiha"]), + "Evan and Madiha like this") def test_three_likes(self): """ Test the case when three people like the post """ - self.assertEqual(who_likes_it( - ["Evan", "Madiha", "Megan"]), - "Evan, Madiha and Megan like this") + self.assertEqual(who_likes_it(["Evan", "Madiha", "Megan"]), + "Evan, Madiha and Megan like this") def test_more_than_three_likes(self): """ Test the case when more than three people like the post """ - self.assertEqual(who_likes_it( - ["Evan", "Madiha", "Megan", "Camila"]), - "Evan, Madiha and 2 others like this") + self.assertEqual(who_likes_it(["Evan", "Madiha", "Megan", "Camila"]), + "Evan, Madiha and 2 others like this") def test_invalid_input(self): """ @@ -73,9 +70,8 @@ def test_boundary_large_list(self): Test boundary case for a large list. """ names = ["Name" + str(i) for i in range(100)] - self.assertEqual( - who_likes_it(names), - f"Name0, Name1 and {len(names) - 2} others like this") + self.assertEqual(who_likes_it(names), + f"Name0, Name1 and {len(names) - 2} others like this") if __name__ == "__main__": unittest.main() diff --git a/solutions/who_likes_it.py b/solutions/who_likes_it.py index fe7188140..d475d0fe8 100644 --- a/solutions/who_likes_it.py +++ b/solutions/who_likes_it.py @@ -49,15 +49,14 @@ def who_likes_it(names: List[str]) -> str: return "no one likes this" # If the list has 1 to 3 names, format them directly in the message. - elif names_length == 1: + if names_length == 1: return f"{names[0]} likes this" - elif names_length == 2: + if names_length == 2: return f"{names[0]} and {names[1]} like this" - elif names_length == 3: + if names_length == 3: return f"{names[0]}, {names[1]} and {names[2]} like this" # For 4 or more names, summarize additional names as 'X others'. - else: - return f"{names[0]}, {names[1]} and {names_length - 2} others like this" + return f"{names[0]}, {names[1]} and {names_length - 2} others like this" From 2ea47817863d63946ec614c23fb79e0284e549e1 Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Tue, 7 Jan 2025 17:43:08 +0530 Subject: [PATCH 111/133] Fix formatting issues flagged by Ruff --- solutions/who_likes_it.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/solutions/who_likes_it.py b/solutions/who_likes_it.py index d475d0fe8..a80dfa786 100644 --- a/solutions/who_likes_it.py +++ b/solutions/who_likes_it.py @@ -13,10 +13,10 @@ # ---- define function ---- def who_likes_it(names: List[str]) -> str: """ - Generate a like display message based on the input list of names. + Generate a "like display message based on the input list of names Args: - names (List[str]): A list of names representing people who liked an item (post) + names (List[str]): A list of names representing people who liked a an item (post) Returns: str: A display message that describes how many people liked the post @@ -49,14 +49,15 @@ def who_likes_it(names: List[str]) -> str: return "no one likes this" # If the list has 1 to 3 names, format them directly in the message. - if names_length == 1: + elif names_length == 1: return f"{names[0]} likes this" - if names_length == 2: + elif names_length == 2: return f"{names[0]} and {names[1]} like this" - if names_length == 3: + elif names_length == 3: return f"{names[0]}, {names[1]} and {names[2]} like this" # For 4 or more names, summarize additional names as 'X others'. - return f"{names[0]}, {names[1]} and {names_length - 2} others like this" + else: + return f"{names[0]}, {names[1]} and {names_length - 2} others like this" From 0f5302d235cdb082bf4959bf5bd9eedae4977692 Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Tue, 7 Jan 2025 18:19:22 +0530 Subject: [PATCH 112/133] Fix formatting issues flagged by Ruff --- solutions/tests/test_who_likes_it.py | 22 ++++++++++++++-------- solutions/who_likes_it.py | 11 +++++++---- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/solutions/tests/test_who_likes_it.py b/solutions/tests/test_who_likes_it.py index 04e3596a7..e32edd4f7 100644 --- a/solutions/tests/test_who_likes_it.py +++ b/solutions/tests/test_who_likes_it.py @@ -13,6 +13,7 @@ import unittest from solutions.who_likes_it import who_likes_it + class TestWhoLikesIt(unittest.TestCase): """ Unit tests for the `who_likes_it` function @@ -34,22 +35,25 @@ def test_two_likes(self): """ Test the case when two people like the post """ - self.assertEqual(who_likes_it(["Evan", "Madiha"]), - "Evan and Madiha like this") + self.assertEqual(who_likes_it(["Evan", "Madiha"]), "Evan and Madiha like this") def test_three_likes(self): """ Test the case when three people like the post """ - self.assertEqual(who_likes_it(["Evan", "Madiha", "Megan"]), - "Evan, Madiha and Megan like this") + self.assertEqual( + who_likes_it(["Evan", "Madiha", "Megan"]), + "Evan, Madiha and Megan like this", + ) def test_more_than_three_likes(self): """ Test the case when more than three people like the post """ - self.assertEqual(who_likes_it(["Evan", "Madiha", "Megan", "Camila"]), - "Evan, Madiha and 2 others like this") + self.assertEqual( + who_likes_it(["Evan", "Madiha", "Megan", "Camila"]), + "Evan, Madiha and 2 others like this", + ) def test_invalid_input(self): """ @@ -70,8 +74,10 @@ def test_boundary_large_list(self): Test boundary case for a large list. """ names = ["Name" + str(i) for i in range(100)] - self.assertEqual(who_likes_it(names), - f"Name0, Name1 and {len(names) - 2} others like this") + self.assertEqual( + who_likes_it(names), f"Name0, Name1 and {len(names) - 2} others like this" + ) + if __name__ == "__main__": unittest.main() diff --git a/solutions/who_likes_it.py b/solutions/who_likes_it.py index a80dfa786..f4429ce48 100644 --- a/solutions/who_likes_it.py +++ b/solutions/who_likes_it.py @@ -10,21 +10,22 @@ from typing import List + # ---- define function ---- def who_likes_it(names: List[str]) -> str: """ - Generate a "like display message based on the input list of names + Generate a "like display message based on the input list of names Args: names (List[str]): A list of names representing people who liked a an item (post) Returns: str: A display message that describes how many people liked the post - + Raises: - ValueError: If any name in the list is not a string - The list itself is not of type `List` - + Examples: >>> who_likes_it([]) 'no one likes this' @@ -40,7 +41,9 @@ def who_likes_it(names: List[str]) -> str: # Defensive assertions assert isinstance(names, List), "Input names should be of type List" - assert all(isinstance(name, str) for name in names), "All names should be of type string" + assert all( + isinstance(name, str) for name in names + ), "All names should be of type string" names_length = len(names) From 01ff5876f0f9fe6680868f2883d54254db332473 Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Tue, 7 Jan 2025 21:50:25 +0530 Subject: [PATCH 113/133] updated doctest --- solutions/who_likes_it.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/solutions/who_likes_it.py b/solutions/who_likes_it.py index f4429ce48..fd8e79e29 100644 --- a/solutions/who_likes_it.py +++ b/solutions/who_likes_it.py @@ -23,7 +23,7 @@ def who_likes_it(names: List[str]) -> str: str: A display message that describes how many people liked the post Raises: - - ValueError: If any name in the list is not a string + - AssertionError: If any name in the list is not a string - The list itself is not of type `List` Examples: @@ -64,3 +64,6 @@ def who_likes_it(names: List[str]) -> str: # For 4 or more names, summarize additional names as 'X others'. else: return f"{names[0]}, {names[1]} and {names_length - 2} others like this" + + +print(who_likes_it(["Evan", "Madiha", 8])) From e33d97a0734e0615e605a4ed668d4152123db239 Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Tue, 7 Jan 2025 21:52:39 +0530 Subject: [PATCH 114/133] updated doctest --- solutions/who_likes_it.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/solutions/who_likes_it.py b/solutions/who_likes_it.py index fd8e79e29..ad9779861 100644 --- a/solutions/who_likes_it.py +++ b/solutions/who_likes_it.py @@ -64,6 +64,3 @@ def who_likes_it(names: List[str]) -> str: # For 4 or more names, summarize additional names as 'X others'. else: return f"{names[0]}, {names[1]} and {names_length - 2} others like this" - - -print(who_likes_it(["Evan", "Madiha", 8])) From 2bbe6140a7e3b6dd14a9144d62c03fcf785eedf4 Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Tue, 7 Jan 2025 22:57:02 +0500 Subject: [PATCH 115/133] Added modules at the top --- solutions/count_vowels.py | 39 ++++++---------------------- solutions/tests/test_count_vowels.py | 16 +++++++++++- 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/solutions/count_vowels.py b/solutions/count_vowels.py index e12281c47..ceeae25b2 100644 --- a/solutions/count_vowels.py +++ b/solutions/count_vowels.py @@ -1,26 +1,22 @@ """ -Write a function count_vowels(s) that returns the number of vowels in a given string. +A module for counting vowels in a string. -Examples -count_vowels("hello") should return 2. -count_vowels("sky") should return 0. -count_vowels("AEIOU") should return 5. -Behavior -The function should: +Module contents: + - count_vowels: Counts the number of vowels in a given string. + It supports both uppercase and lowercase vowels. -Take a single string s as input. -Identify and count the vowels (both uppercase and lowercase) in the string. -Return the total count of vowels as an integer. +Created on: 2025-07-06 +@author: Fatima """ - def count_vowels(text: str) -> int: """Count the number of vowels (a,e,i,o,u) in a string. Parameters: text: str, the input string to check - Returns -> int: number of vowels in the text + Returns: + int: Number of vowels in the text. Raises: AssertionError: if the argument is not a string @@ -39,22 +35,3 @@ def count_vowels(text: str) -> int: if letter in vowels: count += 1 return count - - -# call the function -# print(count_vowels("hello")) -# print(count_vowels("fly")) -# print(count_vowels("AEIOU")) -# print(count_vowels("")) -# print(count_vowels("high")) -# print(count_vowels("hellO World")) - -# if vowels== "": -# return 0 -# if vowels== "aeiouAEIOU": -# return 5 -# if vowels== "fly": -# return 0 -# if vowels== "hellO World": -# return 3 -# return 0 diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index 404d33c6e..c7919e753 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -1,4 +1,18 @@ -"""Unit tests for the count_vowels function.""" +""" +Unit tests for checking the correctnes of the count_vowels function. + +Test cases include: + - Empty string + - Strings with no vowels + - Strings containing only vowels + - Mixed-case vowel counting + - Alphanumeric strings + - Strings with special characters and whitespace + - Handling of invalid (non-string) input + +Created on: 2025-07-06 +@author: Fatima +""" import unittest from solutions.count_vowels import count_vowels From c4312b3a5a978035b5222d8bc2b75965d995da96 Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Tue, 7 Jan 2025 23:11:06 +0500 Subject: [PATCH 116/133] Fixed Ruff formatting --- solutions/count_vowels.py | 1 + 1 file changed, 1 insertion(+) diff --git a/solutions/count_vowels.py b/solutions/count_vowels.py index ceeae25b2..ee96eb134 100644 --- a/solutions/count_vowels.py +++ b/solutions/count_vowels.py @@ -9,6 +9,7 @@ @author: Fatima """ + def count_vowels(text: str) -> int: """Count the number of vowels (a,e,i,o,u) in a string. From 23e7ebd867a67882844dd54a1b0e9c750639862e Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Thu, 9 Jan 2025 10:45:23 +0500 Subject: [PATCH 117/133] Improved module docstring --- solutions/tests/test_count_vowels.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index c7919e753..25c53dc31 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -1,14 +1,11 @@ """ -Unit tests for checking the correctnes of the count_vowels function. - -Test cases include: - - Empty string - - Strings with no vowels - - Strings containing only vowels - - Mixed-case vowel counting - - Alphanumeric strings - - Strings with special characters and whitespace - - Handling of invalid (non-string) input +Unit tests for validating the count_vowels function. + +Test Categories: + - Standard Cases: Regular words with varying vowel counts. + - Edge Cases: Empty strings, repeated vowels, and mixed casing. + - Special Cases: Strings with numbers, special characters, and whitespace. + - Defensive Cases: Ensuring proper handling of non-string inputs. Created on: 2025-07-06 @author: Fatima From 7f4cc52933cc4c870f0b2b8bbb9ee13efe36142a Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Thu, 9 Jan 2025 11:11:16 +0500 Subject: [PATCH 118/133] Rearranged test cases for better organization --- solutions/tests/test_count_vowels.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index 25c53dc31..5a2f29d24 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -18,18 +18,15 @@ class TestCountVowels(unittest.TestCase): """Test cases for count_vowels function.""" - def test_empty_string(self): - """It should return 0 for an empty string.""" - self.assertEqual(count_vowels(""), 0) - + # Standard Cases def test_no_vowels(self): """It should return 0 for a string with no vowels.""" self.assertEqual(count_vowels("fly"), 0) - + def test_all_vowels(self): """It should handle all uppercase and lowercase vowels.""" self.assertEqual(count_vowels("aeiouAEIOU"), 10) - + def test_uppercase_vowels(self): """It should count uppercase vowels in the string.""" self.assertEqual(count_vowels("SMALL"), 1) @@ -37,6 +34,11 @@ def test_uppercase_vowels(self): def test_lowercase_vowels(self): """It should count lowercase vowels in the string.""" self.assertEqual(count_vowels("small"), 1) + + # Edge Cases + def test_empty_string(self): + """It should return 0 for an empty string.""" + self.assertEqual(count_vowels(""), 0) def test_mixed_case_vowels(self): """It should count both uppercase and lowercase vowels in a string.""" @@ -45,7 +47,8 @@ def test_mixed_case_vowels(self): def test_repeated_vowels(self): """It should count all repeated vowels in a string.""" self.assertEqual(count_vowels("aaeeiioouuAAEEIIOOUU"), 20) - + + # Special Cases def test_alphanumeric_string(self): """It should count vowels in alphanumeric strings, ignoring digits.""" self.assertEqual(count_vowels("fatima123Malik"), 5) @@ -58,6 +61,7 @@ def test_string_with_whitespace(self): """It should count vowels even if the string contains spaces.""" self.assertEqual(count_vowels("hello world"), 3) + # Defensive Cases def test_invalid_input(self): """Test that raises assertion error for non-string input.""" with self.assertRaises(AssertionError): From 115ea945492ccf5bd0574bb52865560090b2af16 Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Thu, 9 Jan 2025 11:43:58 +0500 Subject: [PATCH 119/133] Fix code formatting in test_count_vowels.py using Ruff --- solutions/tests/test_count_vowels.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index 5a2f29d24..3e5993d26 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -22,11 +22,11 @@ class TestCountVowels(unittest.TestCase): def test_no_vowels(self): """It should return 0 for a string with no vowels.""" self.assertEqual(count_vowels("fly"), 0) - + def test_all_vowels(self): """It should handle all uppercase and lowercase vowels.""" self.assertEqual(count_vowels("aeiouAEIOU"), 10) - + def test_uppercase_vowels(self): """It should count uppercase vowels in the string.""" self.assertEqual(count_vowels("SMALL"), 1) @@ -34,8 +34,8 @@ def test_uppercase_vowels(self): def test_lowercase_vowels(self): """It should count lowercase vowels in the string.""" self.assertEqual(count_vowels("small"), 1) - - # Edge Cases + + # Edge Cases def test_empty_string(self): """It should return 0 for an empty string.""" self.assertEqual(count_vowels(""), 0) @@ -47,7 +47,7 @@ def test_mixed_case_vowels(self): def test_repeated_vowels(self): """It should count all repeated vowels in a string.""" self.assertEqual(count_vowels("aaeeiioouuAAEEIIOOUU"), 20) - + # Special Cases def test_alphanumeric_string(self): """It should count vowels in alphanumeric strings, ignoring digits.""" From 7209583c90b1126801827d14169a91b53f3820f2 Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Thu, 9 Jan 2025 12:16:54 +0500 Subject: [PATCH 120/133] Added proper spacing using ruff formatting --- solutions/count_vowels.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/solutions/count_vowels.py b/solutions/count_vowels.py index ee96eb134..bc3601975 100644 --- a/solutions/count_vowels.py +++ b/solutions/count_vowels.py @@ -29,10 +29,14 @@ def count_vowels(text: str) -> int: >>> count_vowels("why") 0 """ + assert isinstance(text, str), "input must be a string" + vowels = "aeiouAEIOU" count = 0 + for letter in text: if letter in vowels: count += 1 + return count From 63d1a3cbdfc3c978c4093c2f9cb9a427a9a019c7 Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Thu, 9 Jan 2025 12:40:51 +0500 Subject: [PATCH 121/133] Improved function's docstring in count_vowels.py --- solutions/count_vowels.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/count_vowels.py b/solutions/count_vowels.py index bc3601975..510743f5d 100644 --- a/solutions/count_vowels.py +++ b/solutions/count_vowels.py @@ -11,7 +11,7 @@ def count_vowels(text: str) -> int: - """Count the number of vowels (a,e,i,o,u) in a string. + """Returns the number of vowels (both uppercase and lowercase) in a string. Parameters: text: str, the input string to check From afd5788c2675b9ae3523404c04d765480b59c6b7 Mon Sep 17 00:00:00 2001 From: Mojtaba Fayyaz Date: Thu, 9 Jan 2025 17:13:17 +0500 Subject: [PATCH 122/133] Update Communication.md --- collaboration/communication.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collaboration/communication.md b/collaboration/communication.md index 305c98256..1fa6c35f4 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -46,13 +46,14 @@ use WhatsApp. | **Madiha** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | **Fatima** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | **Shahroz**| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| **Mojtaba**| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ### Hours Available Per Day - **Fatima**: _5h_ - **Madiha**: _5h_ - **M Shahroz**: _4h_ -- **Member 4**: _4h_ +- **Mojtaba**: _5h_ - **Member 5**: _3h_ --- From 3cff4938a02b8ea12503b1e39252dd1c022e0f80 Mon Sep 17 00:00:00 2001 From: Mojtaba Fayyaz Date: Thu, 9 Jan 2025 17:53:44 +0500 Subject: [PATCH 123/133] Update availability in communication.md --- collaboration/communication.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collaboration/communication.md b/collaboration/communication.md index 1fa6c35f4..3de37dc91 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -47,6 +47,7 @@ use WhatsApp. | **Fatima** | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | **Shahroz**| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | **Mojtaba**| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +|**Mudassra**| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ### Hours Available Per Day @@ -54,7 +55,7 @@ use WhatsApp. - **Madiha**: _5h_ - **M Shahroz**: _4h_ - **Mojtaba**: _5h_ -- **Member 5**: _3h_ +- **Mudassra**: _5h_ --- From 183e1753b8d19ee578ce2d61490a269e2edf5ca7 Mon Sep 17 00:00:00 2001 From: Anwar Safdari Date: Thu, 9 Jan 2025 10:20:04 -0500 Subject: [PATCH 124/133] Add files via upload New Challenge: Find All Unique Triplets That Sum to Zero Write a function that finds all unique triplets in an array that sum up to zero. The function should return the triplets without duplicates. --- solutions/three_sum.py | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 solutions/three_sum.py diff --git a/solutions/three_sum.py b/solutions/three_sum.py new file mode 100644 index 000000000..bcdd14dfc --- /dev/null +++ b/solutions/three_sum.py @@ -0,0 +1,45 @@ +def three_sum(nums): + """ + Find all unique triplets in the array that sum up to zero. + + Parameters: + nums (List[int]): The input list of integers. + + Returns: + List[List[int]]: A list of unique triplets that sum to zero. + + Examples: + >>> three_sum([-1, 0, 1, 2, -1, -4]) + [[-1, -1, 2], [-1, 0, 1]] + >>> three_sum([0, 1, 1]) + [] + >>> three_sum([0, 0, 0]) + [[0, 0, 0]] + """ + nums.sort() # Sort the array + result = [] + + for i in range(len(nums) - 2): + # Skip duplicate elements + if i > 0 and nums[i] == nums[i - 1]: + continue + + left, right = i + 1, len(nums) - 1 + while left < right: + total = nums[i] + nums[left] + nums[right] + + if total == 0: + result.append([nums[i], nums[left], nums[right]]) + left += 1 + right -= 1 + # Skip duplicates for left and right pointers + while left < right and nums[left] == nums[left - 1]: + left += 1 + while left < right and nums[right] == nums[right + 1]: + right -= 1 + elif total < 0: + left += 1 + else: + right -= 1 + + return result From 2e65e255e7e22368d3ca9d0d13491aa4cb5663a9 Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Thu, 9 Jan 2025 21:07:48 +0500 Subject: [PATCH 125/133] Added basic test case --- solutions/tests/test_count_vowels.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index 3e5993d26..eab15f8f2 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -19,6 +19,10 @@ class TestCountVowels(unittest.TestCase): """Test cases for count_vowels function.""" # Standard Cases + def test_typical_word(self): + """It should count vowels in a regular word with both vowels and consonants.""" + self.assertEqual(count_vowels("hello"), 2) + def test_no_vowels(self): """It should return 0 for a string with no vowels.""" self.assertEqual(count_vowels("fly"), 0) From 993e24f0dbe30d1bf55ac5645cd2a7634959f6a4 Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Fri, 10 Jan 2025 13:04:14 +0500 Subject: [PATCH 126/133] Added test for only whitespace --- solutions/tests/test_count_vowels.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index eab15f8f2..0d98c8bb4 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -43,6 +43,10 @@ def test_lowercase_vowels(self): def test_empty_string(self): """It should return 0 for an empty string.""" self.assertEqual(count_vowels(""), 0) + + def test_only_whitespace(self): + """It should return 0 for strings with only whitespace.""" + self.assertEqual(count_vowels(" "), 0) def test_mixed_case_vowels(self): """It should count both uppercase and lowercase vowels in a string.""" From 2795e7c63647a745d692f49b6ab0fbd026a229ee Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Fri, 10 Jan 2025 13:10:28 +0500 Subject: [PATCH 127/133] Reformat by new version of Ruff --- solutions/tests/test_count_vowels.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index 0d98c8bb4..ed9ebc28e 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -43,9 +43,9 @@ def test_lowercase_vowels(self): def test_empty_string(self): """It should return 0 for an empty string.""" self.assertEqual(count_vowels(""), 0) - + def test_only_whitespace(self): - """It should return 0 for strings with only whitespace.""" + """It should return 0 for strings with only wtesthitespace.""" self.assertEqual(count_vowels(" "), 0) def test_mixed_case_vowels(self): From fe7514c0ba83ef4bfba162ddd3c5125effa4ed02 Mon Sep 17 00:00:00 2001 From: jola-ds Date: Fri, 10 Jan 2025 09:21:05 +0100 Subject: [PATCH 128/133] Reforamt with ruff update --- solutions/calculate_max_profit.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/solutions/calculate_max_profit.py b/solutions/calculate_max_profit.py index b9242e1c7..783a6a412 100644 --- a/solutions/calculate_max_profit.py +++ b/solutions/calculate_max_profit.py @@ -41,12 +41,12 @@ def calculate_max_profit(prices: list) -> int: """ assert isinstance(prices, list), "Input should be a list." - assert all( - isinstance(price, (int, float)) for price in prices - ), "Prices should be integers or floats." - assert all( - price >= 0 for price in prices - ), "Prices should be non-negative integers or floats." + assert all(isinstance(price, (int, float)) for price in prices), ( + "Prices should be integers or floats." + ) + assert all(price >= 0 for price in prices), ( + "Prices should be non-negative integers or floats." + ) maximum_profit = 0 From 41ca46954b73a99243889e6cf1769a5bd60ccbe3 Mon Sep 17 00:00:00 2001 From: Madiha Malikzada Date: Fri, 10 Jan 2025 13:56:44 +0530 Subject: [PATCH 129/133] reformat after ruff new version --- solutions/who_likes_it.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solutions/who_likes_it.py b/solutions/who_likes_it.py index ad9779861..95d7a9249 100644 --- a/solutions/who_likes_it.py +++ b/solutions/who_likes_it.py @@ -41,9 +41,9 @@ def who_likes_it(names: List[str]) -> str: # Defensive assertions assert isinstance(names, List), "Input names should be of type List" - assert all( - isinstance(name, str) for name in names - ), "All names should be of type string" + assert all(isinstance(name, str) for name in names), ( + "All names should be of type string" + ) names_length = len(names) From 4f579cf2a3534b92549ef3b353320ccfec994b87 Mon Sep 17 00:00:00 2001 From: Muhammad Shahroz Date: Fri, 10 Jan 2025 15:21:36 +0500 Subject: [PATCH 130/133] Fix formatting for remove_duplicates_from_sorted_list.py with updated Ruff version --- solutions/remove_duplicates_from_sorted_list.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solutions/remove_duplicates_from_sorted_list.py b/solutions/remove_duplicates_from_sorted_list.py index 74eef6e50..e0a165983 100644 --- a/solutions/remove_duplicates_from_sorted_list.py +++ b/solutions/remove_duplicates_from_sorted_list.py @@ -56,9 +56,9 @@ def remove_duplicates_from_sorted_list(head: Optional[ListNode]) -> Optional[Lis # result is now a list with values: [1, 2] """ # Defensive Assertion - assert head is None or isinstance( - head, ListNode - ), "Input must be a ListNode or None." + assert head is None or isinstance(head, ListNode), ( + "Input must be a ListNode or None." + ) current_node = head while current_node and current_node.next: From 3712ef25c983153b336021151d7b0d51c53557a9 Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Fri, 10 Jan 2025 16:38:23 +0500 Subject: [PATCH 131/133] Added test for very long strings --- solutions/tests/test_count_vowels.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index ed9ebc28e..d99b3ff92 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -45,7 +45,7 @@ def test_empty_string(self): self.assertEqual(count_vowels(""), 0) def test_only_whitespace(self): - """It should return 0 for strings with only wtesthitespace.""" + """It should return 0 for strings with only whitespace..""" self.assertEqual(count_vowels(" "), 0) def test_mixed_case_vowels(self): @@ -56,6 +56,11 @@ def test_repeated_vowels(self): """It should count all repeated vowels in a string.""" self.assertEqual(count_vowels("aaeeiioouuAAEEIIOOUU"), 20) + def test_long_string(self): + """It should correctly count vowels in a long mixed-case string.""" + text = ("aAeEiIoOuU" * 500) + "bcdfghjklmnpqrstvwxyz" * 100 + self.assertEqual(count_vowels(text), 5000) + # Special Cases def test_alphanumeric_string(self): """It should count vowels in alphanumeric strings, ignoring digits.""" From 96355b159085ba00cbf6a3afbf0cc4a42666d07c Mon Sep 17 00:00:00 2001 From: fatima-malik99 <7223fatimamalik@gmail.com> Date: Fri, 10 Jan 2025 17:12:30 +0500 Subject: [PATCH 132/133] Rearraged tests in test_count_vowels.py --- solutions/tests/test_count_vowels.py | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index d99b3ff92..52f765e30 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -23,13 +23,9 @@ def test_typical_word(self): """It should count vowels in a regular word with both vowels and consonants.""" self.assertEqual(count_vowels("hello"), 2) - def test_no_vowels(self): - """It should return 0 for a string with no vowels.""" - self.assertEqual(count_vowels("fly"), 0) - - def test_all_vowels(self): - """It should handle all uppercase and lowercase vowels.""" - self.assertEqual(count_vowels("aeiouAEIOU"), 10) + def test_mixed_case_vowels(self): + """It should count both uppercase and lowercase vowels in a string.""" + self.assertEqual(count_vowels("hellOWorld"), 3) def test_uppercase_vowels(self): """It should count uppercase vowels in the string.""" @@ -39,6 +35,10 @@ def test_lowercase_vowels(self): """It should count lowercase vowels in the string.""" self.assertEqual(count_vowels("small"), 1) + def test_repeated_vowels(self): + """It should count all repeated vowels in a string.""" + self.assertEqual(count_vowels("aaeeiioouuAAEEIIOOUU"), 20) + # Edge Cases def test_empty_string(self): """It should return 0 for an empty string.""" @@ -48,13 +48,9 @@ def test_only_whitespace(self): """It should return 0 for strings with only whitespace..""" self.assertEqual(count_vowels(" "), 0) - def test_mixed_case_vowels(self): - """It should count both uppercase and lowercase vowels in a string.""" - self.assertEqual(count_vowels("hellOWorld"), 3) - - def test_repeated_vowels(self): - """It should count all repeated vowels in a string.""" - self.assertEqual(count_vowels("aaeeiioouuAAEEIIOOUU"), 20) + def test_no_vowels(self): + """It should return 0 for a string with no vowels.""" + self.assertEqual(count_vowels("fly"), 0) def test_long_string(self): """It should correctly count vowels in a long mixed-case string.""" From b40b1201baf5df395fd6e074ca194b667fd95c31 Mon Sep 17 00:00:00 2001 From: Anwar Safdari Date: Sun, 12 Jan 2025 11:52:51 -0500 Subject: [PATCH 133/133] Add files via upload --- solutions/tests/test_three_sum.py | 53 +++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 solutions/tests/test_three_sum.py diff --git a/solutions/tests/test_three_sum.py b/solutions/tests/test_three_sum.py new file mode 100644 index 000000000..39e437199 --- /dev/null +++ b/solutions/tests/test_three_sum.py @@ -0,0 +1,53 @@ +import unittest + +from solutions.three_sum import three_sum + + +class TestThreeSum(unittest.TestCase): + """Test cases for the three_sum function.""" + + def test_example_case(self): + """It should find all unique triplets that sum to zero.""" + nums = [-1, 0, 1, 2, -1, -4] + expected = [[-1, -1, 2], [-1, 0, 1]] + self.assertEqual(sorted(three_sum(nums)), sorted(expected)) + + def test_no_triplets(self): + """It should return an empty list when no triplets exist.""" + nums = [0, 1, 1] + expected = [] + self.assertEqual(three_sum(nums), expected) + + def test_all_zeros(self): + """It should handle cases with all elements being zero.""" + nums = [0, 0, 0] + expected = [[0, 0, 0]] + self.assertEqual(three_sum(nums), expected) + + def test_empty_list(self): + """It should return an empty list for an empty input list.""" + nums = [] + expected = [] + self.assertEqual(three_sum(nums), expected) + + def test_fewer_than_three_elements(self): + """It should return an empty list if fewer than three elements are provided.""" + nums = [1, -1] + expected = [] + self.assertEqual(three_sum(nums), expected) + + def test_duplicates_in_triplets(self): + """It should avoid duplicate triplets in the result.""" + nums = [-2, 0, 0, 2, 2] + expected = [[-2, 0, 2]] + self.assertEqual(sorted(three_sum(nums)), sorted(expected)) + + def test_large_negative_and_positive_numbers(self): + """It should handle large positive and negative numbers.""" + nums = [-(10**6), 0, 10**6, -1, 1] + expected = [[-(10**6), 0, 10**6], [-1, 0, 1]] + self.assertEqual(sorted(three_sum(nums)), sorted(expected)) + + +if __name__ == "__main__": + unittest.main()