From 841f0aa1a12e318a96d35fe98bd68f079907e9f9 Mon Sep 17 00:00:00 2001 From: Aziz Date: Sun, 22 Dec 2024 21:41:53 +0200 Subject: [PATCH 001/175] Update communication.md --- collaboration/communication.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/collaboration/communication.md b/collaboration/communication.md index 484652e0f..8845be324 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -13,8 +13,9 @@ ______________________________________________________________________ ## Communication Schedule -| Day | How | The topic of discussion | | --- | :-: | ----------------------- | -| | | | +| Day | How | The topic of discussion | +|:-----|:---:|:-------------------------:| +| | | | ## Communication Channels @@ -31,9 +32,9 @@ ______________________________________________________________________ ### Availability for calling/messaging -| Day | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday | | ------- | :----: | :-----: | :-------: | :------: | :----: | :------: | :----: | -| _name_ | | | | | | | | +| Day | Monday | Tuesday | Wednesday | Thursday | Friday |Saturday | Sunday| +|-----------|:------:|:-------:|:---------:|:--------:|:------:|:--------:|:------:| +| _name_ |Az. Azizi|Az. Azizi|Az. Azizi|Az. Azizi|Az. Azizi|Az. Azizi|Az. Azizi| ### How many hours everyone has per day From 76b757cf41dbbe6ed505b2cb94a256ecaa2039ee Mon Sep 17 00:00:00 2001 From: Aziz Date: Thu, 26 Dec 2024 17:52:08 +0200 Subject: [PATCH 002/175] Update learning_goals.md --- collaboration/learning_goals.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 11c583d2b..e094613ef 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -3,3 +3,16 @@ ## Collective ## Individual + +### Aziz Azizi ([Gmail](mailto:aziztablo.aa@gmail.com)) + +* Improve Coding Skills, enhance proficiency in Python programming languages. + +* Enhance Problem-Solving, improve problem-solving abilities by practicing coding +challenges. + +* Enhance communication, teamwork, and project management skills for better +collaboration with peers. + +* Improve Documentation, focus on writing clear and comprehensive documentation +for my code and projects. From ce13e0c0ae6b4fca3f78d74ab10bb585642db8ed Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Fri, 27 Dec 2024 00:52:18 +0200 Subject: [PATCH 003/175] Update README.md --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index e69de29bb..952721ee6 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,23 @@ +# 404s -Turning Errors Into Excellence +**🌟 Welcome to the 404s Repository – Where We Celebrate Every Step of the Journey, Even the "404" Moments! 🌟** + +At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey with a strong + +focus on **teamwork**, **collaboration**, and **creativity**. +Each 404 error is a chance to grow, learn, and innovate. + +We’re here to ensure that no problem is ever lost! + +## 🎯 Our Objective + + +Our goal is to foster a space for innovation and learning by: + +**Collaborating** across diverse skill sets to unlock new possibilities. + +**Embracing challenges** and transforming them into learning opportunities. + +**Developing efficient**, **creative solutions** that address real-world problems. + + +Every detour is a chance for discovery, and every 404 is an invitation to innovate. From 4b08af52ca7758650f6bc6cbbf6ddd6960df775a Mon Sep 17 00:00:00 2001 From: Aziz Azizi Date: Tue, 31 Dec 2024 10:15:46 +0200 Subject: [PATCH 004/175] Update communication.md --- collaboration/communication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collaboration/communication.md b/collaboration/communication.md index 8845be324..10510f0e0 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -34,7 +34,7 @@ ______________________________________________________________________ | Day | Monday | Tuesday | Wednesday | Thursday | Friday |Saturday | Sunday| |-----------|:------:|:-------:|:---------:|:--------:|:------:|:--------:|:------:| -| _name_ |Az. Azizi|Az. Azizi|Az. Azizi|Az. Azizi|Az. Azizi|Az. Azizi|Az. Azizi| +| _name_ |||||||| ### How many hours everyone has per day From c6d6e5f9fa5ecbbe4074987ecbca38359db917fc Mon Sep 17 00:00:00 2001 From: Aziz Azizi Date: Tue, 31 Dec 2024 10:16:04 +0200 Subject: [PATCH 005/175] Update learning_goals.md --- collaboration/learning_goals.md | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index e094613ef..11c583d2b 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -3,16 +3,3 @@ ## Collective ## Individual - -### Aziz Azizi ([Gmail](mailto:aziztablo.aa@gmail.com)) - -* Improve Coding Skills, enhance proficiency in Python programming languages. - -* Enhance Problem-Solving, improve problem-solving abilities by practicing coding -challenges. - -* Enhance communication, teamwork, and project management skills for better -collaboration with peers. - -* Improve Documentation, focus on writing clear and comprehensive documentation -for my code and projects. From 5cf4aacd5b3228ae0a34ee86c52b2fd63c5f2947 Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Tue, 31 Dec 2024 10:43:36 +0200 Subject: [PATCH 006/175] Add 404s Norms --- collaboration/README.md | 69 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/collaboration/README.md b/collaboration/README.md index 20889b951..6270b5e35 100644 --- a/collaboration/README.md +++ b/collaboration/README.md @@ -1,5 +1,74 @@ # Collaboration +## 404s Norms Summary + +> In 404s, we believe in collaboration as our main goal +> and a way to achieve things as well. + +## 404s Norms list + +### Team work + +#### Clear Communication + +> **Share updates and challenges with the group.**\ +> **Use easy tools for async communication.**\ +> **Be mindful of everyone's working hours in our international team.** + +#### Collaborate, Don’t Compete + +> **Offer help when needed, share resources, and brainstorm together.**\ +> **Celebrate success by acknowledging everyone’s contributions.** + +#### Respect Diverse Skill Levels + +> **Try to help explain concepts for other team members.**\ +> **Offer constructive feedback when reviewing solutions.** + +#### Respect the Group's Decisions + +> **Ensure that decisions are made collectively and that everyone's voice is heard.**\ +> **Stick to agreed-upon strategies, tools, and workflows to ensure consistency.** + +#### Document and Share Knowledge + +> **Keep Notes in a shared place** +--- + +### Self-Development + +#### Focus on Growth + +> **Encourage Exploration new techniques that help improve your skills**\ +> **Learn From Mistakes** + +#### Adapt to Change + +> **Be Flexible in new challenges, changes in direction, or adjusting deadlines**\ +> **Adapt to Team Dynamics and be open for new changes in tools or strategies** +--- + +### Resource Development + +#### Efficient Use of Time + +> **Time Management with agreed-on tools to keep things organized and planned ahead**\ +> **Avoid Procrastination by sticking to deadlines as possible as we can** + +#### Efficient Effort + +> **Work smart, not hard.** + +--- + +### Quality Assurance + +#### Maintain Code Quality + +> **Review others’ code for quality and clarity and offer suggestions for improvement**\ +> **Use Best Practices by following standard coding conventions** + +--- From f3567aa5b02fd8bba56935cfa1a79ba50a5c7b10 Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Tue, 31 Dec 2024 17:55:40 +0200 Subject: [PATCH 007/175] Update README.md --- README.md | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 952721ee6..25ea82f2d 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,24 @@ -# 404s -Turning Errors Into Excellence -**🌟 Welcome to the 404s Repository – Where We Celebrate Every Step of the Journey, Even the "404" Moments! 🌟** -At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey with a strong + # 404s -Turning Errors Into Excellence -focus on **teamwork**, **collaboration**, and **creativity**. -Each 404 error is a chance to grow, learn, and innovate. - -We’re here to ensure that no problem is ever lost! + + ## 🌟 Welcome to the 404s Repository – Where We Celebrate Every Step of the Journey, + **Even the "404" Moments!🌟** -## 🎯 Our Objective +At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey +with a strong focus on **teamwork**, **collaboration**, and **creativity**. +Each 404 error is a chance to grow, learn, and innovate. -Our goal is to foster a space for innovation and learning by: +We’re here to ensure that no problem is ever lost! -**Collaborating** across diverse skill sets to unlock new possibilities. +### 🎯 Our Objective -**Embracing challenges** and transforming them into learning opportunities. +Our goal is to foster a space for innovation and learning by: -**Developing efficient**, **creative solutions** that address real-world problems. +- **Collaborating** across diverse skill sets to unlock new possibilities. +- **Embracing challenges** and transforming them into learning opportunities. +- **Developing efficient**, **creative solutions** that address real-world problems. Every detour is a chance for discovery, and every 404 is an invitation to innovate. From 14fc197f8c984139f2cbe60ec44dd48f20abb23b Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Tue, 31 Dec 2024 20:49:37 +0200 Subject: [PATCH 008/175] Update README.md --- README.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 25ea82f2d..3bd7316e0 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ - # 404s -Turning Errors Into Excellence +# 404s - Turning Errors Into Excellence - - ## 🌟 Welcome to the 404s Repository – Where We Celebrate Every Step of the Journey, - **Even the "404" Moments!🌟** +## 🌟 Welcome to the 404s Repository – Where We Celebrate Every Step of the Journey, +**Even the "404" Moments!🌟** At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey with a strong focus on **teamwork**, **collaboration**, and **creativity**. @@ -12,13 +11,18 @@ Each 404 error is a chance to grow, learn, and innovate. We’re here to ensure that no problem is ever lost! +--- + ### 🎯 Our Objective Our goal is to foster a space for innovation and learning by: -- **Collaborating** across diverse skill sets to unlock new possibilities. -- **Embracing challenges** and transforming them into learning opportunities. -- **Developing efficient**, **creative solutions** that address real-world problems. +#### - **Collaborating** across diverse skill sets to unlock new possibilities. +#### - **Embracing challenges** and transforming them into learning opportunities. +#### - **Developing efficient**, **creative solutions** that address real-world problems. + +--- +### πŸ’‘ Innovation through Collaboration Every detour is a chance for discovery, and every 404 is an invitation to innovate. From 3a04f8acd5a2aee869bec5f12e95af50c098d36d Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Tue, 31 Dec 2024 20:16:10 +0100 Subject: [PATCH 009/175] Update README.md I made a clearer conclusion --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3bd7316e0..df289a047 100644 --- a/README.md +++ b/README.md @@ -25,4 +25,11 @@ Our goal is to foster a space for innovation and learning by: ### πŸ’‘ Innovation through Collaboration -Every detour is a chance for discovery, and every 404 is an invitation to innovate. +Every detour is a chance for discovery, and every 404 is an invitation to innovate. + +By leveraging our diverse skills, we create a culture where: + +- **Ideas Flow Freely**: Open discussions lead to unexpected solutions. +- **Feedback Loops**: Continuous feedback helps refine our approaches. + +Together, we transform challenges into opportunities for growth and excellence! From 8c46c4db1e87d716579f496fafff442f6b21fc0d Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Tue, 31 Dec 2024 21:27:58 +0200 Subject: [PATCH 010/175] Update README.md --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index df289a047..e985297ee 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# 404s - Turning Errors Into Excellence + # 404s - Turning Errors Into Excellence -## 🌟 Welcome to the 404s Repository – Where We Celebrate Every Step of the Journey, + ## 🌟 Welcome to the 404s Repository – Where We Celebrate Every Step of the Journey, **Even the "404" Moments!🌟** At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey @@ -13,23 +13,23 @@ We’re here to ensure that no problem is ever lost! --- -### 🎯 Our Objective + ### 🎯 Our Objective Our goal is to foster a space for innovation and learning by: -#### - **Collaborating** across diverse skill sets to unlock new possibilities. -#### - **Embracing challenges** and transforming them into learning opportunities. -#### - **Developing efficient**, **creative solutions** that address real-world problems. + #### - **Collaborating** across diverse skill sets to unlock new possibilities. + #### - **Embracing challenges** and transforming them into learning opportunities. + #### - **Developing efficient**, **creative solutions** that address real-world problems. --- -### πŸ’‘ Innovation through Collaboration + ### πŸ’‘ Innovation through Collaboration Every detour is a chance for discovery, and every 404 is an invitation to innovate. By leveraging our diverse skills, we create a culture where: -- **Ideas Flow Freely**: Open discussions lead to unexpected solutions. -- **Feedback Loops**: Continuous feedback helps refine our approaches. + - **Ideas Flow Freely**: Open discussions lead to unexpected solutions. + - **Feedback Loops**: Continuous feedback helps refine our approaches. Together, we transform challenges into opportunities for growth and excellence! From b8452778622d57a875f41ccb139758269bf82924 Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Tue, 31 Dec 2024 21:43:03 +0200 Subject: [PATCH 011/175] Update README.md --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e985297ee..37bba06d4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ - # 404s - Turning Errors Into Excellence + # 404s - Turning Errors Into Excellence - ## 🌟 Welcome to the 404s Repository – Where We Celebrate Every Step of the Journey, + ## 🌟 Welcome to the 404s Repository – Where We Celebrate Every Step of the Journey, **Even the "404" Moments!🌟** At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey @@ -13,23 +13,23 @@ We’re here to ensure that no problem is ever lost! --- - ### 🎯 Our Objective + ### 🎯 Our Objective Our goal is to foster a space for innovation and learning by: - #### - **Collaborating** across diverse skill sets to unlock new possibilities. - #### - **Embracing challenges** and transforming them into learning opportunities. - #### - **Developing efficient**, **creative solutions** that address real-world problems. + #### - **Collaborating** across diverse skill sets to unlock new possibilities. + #### - **Embracing challenges** and transforming them into learning opportunities. + #### - **Developing efficient**, **creative solutions** that address real-world problems. --- - ### πŸ’‘ Innovation through Collaboration + ### πŸ’‘ Innovation through Collaboration Every detour is a chance for discovery, and every 404 is an invitation to innovate. By leveraging our diverse skills, we create a culture where: - - **Ideas Flow Freely**: Open discussions lead to unexpected solutions. - - **Feedback Loops**: Continuous feedback helps refine our approaches. + - **Ideas Flow Freely**: Open discussions lead to unexpected solutions. + - **Feedback Loops**: Continuous feedback helps refine our approaches. Together, we transform challenges into opportunities for growth and excellence! From db9373a05b62f3ce0378fa005368dce446037c36 Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Tue, 31 Dec 2024 21:47:09 +0200 Subject: [PATCH 012/175] Update README.md --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 37bba06d4..2629deefa 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ - # 404s - Turning Errors Into Excellence + # 404s - Turning Errors Into Excellence - ## 🌟 Welcome to the 404s Repository – Where We Celebrate Every Step of the Journey, + ## 🌟 Welcome to the 404s Repository – Where We Celebrate Every Step of the Journey, **Even the "404" Moments!🌟** At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey @@ -13,23 +13,23 @@ We’re here to ensure that no problem is ever lost! --- - ### 🎯 Our Objective + ### 🎯 Our Objective Our goal is to foster a space for innovation and learning by: - #### - **Collaborating** across diverse skill sets to unlock new possibilities. - #### - **Embracing challenges** and transforming them into learning opportunities. - #### - **Developing efficient**, **creative solutions** that address real-world problems. + #### - **Collaborating** across diverse skill sets to unlock new possibilities. + #### - **Embracing challenges** and transforming them into learning opportunities. + #### - **Developing efficient**, **creative solutions** that address real-world problems. --- - ### πŸ’‘ Innovation through Collaboration + ### πŸ’‘ Innovation through Collaboration Every detour is a chance for discovery, and every 404 is an invitation to innovate. By leveraging our diverse skills, we create a culture where: - - **Ideas Flow Freely**: Open discussions lead to unexpected solutions. - - **Feedback Loops**: Continuous feedback helps refine our approaches. + - **Ideas Flow Freely**: Open discussions lead to unexpected solutions. + - **Feedback Loops**: Continuous feedback helps refine our approaches. Together, we transform challenges into opportunities for growth and excellence! From 88cd0d7c42293e3b9eeee066708045dba412983b Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Tue, 31 Dec 2024 21:50:31 +0200 Subject: [PATCH 013/175] Update README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 2629deefa..466494b95 100644 --- a/README.md +++ b/README.md @@ -4,18 +4,18 @@ ## 🌟 Welcome to the 404s Repository – Where We Celebrate Every Step of the Journey, **Even the "404" Moments!🌟** -At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey + At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey with a strong focus on **teamwork**, **collaboration**, and **creativity**. -Each 404 error is a chance to grow, learn, and innovate. + Each 404 error is a chance to grow, learn, and innovate. -We’re here to ensure that no problem is ever lost! + We’re here to ensure that no problem is ever lost! --- ### 🎯 Our Objective -Our goal is to foster a space for innovation and learning by: + Our goal is to foster a space for innovation and learning by: #### - **Collaborating** across diverse skill sets to unlock new possibilities. #### - **Embracing challenges** and transforming them into learning opportunities. @@ -25,11 +25,11 @@ Our goal is to foster a space for innovation and learning by: ### πŸ’‘ Innovation through Collaboration -Every detour is a chance for discovery, and every 404 is an invitation to innovate. + Every detour is a chance for discovery, and every 404 is an invitation to innovate. -By leveraging our diverse skills, we create a culture where: + By leveraging our diverse skills, we create a culture where: - - **Ideas Flow Freely**: Open discussions lead to unexpected solutions. + - **Ideas Flow Freely**: Open discussions lead to unexpected solutions. - **Feedback Loops**: Continuous feedback helps refine our approaches. -Together, we transform challenges into opportunities for growth and excellence! + Together, we transform challenges into opportunities for growth and excellence! From b3d40d320dfffed6e537684690f14cf6816c0ab5 Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Tue, 31 Dec 2024 22:00:32 +0200 Subject: [PATCH 014/175] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 466494b95..5894f885b 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ with a strong focus on **teamwork**, **collaboration**, and **creativity**. By leveraging our diverse skills, we create a culture where: - - **Ideas Flow Freely**: Open discussions lead to unexpected solutions. + - **Ideas Flow Freely**: Open discussions lead to unexpected solutions. - **Feedback Loops**: Continuous feedback helps refine our approaches. Together, we transform challenges into opportunities for growth and excellence! From f9176188f1bc71fd1a958c2c0affcf94c6eab394 Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Wed, 1 Jan 2025 04:01:05 +0200 Subject: [PATCH 015/175] Update README.md From 87b228f71033191fd736babe8ddc30419274a2cf Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Wed, 1 Jan 2025 04:11:50 +0200 Subject: [PATCH 016/175] Update README.md --- README.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 5894f885b..38acafd59 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ - # 404s - Turning Errors Into Excellence +# 404s - Turning Errors Into Excellence - ## 🌟 Welcome to the 404s Repository – Where We Celebrate Every Step of the Journey, -**Even the "404" Moments!🌟** +## 🌟 Welcome to the 404s Repository – Where We Celebrate Every Step of the Journey +**,Even the "404" Moments!🌟** At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey with a strong focus on **teamwork**, **collaboration**, and **creativity**. @@ -13,23 +13,25 @@ with a strong focus on **teamwork**, **collaboration**, and **creativity**. --- - ### 🎯 Our Objective +### 🎯 Our Objective Our goal is to foster a space for innovation and learning by: - #### - **Collaborating** across diverse skill sets to unlock new possibilities. - #### - **Embracing challenges** and transforming them into learning opportunities. - #### - **Developing efficient**, **creative solutions** that address real-world problems. +#### - **Collaborating** across diverse skill sets to unlock new possibilities. + +#### - **Embracing challenges** and transforming them into learning opportunities. + +#### - **Developing efficient**, **creative solutions** that address real-world problems. --- - ### πŸ’‘ Innovation through Collaboration +### πŸ’‘ Innovation through Collaboration Every detour is a chance for discovery, and every 404 is an invitation to innovate. By leveraging our diverse skills, we create a culture where: - - **Ideas Flow Freely**: Open discussions lead to unexpected solutions. - - **Feedback Loops**: Continuous feedback helps refine our approaches. +- **Ideas Flow Freely**: Open discussions lead to unexpected solutions. +- **Feedback Loops**: Continuous feedback helps refine our approaches. Together, we transform challenges into opportunities for growth and excellence! From d14d7dbbc86c5fdb17d3f08efd2af49f9b0f6de3 Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Wed, 1 Jan 2025 04:13:57 +0200 Subject: [PATCH 017/175] Update README.md --- README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 38acafd59..dbe97bbf7 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,13 @@ # 404s - Turning Errors Into Excellence ## 🌟 Welcome to the 404s Repository – Where We Celebrate Every Step of the Journey + **,Even the "404" Moments!🌟** - At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey -with a strong focus on **teamwork**, **collaboration**, and **creativity**. + At **404s**, we turn "not found" into "newly discovered." We celebrate our + coding journey +with a strong focus on **teamwork**, +**collaboration**, and **creativity**. Each 404 error is a chance to grow, learn, and innovate. @@ -17,17 +20,18 @@ with a strong focus on **teamwork**, **collaboration**, and **creativity**. Our goal is to foster a space for innovation and learning by: -#### - **Collaborating** across diverse skill sets to unlock new possibilities. +#### - **Collaborating** across diverse skill sets to unlock new possibilities -#### - **Embracing challenges** and transforming them into learning opportunities. +#### - **Embracing challenges** and transforming them into learning opportunities -#### - **Developing efficient**, **creative solutions** that address real-world problems. +#### - **Developing efficient**, **creative solutions** that address real-world problems --- ### πŸ’‘ Innovation through Collaboration - Every detour is a chance for discovery, and every 404 is an invitation to innovate. + Every detour is a chance for discovery, and every 404 + is an invitation to innovate. By leveraging our diverse skills, we create a culture where: From 3b2ecd8638f9143e215b81d1757b1c01f377ce44 Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Wed, 1 Jan 2025 04:16:22 +0200 Subject: [PATCH 018/175] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dbe97bbf7..fa2e8b37c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # 404s - Turning Errors Into Excellence -## 🌟 Welcome to the 404s Repository – Where We Celebrate Every Step of the Journey +## 🌟 Welcome to the 404s Repository – Where We Celebrate + +**Every Step of the Journey** **,Even the "404" Moments!🌟** From ab0cadc7589a87ae73a15e7a9714d53564492853 Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Wed, 1 Jan 2025 04:19:43 +0200 Subject: [PATCH 019/175] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index fa2e8b37c..3ecf2a797 100644 --- a/README.md +++ b/README.md @@ -3,14 +3,14 @@ ## 🌟 Welcome to the 404s Repository – Where We Celebrate -**Every Step of the Journey** +## Every Step of the Journey -**,Even the "404" Moments!🌟** +## ,Even the "404" Moments!🌟 At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey -with a strong focus on **teamwork**, -**collaboration**, and **creativity**. +with a strong focus on **teamwork** +**,collaboration**, and **creativity** Each 404 error is a chance to grow, learn, and innovate. @@ -33,7 +33,7 @@ with a strong focus on **teamwork**, ### πŸ’‘ Innovation through Collaboration Every detour is a chance for discovery, and every 404 - is an invitation to innovate. + is an invitation to innovate By leveraging our diverse skills, we create a culture where: From 8cb624a982730f9c17c74070a0952054981f8525 Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Wed, 1 Jan 2025 04:20:40 +0200 Subject: [PATCH 020/175] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ecf2a797..d18c6c56c 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ with a strong focus on **teamwork** ### πŸ’‘ Innovation through Collaboration Every detour is a chance for discovery, and every 404 - is an invitation to innovate + is an invitation to innovate By leveraging our diverse skills, we create a culture where: From 4b254e87b56a17d4688638c157ea9a5fb2836479 Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Wed, 1 Jan 2025 04:51:18 +0200 Subject: [PATCH 021/175] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index d18c6c56c..3c6ac707e 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,7 @@ ## 🌟 Welcome to the 404s Repository – Where We Celebrate -## Every Step of the Journey - -## ,Even the "404" Moments!🌟 +## Every Step of the Journey ,Even the "404" Moments!🌟 At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey From 1166ec3814e1a1ad140ac833aea4d2b232a6076f Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Wed, 1 Jan 2025 04:52:33 +0200 Subject: [PATCH 022/175] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3c6ac707e..65fecaed2 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ## 🌟 Welcome to the 404s Repository – Where We Celebrate -## Every Step of the Journey ,Even the "404" Moments!🌟 + **Every Step of the Journey ,Even the "404" Moments!🌟** At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey From b766ff7f88cdc6fd1ff05b339b574880d80d898c Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Wed, 1 Jan 2025 04:53:26 +0200 Subject: [PATCH 023/175] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 65fecaed2..c66aa89a3 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ## 🌟 Welcome to the 404s Repository – Where We Celebrate - **Every Step of the Journey ,Even the "404" Moments!🌟** + ### Every Step of the Journey ,Even the "404" Moments!🌟 At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey From ec4b5d24b515734347e5b7ba9fadd398d26fff82 Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Wed, 1 Jan 2025 04:54:07 +0200 Subject: [PATCH 024/175] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c66aa89a3..ca319add5 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ## 🌟 Welcome to the 404s Repository – Where We Celebrate - ### Every Step of the Journey ,Even the "404" Moments!🌟 + ### Every Step of the Journey ,Even the "404" Moments!🌟 At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey From 4d5f7d07529fcc87fed172f998f483149f51a1ae Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Wed, 1 Jan 2025 04:54:37 +0200 Subject: [PATCH 025/175] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ca319add5..6ca275172 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # 404s - Turning Errors Into Excellence -## 🌟 Welcome to the 404s Repository – Where We Celebrate +### 🌟 Welcome to the 404s Repository – Where We Celebrate ### Every Step of the Journey ,Even the "404" Moments!🌟 From a1dd907d7d6f0c1064226b45600728279130f199 Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Wed, 1 Jan 2025 04:54:50 +0200 Subject: [PATCH 026/175] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ca275172..3e303bd8c 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ### 🌟 Welcome to the 404s Repository – Where We Celebrate - ### Every Step of the Journey ,Even the "404" Moments!🌟 + ### Every Step of the Journey ,Even the "404" Moments!🌟 At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey From 8bbc617a0392a7b6f9d576f37c0527e4607eb31c Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Wed, 1 Jan 2025 03:56:05 +0100 Subject: [PATCH 027/175] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3e303bd8c..a8addeeae 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ### 🌟 Welcome to the 404s Repository – Where We Celebrate - ### Every Step of the Journey ,Even the "404" Moments!🌟 + ### Every Step of the Journey, Even the "404" Moments!🌟 At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey From bd11eb2f8e1b7b7d8f13645d4e5aafd38d29774d Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Wed, 1 Jan 2025 05:06:19 +0200 Subject: [PATCH 028/175] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a8addeeae..f69480697 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # 404s - Turning Errors Into Excellence -### 🌟 Welcome to the 404s Repository – Where We Celebrate +## 🌟 Welcome to the 404s Repository – Where We Celebrate - ### Every Step of the Journey, Even the "404" Moments!🌟 + ### Every Step of the Journey, Even the "404" Moments!🌟 At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey From f4e994b12f17f6ff75f2830609ef31852f89d93a Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Wed, 1 Jan 2025 05:07:41 +0200 Subject: [PATCH 029/175] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f69480697..e5438616a 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ## 🌟 Welcome to the 404s Repository – Where We Celebrate - ### Every Step of the Journey, Even the "404" Moments!🌟 +### Every Step of the Journey, Even the "404" Moments!🌟 At **404s**, we turn "not found" into "newly discovered." We celebrate our coding journey From 752bb4c592a2e9c616f53835e07d24cf122826b9 Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Wed, 1 Jan 2025 06:51:29 +0200 Subject: [PATCH 030/175] Add summary and mind map --- assets/norms-mindmap.png | Bin 0 -> 48104 bytes collaboration/README.md | 10 ++++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 assets/norms-mindmap.png diff --git a/assets/norms-mindmap.png b/assets/norms-mindmap.png new file mode 100644 index 0000000000000000000000000000000000000000..ab5e9bdad9ff2c668e6813e54bb2446168424cc4 GIT binary patch literal 48104 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

XLhtf{f`my$*jiK_TBRbaKOAg+-pX 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 literal 0 HcmV?d00001 diff --git a/collaboration/README.md b/collaboration/README.md index 6270b5e35..5cf3dfddf 100644 --- a/collaboration/README.md +++ b/collaboration/README.md @@ -2,8 +2,10 @@ ## 404s Norms Summary -> In 404s, we believe in collaboration as our main goal -> and a way to achieve things as well. +> In **404s**, we focus on effective teamwork, continuous self-development, +> efficient resource use, and maintaining high-quality standards. We achieve +> this by making clear communication, mutual respect, and adaptability. +> Our goal is to **Grow** through **Collaboration**. @@ -72,3 +74,7 @@ > **Use Best Practices by following standard coding conventions** --- + +### 404s Norms Mind Map + +![image](../assets/norms-mindmap.png) From 2cc101323fab20ffc4dd03096199279eb327ca04 Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Wed, 1 Jan 2025 08:24:07 +0200 Subject: [PATCH 031/175] Modify challenge --- solutions/minion_game.py | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/solutions/minion_game.py b/solutions/minion_game.py index b312b07d4..11d5e5ea5 100644 --- a/solutions/minion_game.py +++ b/solutions/minion_game.py @@ -1,19 +1,5 @@ def minion_game(string): # your code goes here - string = string.lower() - kevin_score = 0 - stuart_score = 0 - vowels = ['a', 'u','o','i','e'] - kevin_words = {} - stuart_words = {} - for letter in string: - if letter in vowels: - kevin_words[letter] += 1 - kevin_score += kevin_words[letter] - else: - stuart_words[letter] += 1 - stuart_score += stuart_words[letter] - - return max(kevin_score, stuart_score) + return "" minion_game('BANANA') From 807cd7a07be4def7320501eeb43597415293ce70 Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Wed, 1 Jan 2025 08:26:01 +0200 Subject: [PATCH 032/175] Modify Norms Summary --- collaboration/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collaboration/README.md b/collaboration/README.md index 5cf3dfddf..52b522e7b 100644 --- a/collaboration/README.md +++ b/collaboration/README.md @@ -5,7 +5,8 @@ > In **404s**, we focus on effective teamwork, continuous self-development, > efficient resource use, and maintaining high-quality standards. We achieve > this by making clear communication, mutual respect, and adaptability. -> Our goal is to **Grow** through **Collaboration**. +> Our goal is to **Grow** through **Collaboration**.\ +> In **404s**, Together, we code. Together, we grow. From 5e9de1e6a6e2f11b4a7da195c5bc5222d01023ba Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Wed, 1 Jan 2025 08:28:22 +0200 Subject: [PATCH 033/175] Delete unrelated file --- solutions/minion_game.py | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 solutions/minion_game.py diff --git a/solutions/minion_game.py b/solutions/minion_game.py deleted file mode 100644 index 11d5e5ea5..000000000 --- a/solutions/minion_game.py +++ /dev/null @@ -1,5 +0,0 @@ -def minion_game(string): - # your code goes here - return "" - -minion_game('BANANA') From 3088c37852c4a05ebe2eda6b8d7bc24a2fc87cc5 Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Wed, 1 Jan 2025 13:32:29 +0200 Subject: [PATCH 034/175] Update collaboration files --- collaboration/communication.md | 18 +++++------ collaboration/constraints.md | 31 +++++++++++------- collaboration/learning_goals.md | 56 +++++++++++++++++++++++++++++++-- 3 files changed, 81 insertions(+), 24 deletions(-) diff --git a/collaboration/communication.md b/collaboration/communication.md index 10510f0e0..4abd13e92 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -21,10 +21,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**: Daily +- **Pull Requests**: twice a day (first in morning, second at the end of day) +- **Slack/Discord**: Slack +- **Video Calls**: as convenient to our circumstances. ______________________________________________________________________ @@ -34,15 +34,13 @@ ______________________________________________________________________ | Day | Monday | Tuesday | Wednesday | Thursday | Friday |Saturday | Sunday| |-----------|:------:|:-------:|:---------:|:--------:|:------:|:--------:|:------:| -| _name_ |||||||| +| Salem |10:00-15:00|12:00-14:00|10:00-15:00 |10:00-15:00 |❌|13:00-17:00|10:00-15:00| ### How many hours everyone has per day -- name: _5h_; -- name: _6h_; -- name: _5h_; -- name: _4h_; -- name: _3h_; +- Salem: _3-5h_; +- Nagham: _nh_; +- Nilson: _nh_; ## Asking for Help diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 24079505c..449eda388 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -1,19 +1,28 @@ +# Introduction -# Constraints +> Drop introduction here. -Some boundaries around our project. +## External Constraints -## External +> For each team member, we will explain the external constraints. - +### Salem + +| Constraint | Description | +|:------:|:-------:| +| Power & internet | I have limited hours when power is available| +| Deadlines | I have college deadlines in addition to MET program deadlines| + +### Nagham + +| Constraint | Description | +|:------:|:-------:| + +### Nilson + +| Constraint | Description | +|:------:|:-------:| ## Internal: Involuntary diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 11c583d2b..fc67f0078 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -1,5 +1,55 @@ -# Learning Goals -## Collective +# Objectives -## Individual +## Crucial Skills to Build + +- Master collaborative and independent coding workflows using Git and GitHub tools.πŸ› οΈ +- Focus on writing maintainable, thoroughly tested, and well-documented code.πŸ“ + +## Group Objectives 🌟 + +### Excel in Git Collaboration πŸš€ + +- **Organize Markdown and Solutions** + - Structure Markdown files efficiently for clear documentation. πŸ“ + - Push updates to repositories following best practicesβ€”use clear commit + messages and logical folder structures βœ… + +- **Handle Pull Requests** + - Create pull requests (PRs) to propose changes. πŸ“€ + - Address PR feedback constructively and apply updates. πŸ’¬ + +- **Resolve Conflicts** + - Learn how merge conflicts arise and resolve them using Git tools. πŸ€” + - Reduce conflicts by keeping local branches updated with the latest changes.πŸ”„ + +### Build a Collaborative Team Culture 🀝 + +- Foster open communication and provide helpful feedback. πŸ—£οΈ +- Encourage shared learning to uplift the team’s overall performance. 🌱 + +### Conduct Peer Code Reviews πŸ‘€ + +- Review and analyze code for quality, functionality, and adherence to team standards.βœ”οΈ +- Debug and test collaboratively to address issues and suggest improvements. 🐞 + +### Practice TDD (Test-Driven Development) + +- Start coding by writing tests to ensure reliability from the outset. +- Collaborate to refine tests, covering edge cases and ensuring comprehensive coverage. + +## Personal Objectives 🎯 + +### Salem's objectives + +| **Goal** | **Description** | **Progress** | +|------------------------------------|----------------| ----------------| +| πŸ› οΈ Unleash the Secrets of Git |Dive deep into Git and GitHub | ![50%](https://progress-bar.xyz/50) | +| ⚑ TDD: Your New Superpower | Use Test-Driven Development to code with confidence.| ![20%](https://progress-bar.xyz/20) | +| πŸŽ‰ Level Up Your Code Review Game | Collaborate with your my and grow stronger together.| ![10%](https://progress-bar.xyz/10) | + +--- + +### Nagham's objectives + +### Nilson's objectives From 514282a3037a50557fdcd2a7eea774ad101a57f1 Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Thu, 2 Jan 2025 18:17:23 +0200 Subject: [PATCH 035/175] Add function to find the largest number in a list --- .vscode/settings.json | 4 ++-- solutions/Find_largest_number.py | 18 ++++++++++++++++ solutions/tests/Test_Find_Largest_Number.py | 24 +++++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 solutions/Find_largest_number.py create mode 100644 solutions/tests/Test_Find_Largest_Number.py 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/Find_largest_number.py b/solutions/Find_largest_number.py new file mode 100644 index 000000000..462c6bd4b --- /dev/null +++ b/solutions/Find_largest_number.py @@ -0,0 +1,18 @@ +def largest_num(numbers): + """ + This function takes a list of numbers as input and returns the largest number. + + Parameters: + A list of numbers. + + Returns: + float: The largest number in the list. + """ + + if not numbers: + raise ValueError("The list is empty.") + return max(numbers) + +# Example How it will work +numbers = [3, 5, 7, 2, 8, 10] +print("The largest number is:", largest_num(numbers)) diff --git a/solutions/tests/Test_Find_Largest_Number.py b/solutions/tests/Test_Find_Largest_Number.py new file mode 100644 index 000000000..8cbc34b43 --- /dev/null +++ b/solutions/tests/Test_Find_Largest_Number.py @@ -0,0 +1,24 @@ +import unittest +from solutions.Find_largest_number import largest_num +""" + Unit tests for the largest_num() function, verifying its correctness + across positive, negative, mixed, single-element, duplicate, and empty lists. + """ +class TestLargestNum(unittest.TestCase): + def test_positive_numbers(self): + self.assertEqual(largest_num([3, 9, 2, 3, 2]), 9) + + def test_negative_numbers(self): + self.assertEqual(largest_num([-3, -1, -2, -7, -8]), -1) + + def test_mixed_numbers(self): + self.assertEqual(largest_num([4, -9, 3, -8, 5]), 5) + + def test_single_element(self): + self.assertEqual(largest_num([100]), 100) + + def test_duplicates(self): + self.assertEqual(largest_num([1, 1, 1, 1]), 1) + +if __name__ == "__main__": + unittest.main() From d72cdf80f4e41adc614ab43ef3cb1f8fa1193d28 Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Thu, 2 Jan 2025 18:40:47 +0200 Subject: [PATCH 036/175] Update largest_num function and tests --- solutions/tests/Test_Find_Largest_Number.py | 27 ++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/solutions/tests/Test_Find_Largest_Number.py b/solutions/tests/Test_Find_Largest_Number.py index 8cbc34b43..b17f65034 100644 --- a/solutions/tests/Test_Find_Largest_Number.py +++ b/solutions/tests/Test_Find_Largest_Number.py @@ -1,24 +1,45 @@ import unittest -from solutions.Find_largest_number import largest_num -""" +from solutions.Find_largest_number import largest_num + +class TestLargestNum(unittest.TestCase): + """ Unit tests for the largest_num() function, verifying its correctness across positive, negative, mixed, single-element, duplicate, and empty lists. """ -class TestLargestNum(unittest.TestCase): + def test_positive_numbers(self): + """Test case for a list of positive numbers.""" self.assertEqual(largest_num([3, 9, 2, 3, 2]), 9) def test_negative_numbers(self): + """Test case for a list of negative numbers.""" self.assertEqual(largest_num([-3, -1, -2, -7, -8]), -1) def test_mixed_numbers(self): + """Test case for a list of mixed positive and negative numbers.""" self.assertEqual(largest_num([4, -9, 3, -8, 5]), 5) def test_single_element(self): + """Test case for a list with a single element.""" self.assertEqual(largest_num([100]), 100) def test_duplicates(self): + """Test case for a list with duplicate numbers.""" self.assertEqual(largest_num([1, 1, 1, 1]), 1) + def test_empty_list(self): + """Test case for an empty list (should raise ValueError).""" + with self.assertRaises(ValueError): + largest_num([]) + + def test_non_numeric_input(self): + """Test case for non-numeric input (should raise ValueError).""" + with self.assertRaises(TypeError): + largest_num(["a", "b", "c"]) + + def test_large_numbers(self): + """Test case for large numbers.""" + self.assertEqual(largest_num([1e10, 1e15, 1e11]), 1e15) + if __name__ == "__main__": unittest.main() From 6fb6e6b3621f2939cbfdd6a8ebfab26c7f5b1e34 Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Fri, 3 Jan 2025 14:30:14 +0200 Subject: [PATCH 037/175] Update constraints --- assets/bug-fix.png | Bin 0 -> 40996 bytes assets/bug.png | Bin 0 -> 40996 bytes assets/indoor.png | Bin 0 -> 1627 bytes assets/limited-access.png | Bin 0 -> 2155 bytes assets/outdoor.png | Bin 0 -> 1730 bytes assets/planning.png | Bin 0 -> 41877 bytes assets/python.png | Bin 0 -> 17269 bytes assets/scope.png | Bin 0 -> 1719 bytes assets/task-planner.png | Bin 0 -> 2427 bytes collaboration/constraints.md | 49 +++++++++++++++++++++++------------ 10 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 assets/bug-fix.png create mode 100644 assets/bug.png create mode 100644 assets/indoor.png create mode 100644 assets/limited-access.png create mode 100644 assets/outdoor.png create mode 100644 assets/planning.png create mode 100644 assets/python.png create mode 100644 assets/scope.png create mode 100644 assets/task-planner.png diff --git a/assets/bug-fix.png b/assets/bug-fix.png new file mode 100644 index 0000000000000000000000000000000000000000..1b6e7046029e2e49df08e2c2767e2b391dbaa5ce GIT binary patch literal 40996 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 Z`!AY(o*>h>^=1G7002ovPDHLkV1nQr6ypE@ literal 0 HcmV?d00001 diff --git a/assets/limited-access.png b/assets/limited-access.png new file mode 100644 index 0000000000000000000000000000000000000000..0999dc1e1855413ee84ee62d9407e6646a833bd0 GIT binary patch literal 2155 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 Y1+bsd-pOeiwEzGB07*qoM6N<$f^2Fxn*aa+ literal 0 HcmV?d00001 diff --git a/assets/planning.png b/assets/planning.png new file mode 100644 index 0000000000000000000000000000000000000000..98a97725878e4dc8b5f48038d1e88cb9bb81e342 GIT binary patch literal 41877 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 W*-fH2G6$_=Kw18!TqWE*{Qm$jKwt0x literal 0 HcmV?d00001 diff --git a/assets/python.png b/assets/python.png new file mode 100644 index 0000000000000000000000000000000000000000..00557bfbe2234f132a724ffb39d4c66554b8484c GIT binary patch literal 17269 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 Tu`F$uud`z)7cR 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 literal 0 HcmV?d00001 diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 449eda388..00afd60d5 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -1,18 +1,18 @@ - -# Introduction +# ![Alt Text](../assets/task-planner.png) Constraints -> Drop introduction here. +> In this readme, we explain potential **constraints** that limit our productivity and\ +> achievement throughout the project trip. -## External Constraints +## ![Alt Text](../assets/outdoor.png) External Constraints > For each team member, we will explain the external constraints. -### Salem +### _Salem πŸ‘€_ | Constraint | Description | |:------:|:-------:| -| Power & internet | I have limited hours when power is available| -| Deadlines | I have college deadlines in addition to MET program deadlines| +| Power & internet πŸ›œ | I have limited hours when power is available| +| Deadlines ❌ | I have college deadlines in addition to MET program deadlines| ### Nagham @@ -24,20 +24,37 @@ | Constraint | Description | |:------:|:-------:| -## Internal: Involuntary +## ![indoor](../assets/limited-access.png) Internal: Involuntary +### 1. Various Skill Levels🎚️ -## Internal: Voluntary +- Limited experience with specific tools, methodologies, or frameworks. +- Uneven distribution of skills across team members. + +### 2. Communication ChallengesπŸ’¬ - +- Communication hardship due to limited resources of power and internet. + +### 3. Productivity unstabilityπŸ¦₯ + +- Due to unstable circumstances ongoing on team members' locations. + +## ![indoor](../assets/scope.png) Internal: Voluntary + +### 1. Documentation ConstraintsπŸ“ + +- Write documentation for every major feature or module. +- Update the README file with every change. + +### 2. Quality Assurance Constraintsβœ… + +- Require all features to pass automated tests before deployment. + +## 3. Collaboration ConstraintsπŸš€ + +- Enforce version control workflows (e.g., Git Flow) From 929f970801326615b94657be8b9568f060ab7e89 Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Fri, 3 Jan 2025 14:32:11 +0200 Subject: [PATCH 038/175] Fix line length --- collaboration/constraints.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 00afd60d5..a554e0881 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -1,7 +1,7 @@ # ![Alt Text](../assets/task-planner.png) Constraints -> In this readme, we explain potential **constraints** that limit our productivity and\ -> achievement throughout the project trip. +> In this readme, we explain potential **constraints** that limit our +> productivity and achievement throughout the project trip. ## ![Alt Text](../assets/outdoor.png) External Constraints From e1463b3a88f90682b8ec635ada2157a874ea5214 Mon Sep 17 00:00:00 2001 From: Nagham al baba <142064107+naghambaba1@users.noreply.github.com> Date: Fri, 3 Jan 2025 15:47:28 +0200 Subject: [PATCH 039/175] Update communication.md --- collaboration/communication.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/collaboration/communication.md b/collaboration/communication.md index 4abd13e92..06acb1963 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -35,12 +35,14 @@ ______________________________________________________________________ | Day | Monday | Tuesday | Wednesday | Thursday | Friday |Saturday | Sunday| |-----------|:------:|:-------:|:---------:|:--------:|:------:|:--------:|:------:| | Salem |10:00-15:00|12:00-14:00|10:00-15:00 |10:00-15:00 |❌|13:00-17:00|10:00-15:00| +| Nagham | βœ”οΈ|βœ”οΈ|βœ”οΈ|βœ”οΈ |βœ”οΈ|βœ”οΈ|βœ”οΈ| ### How many hours everyone has per day - Salem: _3-5h_; -- Nagham: _nh_; +- Nagham: _5h_; - Nilson: _nh_; +- Matvii: _nh_; ## Asking for Help From 9c65d8b3d1f6dba812cdc1fbe3371c5f8934d10e Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Fri, 3 Jan 2025 18:44:43 +0200 Subject: [PATCH 040/175] Find Largest Number in a list Fixes #8 --- solutions/Find_largest_number.py | 19 +------------------ solutions/tests/Test_Find_Largest_Number.py | 4 +++- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/solutions/Find_largest_number.py b/solutions/Find_largest_number.py index 462c6bd4b..df2fd0554 100644 --- a/solutions/Find_largest_number.py +++ b/solutions/Find_largest_number.py @@ -1,18 +1 @@ -def largest_num(numbers): - """ - This function takes a list of numbers as input and returns the largest number. - - Parameters: - A list of numbers. - - Returns: - float: The largest number in the list. - """ - - if not numbers: - raise ValueError("The list is empty.") - return max(numbers) - -# Example How it will work -numbers = [3, 5, 7, 2, 8, 10] -print("The largest number is:", largest_num(numbers)) +print("The largest number is:", largest_num(numbers)) diff --git a/solutions/tests/Test_Find_Largest_Number.py b/solutions/tests/Test_Find_Largest_Number.py index b17f65034..fc31939b9 100644 --- a/solutions/tests/Test_Find_Largest_Number.py +++ b/solutions/tests/Test_Find_Largest_Number.py @@ -1,9 +1,10 @@ import unittest from solutions.Find_largest_number import largest_num + class TestLargestNum(unittest.TestCase): """ - Unit tests for the largest_num() function, verifying its correctness + Unit tests for the largest_num() function, verifying its correctness across positive, negative, mixed, single-element, duplicate, and empty lists. """ @@ -41,5 +42,6 @@ def test_large_numbers(self): """Test case for large numbers.""" self.assertEqual(largest_num([1e10, 1e15, 1e11]), 1e15) + if __name__ == "__main__": unittest.main() From 10b97ddfdeacbc8c03d35252c328dc66beb51d95 Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Fri, 3 Jan 2025 19:57:27 +0200 Subject: [PATCH 041/175] Add voluntary constraints --- .markdownlint.yml | 2 ++ assets/internal-voluntary-constraints.png | Bin 0 -> 15208 bytes collaboration/constraints.md | 38 +++++++++------------- 3 files changed, 18 insertions(+), 22 deletions(-) create mode 100644 assets/internal-voluntary-constraints.png diff --git a/.markdownlint.yml b/.markdownlint.yml index ee6205f5c..b2d26ed41 100644 --- a/.markdownlint.yml +++ b/.markdownlint.yml @@ -1,3 +1,5 @@ ignore: - venv - .github + +MD033: false diff --git a/assets/internal-voluntary-constraints.png b/assets/internal-voluntary-constraints.png new file mode 100644 index 0000000000000000000000000000000000000000..fafd1ada06d1ffb071c32b328d01b92d8c5b721e GIT binary patch literal 15208 zcmeHuS5#BmyKevirEWz)x{88;fSV${DAIcg(osPXkRmNWAfPCyNK=Y*ke*Pamk^>N zRRjb=s6lFg5JF3U(C*^D&$(sXhkMVs5BEHrhs=z%MzZEybItkv%J;3eW+u9d{>4ygQL?{>pQa;kZcgHH&i8vkM>#&%OKS-Frcg|C~Hb}4a>agDZa(*|p zw6Z|GiozCeckvouU*Bh`DPPY%cPaQYc;!-n@WKy-fSd@I-94kRHbseNTvxL62p#bZ zFDlDN42X9v#06*g#48n_ZW_qlnZH>rdXFtu#$-mLe`Vd@BsZ0sH$&~M+8M0{gsoLBElAZ(EfMKH0N+xwjp!-^U8#2wmDr1cN)~J%P zQ(|)MJ;X_1O55gFkqW0LLKlfc4HIl}6S2nzm?8U;t9W>szw)L*%!IQ_rNWGH8_elp z`g$wcg3r3s^e=_-Vls3@TA%602-oORS%C+P8hO$ zC$%13bcj!7V5*y?5L+5QYZ`LA(EadvbxP18xX(`9XU*E>t^dJ}iE4OSQ0tRjamPme z1C<8&V11Vod1M+PYGP;D42EL%F|=60He$1)?oXdqedl9~`gNn`C;D0yOt)F>PS*Et z+E`4sia+q#;y;*kp+OA|<>&k^6)7qA$5+^uOte&q2ZyUJH&2QQ+&^$sEcx9gh}xJi z&%UJMhH5Cx@}#52q9+Omvk6wqq3q$f*Z~2oKQbaO%{2S>!t2PpGyAPhu){ZMXIk#c z&)%NK%broDhE+5KPG~=I4mPVg{-tc5%kJQ?qdL14Gd&rq)V*u}O? z*lqN1WxHvHxKY+~w~QGwq#X=)^(?w}qq zin^z)xBe2y8fw757RwIbZkou&<=Z15Wp2@fGM*%XQ7!x3((OWlEZ1!4p=&}AW)$Jy zfR7UdA35%NOb$D~YfWb{`5;GzS&709-#36spN`2V$EB+zFN=d7*`A=DDhnd_oJ!X3 zpH;0%QyQ~%42*M_eZ#sC*>C5XE}k`QYDGmjx%o^Lq6A_tt`MywbhCS_;(Yk5hGA&w zESC3yEBREZ?5qy~L}RA#U3&6vki-yFPnY5i9#rpI&hOeuF6itcmcw=)CG-|kuuT7tIKBY4&pRuv@q+%&!^<<2 z8%f#kZa-}gjF0Q5Wc4>I?A$ALQX_>Z^hNb-DlkvI| zX7}R4G>^lT#WQvL`CI}@&rsY+>q4s?(H4u6Is0T?Ho-wXgUOrb&B83k6aoEgkvY6B z*-uraVk}R(YV#SRulZj&z9IHuwY<4waCxk)mXs1U1wPxB$&o3Vz-sTj{K9}ps&5;y z>-`YJJ^HFbx&`O0eL*V-9}w&lqa)qTD>aU?2YaUWs7Iw%O%zU7U?_>05V8hD@t5zP z5Mz_28&#i8q&v}OsP>o7({Z{}Lzz1pZCas$Gf@*?JYM^)9K*ULzK3K;GgrDl&+nynzF~A@WP_Peq~%r|HY$} zPJ%~2KlUv|ZPM!}da9ILNDSr*0cN?N|IWxS?b-u5FA!-P>?Imd%7AIy+MVt$)t@%!~Yl`+vW z^s%nqMLFy%RhZn&!Y%~3d>L-OY<#%&CI{N;v}-kkuotMU!Lt8=WGs>I&s5RPR2aR& z7t&%zu4(P`2<={rqB2H>HcR6O>B>e-f99?L5rI;+xP5XXOfKW_<-4GjoO?H(AHUwo zawJG*kB&{gEf7d84e*NQxW|j@S};T0o<2Vme=<^Z{L$PvEAs@#>zu>WC0r$lvDFui zXT1*9yj|{p=7K47scM+PC$d`75qXDjVP)k#Ol3w3f|Zo@n164~MtHlb5-`xnUV1bp z7Kg@{;(G@(9_UYa{uG-m{IwaRH2kqtK9iT%>KaUtbW1EU_T9#rz9{yS1xI21pMl{m zK0lh@2>#YeU>ETyORXxiGTfs_O?a`3)px{PlxDj>yVrAvHQq5xFp>R;wtHcrj-Hz4 zWR;z;Zf+VT=QVB&cb`HC$9!n_$qyU2qMjPjOL}fFIhPrLCvJN8Z!1p$0G(|)FeBKA z4T;gGad`Gh^sB^QdeI4*MNR=D&4mZDAqx?eA~5B|av|#XsMS61`gh(A#YLMw1I(7( z`A*&6z=|*f=@C+98{?1h92Z^8b}`g{YN1+C!1!7LXN$TM!GBt&%MwZ*w{Vz`Cuip}_&7Jxto zkJDk0UpMA`@d*3_%KSM>d3E=3#B7$16JP(De#`!Ca@P;Elw z;vuvFSA1@`29A(id^$Ge0!oZ0`G;poz-_1Doo_tZicN-?U+q0kMV~F`=jF`}(^S?s zlP7Z2;pYz2GT#Y;htUZGuLF|eSXY zw_ls65`0n~roxd{uS6XJx4hr5zpzOdoT>d?=`t}0Ki?BN0nfL49s4+Z{KQ%1qToA^ zUN!^E-w$64Rf3O(p><`U2~-Y^mr(aGKkcoUB@t(pJiJL(ZD>Yuzh_t;n4Opa(RWb& zDUl@`KRHB+RGb_Z4?|wrUsjJiReLY%296t)-S*3~gcBXyp+YUsyK0`i!Y;3icA- z8kC?s^L|$`3rotbz3N1(93jw!*}}wVL3Kam0m4jaC{`25FjHffYkNBTfz=Sf^Aud{~>d$tqZs zpraPLG!`KcgF7Eo-%HP>NwtE+zD`B}x z4?QJADG0>Qa}v$ANFH3&erIFirK@rJ^yq$&kIi~o5Mus-9qvJXx1i=&YlOghV``<> zFevq1SrsKF?|}ZxZTB)I-Z?@+O>%o)DxfAKqoYFo#glKaUT^Ip3flL1Zuyx%2|1#m zrkjc-qMsgqy7*OFJD4`IT&}1`mXe_E{Ap-8U(F*{gE{frX*7v>r~>LXFc0)*7t7jn z&n#SY##IQD-Z+XL$dG#ia-n zLYq~EiUd<#K=rPs>$7rQ&wfkH0dqAI!6(;TE@b7lznma zy~VhJvg!pHW;1*|;%NV&vEB!!fCFJZtL16@Bjg)3(^G+wHdA-3)>vpKul=(X3DUHC zC3;yHFFzEPyUNJ_&3#j*V&AX+uCtgqj%=7L?C!BuXL6WE=b^q6-S3nb5MCBUDzo%` zyu7#Rj^6Ihq)mo<;Z_kA&rMQ07*vPiit9+|X{3EixYbaG!Y8+dB<(eeWq z{)P`m88aFV{zkBjPwhwLw+}#;7n6p08*|zEns4W!Z-`^EA>J0h$x4;8`kXOCjc1GCQJQphbGg=?iFRn&77Wt@t(MQbtq!7qM&vV_j@VXbh zHQ?WZ`6P4=>FC9e5WnEf1vbsH@3oqjQeI8Bwvk8tFbs#cbkafidJ&9b&u5 zq%-Q{HREjTUQYp&0%mn|LTLF%;ele>E*l}g0y+{Rb6g~~@;$lJl=Aex7fQKn3Tb+D z$kVndS^-Lt3`k`8q8UsU=7|C15-dJRm$Ci927d*5QduaZ`*3lHdt z70voT{h6$Whd#rVrqXZ(^Sv&7tEZQe-BFRTc#E}NTd{@YtPmXCXrF}hCZoUD=cDU# z?y0J5gx6oU^jN}aRMjeY58>Dll2nydE0|Z% zLPthm%Fml7nJ{bKBhitlU3q#SK!5a`&opIqSIl|be`JByTR`)HTW{xObpYGO{a5Pr zs&bve-`rsHs6ff229K_hGesWN?IwkdlP5iOJ=+<5=brjU3G{^`9kqgbXYx|H*~$n= zjCjj$^9SfT5pcLmZFuFjva(!kUhUo!dG%_rXJxIEJif(3ehT9MXnUdhVRmw%W)Wp_ zchDkLwe^cgR#W2}HCG6Q+h=T8PLImnAznYJgm1~TB2RPgtnR|=L*2LJK@N^*O~11E zRY9U(4~GuRUQ4Y$f#@A=UMW1?$6k%=5@LfED*6jICCxU@@49SrXz*-Q{k9FQeRn@} zwBj(!T9m8bQwCP)ndTYt=!h@$kzqxUDlWfWxI}LAIN5Kh$lLAh?Gs}g_O$VDeO)8_ z!@Np+bVTYB3J!18`bOrf(9jhaS}5${w`(|M_NIwF`%`e&z09l;(sZUdxv)%7N&zd zx57x-!#>lQl2}RqGoN{GN{yoT-wCrAW&eKb;z-3gV-fHzwv?I4!v5S6KEI!XLo(pQ zBFN*Ry?lX|`W7eT1oUFaw!;?w*;0E+)~s(%@-wp(M2|@sdOLCzGO{}Q3sSl|6S%U# zpULts$EeTM_N~GF>)fJjM9Tqazrdlf@h@G?PeWEMEuwS?G_JTmn$>Q8`yy^6eV$2! z8rin%PvW8*e$`x-WUaO{<&M0it{cM1?s4)$NF-*L*ANwRv$aD(Z0BxfP{iYut;$XB ztf3zR$~)wPk}`cdUu|Jv^Vt=%rW6?jTy#_{5*2)Efv%08a#^il3lHB$!8L-#H_zC5 z!|wRSxafY=3KpD?IPln7X#$boLHj$bR z5<~pvY-;)?cH_BFdvDaLpB}bJ_33uEp7pc7u}9`Y1vl9Pf*0=ZlYQ57THd|turK^< zB!X`CT(_o4Pmp}75-fN9Xx?KYv?@pyYE?iIDdGE+p<0oIhm>t)I`X1?orH9pVeZ1z1*YZjDQ5?>zyJihYWlj4_`t6}a!NY&*RW5ovHRgY)$YZoD`dpQ zsTxa3i1KQ))ZyRzB&jZp!mXIU#dS$W>m?Q?A&So*acR$OKb4bNJ`o?d{OI$&t$7ny{M+D1C zjt>^mvQpYfth-Id@vVla@r+nk1-v(AppEa^7(k%+ara*AHfRk8H1F>%yjvg*X9chD zkna&y4*$G2;h!oh#y&B>1}p^y#k=!1Y3tQ9QGcSXI_Uo-ChYHE#jg(i%GVxwC; z(Q|&Ze095DkL=XiVdZx1q0%$QZMBItTiqe+E+ zsW%{}Ot(~9m+duqV`9Xa-pQ%j5;&+wu0E+~lTyMb0l)DfE5GKQ-0_$^5=)pFuRY!`2XQtu60PWUWP9EDG zy*41K`4?fdbix3k zW2$5?ljY0sEtOwHp|;wWzhsR1SbYf@L(+U@ImN^|=dJK>U#_C2d(fR0aSbt*FQvz0 z#o*48PlIdd?tL7Y3-f`tGcB^ik3G(IyO6I^SkT_zdTfta=aUT{$@5js!<} z(019Z9k{r2)?c?75QaW;4{jVpW25ajr*PU;oRtQEXoySd&P#T#n0UR)^R0tJzUS2{t4D}6Gx6?)sPwDrSUpJ+GmH&TpQCo z4KFgtaw)}BqMz>s-9y$@G-wsX3p1mzi;5<{_`n)}#*~1uv}wtX?zg+dgVhh><$SCr zSsxMyNCs1uhfX@Jc#E?6iHh565bxA^e%LOYg@hdsiYIK%C}4hkON37_TMT3;8BP3J zqm~n%2mDGQS{3Fi2BLm>oII4TAPu@re(!~f9jpJCoY~+d5_kX&6H2sNST8+L`%Q@eKyow;C19Eyr9VliAf3jZ<9EwLnsIIxDGJvVoGy_(&sk zvU&)Hs)t5rNw{dVoHUG$rtzz^9lJgwN}6^?b0GH|Vo*}#CdNnhs4BMrwc`V})4!6B z86SC)NbgaEX{=B7Hq`~l9^SqP?SmeF8bEbEs)jg+UTzqLqO0@ATpEK19@kIXk<|9; zEF(3Cd*=>hIP)nd)UUTAbEl7S+vwv$Q@-M6 zO7g%N-w>BEwoj&76>y=AeQ6><_8P$m-vK_k1bse+xxsZ~D zvT67n?OmU&%?VR=%6)`AP=s;}t$XqaNSMWz=)y~{)Q>eSuX}KMn1ze%Ug9PWRZ>b# z*&TtU2Z4u`Yav@-@8dFx>bzuy`X(hm68Iui#8XlfL%$lWE`R3zHM25~6%T?qyJ&*t zi-yMXu9gYd3Kr$;w%F9m)3`r)y7YbjsntAF=_9YL(3&D|mQSXDcV~JzPgQ^3MHV*P zWD{sn#6%4z(Z2&HNt1P#oc1yyQ8VWZz?n% z#LqWUY5<6nMHhG+KN#^TB2?4(1@Uhd-Sd97ij7Nar$ z^Ge5us}GVjjD7X@=UA3&S7da0+g5D-A1GD*D(UR`A-DU7Rlq+9*$|Mb=DI!XZPIN2 z-MR|wRU;4=Dmr}0onk~?DHBF2zQa7-{UXx;lOv>w_IysHTzSqbw)%8fQc-rmE% znttGJEBBY_o!Ib7;!;)Vw<8=y;n!n76NzWo1TbQFA6Ew+5TD|yjmhB1jj3h>|DANR z@)of9vp*=;C+i;>4-c5j4P_mE-sWr3|MYOI%QURz)pX9R;>qPCSd9tRcaEh!W|&Q_ zvx8Lh`=HQ)x*_{<1sWBNQTU_5a$AK49A0Ag+C>1K;eA~AG_9cny@xNDmPtfje`egT zl<8!u&&z9prezB6+J3dj|9yIGob2H~bN|oQy?)i(FB zdgJxW54o*WMz3jOAblER*UtdjWJ|+F}fyz8s2rSYNMe851EZHf9~RH#muF_t;8zde9%Ho{4M7QXI=aUWrzD@$;{3 z)hnK^SXEOe_3fp?^jh7mTxLuK{}xX2;JYV?81hBZ7*yGeCojGSS-={ z^&NfO;)QMR%jqRR*Y$HKpGYA&hf7B9l8dLh>cVi+yIEk9^g8=uEH~!fjzB#o)T6@! zC%dckaa)y`WTAc^=4As<#a$pbQ%q5vb)>+I-Cm`E`wxw6kXQrd(Y3Ok?GWn4roQtz ziSjinsx+Vn569R*ps#=#_5ae2yKLr8{X|F1pjbefT$fd^K*QD&Dm%uiW}ZvZff8BI zns)QXs#6ly7a1{#ZeQ)R4}x-Y1PiLq)g>Q00YKKfhK)Bz@Nxfg0VgF{yPi=!ZVph^n!Z?F=r|F5ij* zItk{lL;c0mQLJjoS9m_wc9ElZzX`0hdHy()raM%~_FBr!XYF0DU2hsL{@HWm!j8eT zpv$ovxqkqz$Z!@Yp85aZeqDT23jRi};N7fb1UXoox{B={c4+fE1J1*V5VT=WTk+CE zQgrMMct4R3pb49MvBk5;07*4b)&uH<0!auBIt3pMopDPGtQX1 zN6*zve6lQ6rcA?64B8613X% z9Y{{Q)Pj?cMX=GT&pWgU!b$Ct!9nOhbn@|Flw5fOrL;hemWhE5;Bi~*?{Np|E3oXz z0>_CZsBxK>^3XGB6(?y}u60Gm_JB&=YOvY>c@O1dP=^hu;z1wtP-uK@0c8*SY#wLW z`*U|xsp$OK8>T~hpH9-&>j1ELrd(l`S#SweZFOXP{G!WQ6MWFZxxy-uES;jz>5MRG z^maG9F;k@@2G_eLo&rXA6i@P>24uKR=G5O1!}?yw7r#^eG#`ZC0_ z40FwpeO#cwnZ;+nX3u0Dr`5qyi64dMPnj?H#ya@oP2=>2%L?erkF$r3CgW04jO+(< zAD~N|U|O{y3Qc?+p}m8Ag3}K24+Wb&4Z(`HOZB3KL_y&i9C-n3-D>zvjbj?M^E&&d7m)Qs8wBvC8>b~Q=Ccgm zUUYb}B2|Wz<3BI%Ap|^HfDR2C&OPDoFERRSwR}Zi;6mT@+!(rg1TNt>BKNB<+ogB%0`F%k#KedL&g3>un2?CGrL#St!L(?)BwK zQWM4aqB}J0XHW~l)hJX&<}r3_r?C-U7H;-hK1G%dV$8p026Ue(bEhrhM*oqwIsxVXwl%T!-P5#I}+jhBlV5yi&`RYi;181X-AfH6Ey9pcQeN4ZC>3i)d& z;iU!Fp1{RwVibv2z9l^&jhqSk7Saaxmm3Z`xx4dF9>Zpkz5^NuxWer>@a;_{mTX|& zi*CYwD@65FBFdG_%BCs4g#TnuwOI?{0IjN**Go{DlrTQ%AWe@``pNOT z!!4Bti`sO(ap+fwqsO@_@(y%OVW%Klqpa#ER&JJWM0+0emAgIYE9Tn#-RB@pdUWkqXZ}2yyHg0ZSw7{UA&nyz1hw64neDr_%&C_%$v< z*HR}R**hDw<<$>-te*Xm0SHH&f9EdpwC3UMr9y|Hqf zzNoSg(D!&(N~TrwPt%bxU!TQKdvVG zyR?(jtYcz)I!LVe-*@m7scpj6yCC;Wx1j;oX-vmQwsdC=v| z(>3w#WzmpL%!Cnotn0J;OJl2fG3^l^CSWcez3k5x7b2Kp_(kwp|At|4@%kE2B*tQC zdVB7Mhh9!?tw`Q+u|z~e5a>SJKM~TdxA3@l1#imhZUWo1f8l9%9(_~*5QdMvQU2lZ za+^4m3b^tPIh{d8-@+AKfGE}dZqv^Bbs1=Rai|ce+6=G;{2ydSIXx17xOyz^eS&kygU-Gy_Lz_8)AZ2H3g#8I>P9j$f)VSwY1YDaK)3|<5NM? zOge}5@6al69oV)iYh70HK#=>4J5)_UQo^TfyPORO4K|k==s=)b07U%<+q)E-g?+{2 z&4}hS8c;Xw=>@YAkZC9Q6JKdSZO{X1Ls01C6?9+iI|u0U0U$Nh)R$I5LVf!FCwbzs zzIZ|@--(Ivt)c@xcySu@)c4)pH|G|%_G^b;RP?I>BlP{(wN3SM9cG;%)RLiySzXK zj~5XU!}Ch`hX43m?yPHV(a$2*nbhM&Zj?Rf=H>5z(W*sY+W9GoU^zgE0FB?r*T;m{EHukT`TCkpSpXzq%m(~kd7~32)o@upzA;GI=`n3)yKAx<2gRi=d)&dh0 z#K%$cHhnyUedV3s}?TI7e7 zq17harkTLUnU=wzkJfgR3zaY5BG=a&Hmjb zjyHQSLAYc+OjWZuEhd?3e-j0N>X|4AX?6PSJ3fKdfCW#yTpA&WCFHi>9y(ff29G`TCtbA=O2GN=f57e^ z`*e&50N|Sn)MCS!OO=Xs+ceK)=ufX|z>npZaH*bEi=Q8MiV4j5LFjP)85rOAk3~D7 zX4)y}@8}YSI%qw{x@5Z%4Btjo5Dc4j586;w`_zwOUb7J}Xg0)oW}ZmdDQ~R&8ItS1 z-qTnyM@qu)U4&tCcxDD7XYkkO3ER!7$pZ!T2?tr5{;GdXu1-J6odg_R*~G2=SZBkG zh9Du&nb=0wVFze0>?`f53+pEQ3pzsDcK!)Cf2-x^O3`It;mvU8)xoF0VpgNa`Yj>$iN}?A{ajpqu=Q8c!o%w$i%Fy-ns#fCGf_A?Kw7D zpD5FSi3CbkS6gxQ9c>F0kterD;8dF2ob-SE-ocXFzoxA%)>A!FB;ai>wat+{fCZ0G z%a~v;ek4C(iYF>BtCRY$yYVo2krYM&qK!p~UR5JRJiGK_K(5wlWii>o<=<@L;H6o2 z5`O&8*xTx13s~99{sH%1{280zSE3K%MLJCk#m$^FKLFO>Wlo0J@F>&u35!#&Sj%9| z-bogjxFDVPu0F@-m!{@xcdUvaIe`t~bJJMB^i*2sn3-FDkU5i{>HNpm<;GuT`4Gow zfU4z4JH=>Li*FSjzp2$6FEQT1Q=hfDf!{@LZC#Jkc4MJ4;pk$Jhg*P~URpX-i(Am@ zh+y3$2ilhUN&LrK-rdhM&;zjIuB9bzJr@Cwp8#L@dRl#?e~P-j>^BCgZ%b?ZO4I&Y z?JNg>zB_vJFK|;(!Ak-v0#+~UuQ0Txlu**&X#=~w7(4lhF(<_0V%B5!biDsuvinzG zW*`CMXCj6W_^6gyt57a7;P$o3#2uG1GLEY4+4kPv>7*G45>$O1W@+DD%22xVF7C(d zGd!QN?udJyx#(e-eNpaMVcKQ?Nx3whTJ5pB@WBgHyB_kPn85nZBTT*BS^sS>CwT9A zyDqV7h;eDNaX9SB6RYyhdwkKHy+T$;)I_&8n6E%oA?!YF6{hC>^Sjcfc&wXeUlHS@5erEbI`B2Fel&?%g1Y=uB0HemalZ8d8@p5 zKg(0>xby^~s+IbCxg45POk{n>h8VEtlN0UmsKf7NG`RivTQ>#TJ?crF#q|ND+tTHU zkT;k}`9s@^>6|>(178Kk>w)j&LOr)5U+V_bK6zL;F8IhmtTOc-@7lwQrekk3K0D$* zW%*sMuEL|sbu$Dsj^?;Mfboq6*uCCXym+17iY$QmGI8Wg-4tW{Tt*{hi8JFkTY9VL z)?`lbP{MAo#`QoCu~=~j!b;%tzB44Lk(>g+NSHWv9Y|*5K=_xZ3u!A4Vz%;VRJ*n) z<X40hIEPu!_v_?Y99UL%34R~HUvjmb6x74x!7qQ4!r^PZ@g~;0%wM)c=i zq)K^W)(P^QSow(P{THu0ucdbjj^EY?-d$4%w9|i(js5Sx2lyFPY*jtP zbpPnwt_+YWj@)>)R=uFSD+B1m$eZ_06Um}Kr+>~1uRjL;t1NPSUiPFHb(raFph5Ec zAM6ZeK<(q*ZBby;7s~QKJ$*`I9FH4M+L1cS0cZ@J_8VG|>xM8X#eaB3h2cl9mvl};JLiELzu zPVn6z1MWP~Wy_O**L5pAB)bRwfD0VNq<*u)K~(bi6NDM$y0q(781W_)OY5%#B*!O7 zFv)DeWE^jz`W_=`wD0DJA0_-v)UYj`l~FZZ{nxDXz&jgF8@em(ZbjQ9+mpj~pCV>U z9P03BK4yr7OH$vLE=-Und(-<~r*`WWz0BMBod9hF`Rn|{j(>5SmZt)A_P^TyngLMc cixZ(&*^kwO&Q`JjsQ{3^w#mK9yANLeH-PLry8r+H literal 0 HcmV?d00001 diff --git a/collaboration/constraints.md b/collaboration/constraints.md index a554e0881..3897934aa 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -3,29 +3,34 @@ > In this readme, we explain potential **constraints** that limit our > productivity and achievement throughout the project trip. -## ![Alt Text](../assets/outdoor.png) External Constraints +## ![Alt Text](../assets/outdoor.png) Constraints -> For each team member, we will explain the external constraints. +> For each team member, we will explain the constraints. ### _Salem πŸ‘€_ -| Constraint | Description | -|:------:|:-------:| -| Power & internet πŸ›œ | I have limited hours when power is available| -| Deadlines ❌ | I have college deadlines in addition to MET program deadlines| +| Constraint |Type | Description | +|:------:|:-------:|:-------:| +| Power & internet πŸ›œ |External| I have limited hours when power is available| +| Deadlines ❌ |External|I have college deadlines in addition to MET program deadlines| ### Nagham -| Constraint | Description | -|:------:|:-------:| +| Constraint |Type | Description | +|:------:|:-------:|:-------:| ### Nilson -| Constraint | Description | -|:------:|:-------:| +| Constraint |Type | Description | +|:------:|:-------:|:-------:| + +#### Summary + +> Summary of External constraints. ## ![indoor](../assets/limited-access.png) Internal: Involuntary +### Examples # Communication +> In this readme file, we try to list communication-related issues. + ______________________________________________________________________ ## Communication Schedule @@ -47,12 +41,14 @@ ______________________________________________________________________ ### Availability for calling/messaging πŸ’¬ -#### "βœ…" means "Available at any time" +- βœ… means "Available at any time" +- ❌ means "Not available" +- 🫑 means "On demand" | Name| Monday| Tuesday| Wednesday | Thursday | Friday| Saturday| Sunday| Timezone| |-------------|-------------|-------------|-------------|-------------|-------------|-------------|-------------|-------------| -| Nagham al baba| βœ… | βœ…| βœ… | βœ… | βœ…| βœ…| βœ…| After 4:00 EET | -| Salem Amassi | βœ…|βœ…|βœ… | 10:00–01:00| βœ…| 13:00–15:00 | Not available| EET (Palestine)| +| Nagham al baba| βœ… | βœ…| βœ… | βœ… | βœ…| βœ…| βœ…| After 4:00 EET| +| Salem Amassi | βœ…|🫑|βœ… | 10:00–13:00| Evening| 13:00–17:00 |❌ | EET (Palestine)| | Matvii Morozov| 12:00–15:00|12:00–15:00| 12:00–15:00| 12:00–15:00| 12:00–15:00|βœ…|βœ…|GMT+2| |Nelson Fodjo|18:00–20:00|18:00–20:00|18:00–20:00|18:00–20:00|18:00–20:00|18:00–20:00|18:00–20:00|WAT(GMT+1)| From 0caa5fcc91d5f32be02c049cbca2f7c803adefc6 Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sat, 4 Jan 2025 14:42:10 +0200 Subject: [PATCH 062/175] Add communication navigation --- collaboration/communication.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/collaboration/communication.md b/collaboration/communication.md index 8043f5377..9346cbd46 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -3,6 +3,13 @@ > In this readme file, we try to list communication-related issues. +## How to navigate this file? + +- [Communication Schedule](#communication-schedule) +- [Communication Channels](#communication-channels) +- [Availability](#availability) +- [Asking for Help](#asking-for-help) + ______________________________________________________________________ ## Communication Schedule From 4e4b79af5cbd8cbece3bcad609026d85f79bb9de Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sat, 4 Jan 2025 14:55:46 +0200 Subject: [PATCH 063/175] Add learning-goals navigation --- collaboration/learning_goals.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 0d6496123..a8beb9dd9 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -1,12 +1,15 @@ -# Objectives +# Objectives -## Crucial Skills to Build +>In this readme file, we list learning goals on the the team **404s** level and +**individual level** -- Master collaborative and independent coding workflows using Git and GitHub tools.πŸ› οΈ -- Focus on writing maintainable, thoroughly tested, and well-documented code.πŸ“ +## How to navigate? -## Group Objectives 🌟 +- [Group Objectives](#group-objectives) +- [Personal Objectives](#personal-objectives) + +## Group Objectives ### Excel in Git Collaboration πŸš€ @@ -38,7 +41,7 @@ - Start coding by writing tests to ensure reliability from the outset. - Collaborate to refine tests, covering edge cases and ensuring comprehensive coverage. -## Personal Objectives 🎯 +## Personal Objectives ### Salem's objectives @@ -53,3 +56,5 @@ ### Nagham's objectives ### Nilson's objectives + +### Matvii's objectives From 7c04cdebb98b59ac82b24b6bc2b4d2a5a9bd15e4 Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Sat, 4 Jan 2025 18:34:51 +0200 Subject: [PATCH 064/175] rename the file --- solutions/Find_largest_number.py | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 solutions/Find_largest_number.py diff --git a/solutions/Find_largest_number.py b/solutions/Find_largest_number.py deleted file mode 100644 index 55d005a00..000000000 --- a/solutions/Find_largest_number.py +++ /dev/null @@ -1,28 +0,0 @@ -""" -This module contains a function `largest_num` that takes a list of numbers -and returns the largest number from that list. - -The `largest_num` function checks if all elements in the input list are -numeric (either integers or floats). If the list is empty, it raises a -ValueError. The function returns the maximum number in the list using the -built-in `max()` function.""" - - -def largest_num(numbers): - """ - This function takes a list of numbers as input and returns the largest number. - - Parameters: - A list of numbers. - - Returns: - float: The largest number in the list. - """ - - if not all(isinstance(x, (int, float)) for x in numbers): - raise ValueError("All elements in the list must be numeric.") - - if not numbers: - raise ValueError("The list is empty.") - - return max(numbers) From 4ea88bef08263f0af5552585faf333c9c249f295 Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Sat, 4 Jan 2025 18:40:47 +0200 Subject: [PATCH 065/175] tt --- solutions/find_largest_number.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 solutions/find_largest_number.py diff --git a/solutions/find_largest_number.py b/solutions/find_largest_number.py new file mode 100644 index 000000000..55d005a00 --- /dev/null +++ b/solutions/find_largest_number.py @@ -0,0 +1,28 @@ +""" +This module contains a function `largest_num` that takes a list of numbers +and returns the largest number from that list. + +The `largest_num` function checks if all elements in the input list are +numeric (either integers or floats). If the list is empty, it raises a +ValueError. The function returns the maximum number in the list using the +built-in `max()` function.""" + + +def largest_num(numbers): + """ + This function takes a list of numbers as input and returns the largest number. + + Parameters: + A list of numbers. + + Returns: + float: The largest number in the list. + """ + + if not all(isinstance(x, (int, float)) for x in numbers): + raise ValueError("All elements in the list must be numeric.") + + if not numbers: + raise ValueError("The list is empty.") + + return max(numbers) From 2d9b87acc2d681f28326bb5c1b9fc31c5d56ea4c Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Sat, 4 Jan 2025 20:29:13 +0200 Subject: [PATCH 066/175] Adding --- solutions/__init__.py | 1 - solutions/python_calculator.py | 58 +++++++++++++++++++++++ solutions/tests/test_python_calculator.py | 50 +++++++++++++++++++ 3 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 solutions/python_calculator.py create mode 100644 solutions/tests/test_python_calculator.py diff --git a/solutions/__init__.py b/solutions/__init__.py index 8b1378917..e69de29bb 100644 --- a/solutions/__init__.py +++ b/solutions/__init__.py @@ -1 +0,0 @@ - diff --git a/solutions/python_calculator.py b/solutions/python_calculator.py new file mode 100644 index 000000000..7dc85e41a --- /dev/null +++ b/solutions/python_calculator.py @@ -0,0 +1,58 @@ +""" +Module: python_calculator + +This module contains a single function `calculate` that performs basic mathematical operations +(addition, subtraction, multiplication, and division) based on the provided operator. +""" + +from typing import Union + + +def calculate( + a: Union[int, float], b: Union[int, float], operator: str +) -> Union[int, float]: + """ + Perform a basic mathematical operation on two numbers based on the operator provided. + + Args: + a (int | float): The first operand. + b (int | float): The second operand. + operator (str): The operator specifying the operation. Must be one of: '+', '-', '*', '/'. + + Returns: + int | float: The result of the operation. + + Raises: + ValueError: If the operator is not one of the allowed operations. + ZeroDivisionError: If the operator is '/' and the second operand is zero. + + Examples: + >>> calculate(2, 3, '+') + 5 + >>> calculate(10, 4, '-') + 6 + >>> calculate(6, 3, '*') + 18 + >>> calculate(9, 3, '/') + 3.0 + """ + # Defensive assertions + if not isinstance(a, (int, float)): + raise TypeError("The first operand (a) must be an integer or a float.") + if not isinstance(b, (int, float)): + raise TypeError("The second operand (b) must be an integer or a float.") + if operator not in ["+", "-", "*", "/"]: + raise ValueError("Operator must be one of '+', '-', '*', '/'.") + + if operator == "/" and b == 0: + raise ZeroDivisionError("Division by zero is not allowed.") + + # Perform the operation + if operator == "+": + return a + b + elif operator == "-": + return a - b + elif operator == "*": + return a * b + elif operator == "/": + return a / b diff --git a/solutions/tests/test_python_calculator.py b/solutions/tests/test_python_calculator.py new file mode 100644 index 000000000..e64167e48 --- /dev/null +++ b/solutions/tests/test_python_calculator.py @@ -0,0 +1,50 @@ +""" +Unit Tests for the `calculate` function in the `python_calculator` module. +""" + +import unittest +from solutions.python_calculator import calculate + + +class TestPythonCalculator(unittest.TestCase): + """ + Unit tests for the `calculate` function. + """ + + def test_addition(self): + """Test addition operation.""" + self.assertEqual(calculate(2, 3, "+"), 5) + + def test_subtraction(self): + """Test subtraction operation.""" + self.assertEqual(calculate(10, 4, "-"), 6) + + def test_multiplication(self): + """Test multiplication operation.""" + self.assertEqual(calculate(6, 3, "*"), 18) + + def test_division(self): + """Test division operation.""" + self.assertEqual(calculate(9, 3, "/"), 3.0) + + def test_division_by_zero(self): + """Test division by zero raises ZeroDivisionError.""" + with self.assertRaises(ZeroDivisionError): + calculate(10, 0, "/") + + def test_invalid_operator(self): + """Test invalid operator raises ValueError.""" + with self.assertRaises(ValueError): + calculate(10, 5, "%") + + def test_invalid_operand_type(self): + """Test invalid operand types raise TypeError.""" + with self.assertRaises(TypeError): + calculate("10", 5, "+") + with self.assertRaises(TypeError): + calculate(10, "5", "+") + + def test_boundary_cases(self): + """Test boundary cases (e.g., very large or small numbers).""" + self.assertAlmostEqual(calculate(1e308, 1e308, "+"), float("inf")) + self.assertEqual(calculate(0, 0, "+"), 0) From ed8e207386fab6462d508c5015f81219000de580 Mon Sep 17 00:00:00 2001 From: matopcheg Date: Sun, 5 Jan 2025 13:45:07 +0200 Subject: [PATCH 067/175] added personal info --- collaboration/constraints.md | 7 +++++++ collaboration/learning_goals.md | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index fe31dcc3f..7b310788f 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -24,6 +24,13 @@ | Constraint |Type | Description | |:------:|:-------:|:-------:| +### Matvii 😊 + +| Constraint |Type | Description | +|:------:|:-------:|:-------:| +| Deadlines ❌ |External|I have exams so I might not as active as I stated in the availability table| +| Power & internet πŸ›œ |External| Due to missile attacks I might not have unlimited access to electricity| + #### Summary > Summary of External constraints. diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index a8beb9dd9..4fa0c796e 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -58,3 +58,9 @@ ### Nilson's objectives ### Matvii's objectives + +| **Goal** | **Description** | **Progress** | +|------------------------------------|----------------| ----------------| +| Fully understand how GIT system works |Practice more and more to became fully aware of how the GIT and GitHub work | ![40%](https://progress-bar.xyz/40) | +| Level up my English speaking skill |Communication with a team helps a lot!| ![50%](https://progress-bar.xyz/50) | +| Learn how to review any code |Choose each code and describe it to myself | ![55%](https://progress-bar.xyz/55) | \ No newline at end of file From 25fdd819ccbded07f3c24f667ca32ac8c4120ea5 Mon Sep 17 00:00:00 2001 From: matopcheg Date: Sun, 5 Jan 2025 13:49:04 +0200 Subject: [PATCH 068/175] fix line length --- collaboration/learning_goals.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 4fa0c796e..2be228236 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -63,4 +63,6 @@ |------------------------------------|----------------| ----------------| | Fully understand how GIT system works |Practice more and more to became fully aware of how the GIT and GitHub work | ![40%](https://progress-bar.xyz/40) | | Level up my English speaking skill |Communication with a team helps a lot!| ![50%](https://progress-bar.xyz/50) | -| Learn how to review any code |Choose each code and describe it to myself | ![55%](https://progress-bar.xyz/55) | \ No newline at end of file +| Learn how to review any code |Choose each code and describe it to myself | ![55%](https://progress-bar.xyz/55) | + +--- \ No newline at end of file From d9f1be78da8704060340e60669cf779a0083bf7c Mon Sep 17 00:00:00 2001 From: matopcheg Date: Sun, 5 Jan 2025 13:54:03 +0200 Subject: [PATCH 069/175] fix formatting errors --- collaboration/constraints.md | 4 ++-- collaboration/learning_goals.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 7b310788f..5b9c6b4fc 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -28,8 +28,8 @@ | Constraint |Type | Description | |:------:|:-------:|:-------:| -| Deadlines ❌ |External|I have exams so I might not as active as I stated in the availability table| -| Power & internet πŸ›œ |External| Due to missile attacks I might not have unlimited access to electricity| +| Deadlines ❌|External|University exams| +| Power & internet πŸ›œ|External|I might not have unlimited access to electricity| #### Summary diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 2be228236..86d665e77 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -65,4 +65,4 @@ | Level up my English speaking skill |Communication with a team helps a lot!| ![50%](https://progress-bar.xyz/50) | | Learn how to review any code |Choose each code and describe it to myself | ![55%](https://progress-bar.xyz/55) | ---- \ No newline at end of file +--- From a54be4d7cf43e94de8904bca9a68927b3050faf1 Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Sun, 5 Jan 2025 16:55:11 +0200 Subject: [PATCH 070/175] update constraints --- collaboration/constraints.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 5b9c6b4fc..ee9987448 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -18,6 +18,8 @@ | Constraint |Type | Description | |:------:|:-------:|:-------:| +| internet πŸ›œ |External|Internet is Not always available| +| Time Zone Differences πŸ•’|External|It causes conflicts and delays progress| ### Nilson From 0f2f1284a19eeb53d835c076509e9577fd5235bf Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Sun, 5 Jan 2025 17:03:05 +0200 Subject: [PATCH 071/175] update learning goals --- collaboration/learning_goals.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 86d665e77..8968fc727 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -55,6 +55,12 @@ ### Nagham's objectives +| **Goal** | **Description** | **Progress** | +|------------------------------------|-----------------|--------------| +| πŸ”Strengthen Algorithmic Thinking | Improve problem-solving | ![55%](https://progress-bar.xyz/55)| +| πŸ› οΈMaster Git and GitHub | Master version control and teamwork | ![20%](https://progress-bar.xyz/20) | +| πŸ’»Refine Coding Practices | Write cleanand well-documented code | ![70%](https://progress-bar.xyz/70) | + ### Nilson's objectives ### Matvii's objectives From a5b9e40a9787919d52b7f7bf616b264bf5e08bf1 Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Mon, 6 Jan 2025 15:01:19 +0200 Subject: [PATCH 072/175] Fix import error --- solutions/tests/test_find_largest_number.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/solutions/tests/test_find_largest_number.py b/solutions/tests/test_find_largest_number.py index bd218e1d9..d6f45b590 100644 --- a/solutions/tests/test_find_largest_number.py +++ b/solutions/tests/test_find_largest_number.py @@ -6,8 +6,10 @@ """ import unittest +import sys -from solutions.find_largest_number import largest_num +sys.path.append("../") +from find_largest_number import largest_num class TestLargestNum(unittest.TestCase): From fe5f9fd78af1274703f17b853162c2934b3f645d Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Mon, 6 Jan 2025 15:14:38 +0200 Subject: [PATCH 073/175] Fix import error --- solutions/tests/test_find_largest_number.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_find_largest_number.py b/solutions/tests/test_find_largest_number.py index d6f45b590..d57d356ee 100644 --- a/solutions/tests/test_find_largest_number.py +++ b/solutions/tests/test_find_largest_number.py @@ -9,7 +9,7 @@ import sys sys.path.append("../") -from find_largest_number import largest_num +from ..find_largest_number import largest_num class TestLargestNum(unittest.TestCase): From 20efb7eee8482fbab88b15e6b3b1fad9f2215a5b Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Tue, 7 Jan 2025 01:17:15 +0200 Subject: [PATCH 074/175] change the function name to meet file name add type annotation in function --- solutions/find_largest_number.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/find_largest_number.py b/solutions/find_largest_number.py index 55d005a00..fea6ce1d5 100644 --- a/solutions/find_largest_number.py +++ b/solutions/find_largest_number.py @@ -8,7 +8,7 @@ built-in `max()` function.""" -def largest_num(numbers): +def find_largest_num(numbers) -> float: """ This function takes a list of numbers as input and returns the largest number. From 063d1c4ea10541121d467e02002cf7777d2c0f9c Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Tue, 7 Jan 2025 01:18:42 +0200 Subject: [PATCH 075/175] change the function name to meet file name >> add type annotation in function --- solutions/tests/test_find_largest_number.py | 34 ++++++++++----------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/solutions/tests/test_find_largest_number.py b/solutions/tests/test_find_largest_number.py index d57d356ee..af51e7d90 100644 --- a/solutions/tests/test_find_largest_number.py +++ b/solutions/tests/test_find_largest_number.py @@ -9,7 +9,7 @@ import sys sys.path.append("../") -from ..find_largest_number import largest_num +from ..find_largest_number import find_largest_num class TestLargestNum(unittest.TestCase): @@ -18,39 +18,39 @@ class TestLargestNum(unittest.TestCase): across positive, negative, mixed, single-element, duplicate, and empty lists. """ - def test_positive_numbers(self): + def test_positive_numbers(self) -> None: """Test case for a list of positive numbers.""" - self.assertEqual(largest_num([3, 9, 2, 3, 2]), 9) + self.assertEqual(find_largest_num([3, 9, 2, 3, 2]), 9) - def test_negative_numbers(self): + def test_negative_numbers(self) -> None: """Test case for a list of negative numbers.""" - self.assertEqual(largest_num([-3, -1, -2, -7, -8]), -1) + self.assertEqual(find_largest_num([-3, -1, -2, -7, -8]), -1) - def test_mixed_numbers(self): + def test_mixed_numbers(self) -> None: """Test case for a list of mixed positive and negative numbers.""" - self.assertEqual(largest_num([4, -9, 3, -8, 5]), 5) + self.assertEqual(find_largest_num([4, -9, 3, -8, 5]), 5) - def test_single_element(self): + def test_single_element(self) -> None: """Test case for a list with a single element.""" - self.assertEqual(largest_num([100]), 100) + self.assertEqual(find_largest_num([100]), 100) - def test_duplicates(self): + def test_duplicates(self) -> None: """Test case for a list with duplicate numbers.""" - self.assertEqual(largest_num([1, 1, 1, 1]), 1) + self.assertEqual(find_largest_num([1, 1, 1, 1]), 1) - def test_empty_list(self): + def test_empty_list(self) -> None: """Test case for an empty list (should raise ValueError).""" with self.assertRaises(ValueError): - largest_num([]) + find_largest_num([]) - def test_non_numeric_input(self): + def test_non_numeric_input(self) -> None: """Test case for non-numeric input (should raise ValueError).""" with self.assertRaises(ValueError): - largest_num(["a", "b", "c"]) + find_largest_num(["a", "b", "c"]) - def test_large_numbers(self): + def test_large_numbers(self) -> None: """Test case for large numbers.""" - self.assertEqual(largest_num([1e10, 1e15, 1e11]), 1e15) + self.assertEqual(find_largest_num([1e10, 1e15, 1e11]), 1e15) if __name__ == "__main__": From 71eb0bbeadd168a0884684837e22f2b83c89de15 Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Tue, 7 Jan 2025 01:29:30 +0200 Subject: [PATCH 076/175] trying to solve the import error again --- solutions/tests/test_find_largest_number.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_find_largest_number.py b/solutions/tests/test_find_largest_number.py index af51e7d90..9d152ed08 100644 --- a/solutions/tests/test_find_largest_number.py +++ b/solutions/tests/test_find_largest_number.py @@ -9,7 +9,7 @@ import sys sys.path.append("../") -from ..find_largest_number import find_largest_num +from solutions.find_largest_number import find_largest_num class TestLargestNum(unittest.TestCase): From f4497727c2953d274f7d851c8dc0346c4f32e24a Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Tue, 7 Jan 2025 01:47:44 +0200 Subject: [PATCH 077/175] rename the function --- solutions/find_largest_number.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solutions/find_largest_number.py b/solutions/find_largest_number.py index fea6ce1d5..a9dcf7dec 100644 --- a/solutions/find_largest_number.py +++ b/solutions/find_largest_number.py @@ -1,14 +1,14 @@ """ -This module contains a function `largest_num` that takes a list of numbers +This module contains a function `find_largest_number` that takes a list of numbers and returns the largest number from that list. -The `largest_num` function checks if all elements in the input list are +The `find_largest_number` function checks if all elements in the input list are numeric (either integers or floats). If the list is empty, it raises a ValueError. The function returns the maximum number in the list using the built-in `max()` function.""" -def find_largest_num(numbers) -> float: +def find_largest_number(numbers) -> float: """ This function takes a list of numbers as input and returns the largest number. From eba7abf08f43c16f85dc0572e800c6ecbeb46a1a Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Tue, 7 Jan 2025 01:49:30 +0200 Subject: [PATCH 078/175] fix error --- solutions/tests/test_find_largest_number.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/solutions/tests/test_find_largest_number.py b/solutions/tests/test_find_largest_number.py index 9d152ed08..db5b2efb0 100644 --- a/solutions/tests/test_find_largest_number.py +++ b/solutions/tests/test_find_largest_number.py @@ -9,7 +9,7 @@ import sys sys.path.append("../") -from solutions.find_largest_number import find_largest_num +from solutions.find_largest_number import find_largest_number class TestLargestNum(unittest.TestCase): @@ -20,37 +20,37 @@ class TestLargestNum(unittest.TestCase): def test_positive_numbers(self) -> None: """Test case for a list of positive numbers.""" - self.assertEqual(find_largest_num([3, 9, 2, 3, 2]), 9) + self.assertEqual(find_largest_number([3, 9, 2, 3, 2]), 9) def test_negative_numbers(self) -> None: """Test case for a list of negative numbers.""" - self.assertEqual(find_largest_num([-3, -1, -2, -7, -8]), -1) + self.assertEqual(find_largest_number([-3, -1, -2, -7, -8]), -1) def test_mixed_numbers(self) -> None: """Test case for a list of mixed positive and negative numbers.""" - self.assertEqual(find_largest_num([4, -9, 3, -8, 5]), 5) + self.assertEqual(find_largest_number([4, -9, 3, -8, 5]), 5) def test_single_element(self) -> None: """Test case for a list with a single element.""" - self.assertEqual(find_largest_num([100]), 100) + self.assertEqual(find_largest_number([100]), 100) def test_duplicates(self) -> None: """Test case for a list with duplicate numbers.""" - self.assertEqual(find_largest_num([1, 1, 1, 1]), 1) + self.assertEqual(find_largest_number([1, 1, 1, 1]), 1) def test_empty_list(self) -> None: """Test case for an empty list (should raise ValueError).""" with self.assertRaises(ValueError): - find_largest_num([]) + find_largest_number([]) def test_non_numeric_input(self) -> None: """Test case for non-numeric input (should raise ValueError).""" with self.assertRaises(ValueError): - find_largest_num(["a", "b", "c"]) + find_largest_number(["a", "b", "c"]) def test_large_numbers(self) -> None: """Test case for large numbers.""" - self.assertEqual(find_largest_num([1e10, 1e15, 1e11]), 1e15) + self.assertEqual(find_largest_number([1e10, 1e15, 1e11]), 1e15) if __name__ == "__main__": From 2bc905f8cd1164ec1472445d635c81bea9806342 Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Tue, 7 Jan 2025 02:41:05 +0200 Subject: [PATCH 079/175] fix the error --- solutions/tests/test_find_largest_number.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/solutions/tests/test_find_largest_number.py b/solutions/tests/test_find_largest_number.py index db5b2efb0..f94823db2 100644 --- a/solutions/tests/test_find_largest_number.py +++ b/solutions/tests/test_find_largest_number.py @@ -2,19 +2,19 @@ Unit tests for the largest_num function in the Find_largest_number module. This module contains a set of test cases to ensure the correctness of the -largest_num function, which identifies the largest number in a given list. +find_largest_number function, which identifies the largest number in a given list. """ import unittest -import sys +# import sys -sys.path.append("../") +# sys.path.append("../") from solutions.find_largest_number import find_largest_number class TestLargestNum(unittest.TestCase): """ - Unit tests for the largest_num() function, verifying its correctness + Unit tests for the find_largest_number function, verifying its correctness across positive, negative, mixed, single-element, duplicate, and empty lists. """ From 0f8cab802eaa237bf2e53b42f5b1f133f689ce9e Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Tue, 7 Jan 2025 14:26:25 +0100 Subject: [PATCH 080/175] Update constraints.md Added some informations on observed contraints --- collaboration/constraints.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 24079505c..459964815 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -15,6 +15,7 @@ Some boundaries around our project. - ... --> +- **Connectivity issues**: Some team members may experience unreliable network connections, impacting real-time collaboration. ## Internal: Involuntary -## Internal: Voluntary +- **Individual skill levels**: The team has varying levels of programming expertise, which may affect task assignments and peer reviews. +- **Available time for project work**: Due to significant time zone differences, scheduling meetings can be challenging. +## Internal: Voluntary + +- **Coding style & conventions**: Agree on a set of guidelines for consistency across the codebase. +- **Code review checklist**: Create a checklist to ensure thorough reviews while accommodating varying skill levels. +- **Desired hours to work per week**: Establish a flexible schedule that considers team members' availability, possibly utilizing asynchronous communication. + + From a3185c96025411ba660e0e6089a4379f72e54381 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Tue, 7 Jan 2025 15:53:30 +0100 Subject: [PATCH 081/175] Update constraints.md --- collaboration/constraints.md | 1 + 1 file changed, 1 insertion(+) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 459964815..bc075beeb 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -16,6 +16,7 @@ Some boundaries around our project. --> - **Connectivity issues**: Some team members may experience unreliable network connections, impacting real-time collaboration. + ## Internal: Involuntary -- **Connectivity issues**: Some team members may experience unreliable network connections, impacting real-time collaboration. +- **Connectivity issues**: Some team members may experience unreliable network + connections, impacting real-time collaboration. ## Internal: Involuntary @@ -25,10 +26,13 @@ Some boundaries around our project. - amount of time available to work on the project --> -- **Individual skill levels**: The team has varying levels of programming expertise, which may affect task assignments and peer reviews. -- **Available time for project work**: Due to significant time zone differences, scheduling meetings can be challenging. +- **Individual skill levels**: The team has varying levels of + programming expertise which may affect task assignments and peer reviews. +- **Available time for project work**: Due to significant time zone + differences, scheduling meetings can be challenging. ## Internal: Voluntary + -- **Coding style & conventions**: Agree on a set of guidelines for consistency across the codebase. -- **Code review checklist**: Create a checklist to ensure thorough reviews while accommodating varying skill levels. -- **Desired hours to work per week**: Establish a flexible schedule that considers team members' availability, possibly utilizing asynchronous communication. +- **Coding style & conventions**: Agree on a set of guidelines for + consistency across the codebase. +- **Code review checklist**: Create a checklist to ensure thorough + reviews while accommodating varying skill levels. +- **Desired hours to work per week**: Establish a flexible schedule + that considers team members' availability, possibly utilizing + asynchronous communication. + From 8f774f08fef7bd826cc25c2ffc640f626d884823 Mon Sep 17 00:00:00 2001 From: matopcheg Date: Wed, 8 Jan 2025 17:12:45 +0200 Subject: [PATCH 088/175] remove blank lines --- collaboration/constraints.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index d970f5639..e6ad988e2 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -48,6 +48,3 @@ Some boundaries around our project. - **Desired hours to work per week**: Establish a flexible schedule that considers team members' availability, possibly utilizing asynchronous communication. - - - From 3b1837fd3da1ba2192f4929c6ed56f04e42c04e9 Mon Sep 17 00:00:00 2001 From: matopcheg Date: Wed, 8 Jan 2025 17:20:50 +0200 Subject: [PATCH 089/175] minor fixes --- collaboration/constraints.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index e6ad988e2..07ffb1390 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -41,8 +41,8 @@ Some boundaries around our project. - only using the colors black and white --> -- **Coding style & conventions**: Agree on a set of guidelines for - consistency across the codebase. +- **Coding style & conventions**: Agree on a set of guidelines + for consistency across the codebase. - **Code review checklist**: Create a checklist to ensure thorough reviews while accommodating varying skill levels. - **Desired hours to work per week**: Establish a flexible schedule From b7677a09159016b916b541fb9c23be54e9de215b Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Wed, 8 Jan 2025 17:33:22 +0200 Subject: [PATCH 090/175] fix import error --- solutions/tests/test_find_largest_number.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_find_largest_number.py b/solutions/tests/test_find_largest_number.py index f94823db2..c37ceeb1a 100644 --- a/solutions/tests/test_find_largest_number.py +++ b/solutions/tests/test_find_largest_number.py @@ -6,8 +6,8 @@ """ import unittest -# import sys +# import sys # sys.path.append("../") from solutions.find_largest_number import find_largest_number From 15d2a1d73bf6c032e4fa7d084c03125b84f956a9 Mon Sep 17 00:00:00 2001 From: matopcheg Date: Wed, 8 Jan 2025 17:45:08 +0200 Subject: [PATCH 091/175] Revert "Merge branch 'main' of https://github.com/MIT-Emerging-Talent/ET6-foundations-group-20 into palindrome" This reverts commit e07916478abaa1a92a27214bbd3bc3c19c038b21, reversing changes made to 74b3e41865788632b290f386c6b962a2d18da8f8. --- solutions/is_palindrome.py | 30 ------------------- solutions/tests/test_is_palindrome.py | 42 --------------------------- 2 files changed, 72 deletions(-) delete mode 100644 solutions/is_palindrome.py delete mode 100644 solutions/tests/test_is_palindrome.py diff --git a/solutions/is_palindrome.py b/solutions/is_palindrome.py deleted file mode 100644 index 49d2978c5..000000000 --- a/solutions/is_palindrome.py +++ /dev/null @@ -1,30 +0,0 @@ -class Solution(object): - def is_palindrome(self, x: int) -> bool: - """ - Check if the given integer is a palindrome. - - A palindrome is a number that reads the same backward as forward. - - :param x: Integer to check - :type x: int - :raises ValueError: If the input is not an integer. - :return: True if the integer is a palindrome, False otherwise - :rtype: bool - - Examples: - >>> s = Solution() - >>> s.is_palindrome(121) - True - >>> s.is_palindrome(-121) - False - >>> s.is_palindrome(10) - False - """ - - # Negative numbers cannot be palindromes - if x < 0: - return False - - # Comparing number's string with its reverse - str_x = str(x) - return str_x == str_x[::-1] diff --git a/solutions/tests/test_is_palindrome.py b/solutions/tests/test_is_palindrome.py deleted file mode 100644 index 4b1f2608b..000000000 --- a/solutions/tests/test_is_palindrome.py +++ /dev/null @@ -1,42 +0,0 @@ -import unittest -from solutions.is_palindrome import Solution - - -class TestIsPalindrome(unittest.TestCase): - """ - Unit tests for the is_palindrome function in the Solution class. - """ - - def setUp(self): - """ - Set up the test case environment by initializing a Solution object. - """ - self.solution = Solution() - - def test_positive_palindrome(self): - """ - Test that the function returns True for a positive palindrome number. - """ - self.assertTrue(self.solution.is_palindrome(121)) - - def test_negative_number(self): - """ - Test that the function returns False for a negative number. - """ - self.assertFalse(self.solution.is_palindrome(-121)) - - def test_non_palindrome(self): - """ - Test that the function returns False for a number that is not a palindrome. - """ - self.assertFalse(self.solution.is_palindrome(123)) - - def test_single_digit(self): - """ - Test that the function returns True for a single-digit number. - """ - self.assertTrue(self.solution.is_palindrome(7)) - - -if __name__ == "__main__": - unittest.main() From 43f2ef89e4d491c3db9a83ebc78c204d9c7e8aff Mon Sep 17 00:00:00 2001 From: matopcheg Date: Wed, 8 Jan 2025 17:50:11 +0200 Subject: [PATCH 092/175] Restore palindrome files after revert --- solutions/is_palindrome.py | 30 +++++++++++++++++++ solutions/tests/test_is_palindrome.py | 42 +++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 solutions/is_palindrome.py create mode 100644 solutions/tests/test_is_palindrome.py diff --git a/solutions/is_palindrome.py b/solutions/is_palindrome.py new file mode 100644 index 000000000..49d2978c5 --- /dev/null +++ b/solutions/is_palindrome.py @@ -0,0 +1,30 @@ +class Solution(object): + def is_palindrome(self, x: int) -> bool: + """ + Check if the given integer is a palindrome. + + A palindrome is a number that reads the same backward as forward. + + :param x: Integer to check + :type x: int + :raises ValueError: If the input is not an integer. + :return: True if the integer is a palindrome, False otherwise + :rtype: bool + + Examples: + >>> s = Solution() + >>> s.is_palindrome(121) + True + >>> s.is_palindrome(-121) + False + >>> s.is_palindrome(10) + False + """ + + # Negative numbers cannot be palindromes + if x < 0: + return False + + # Comparing number's string with its reverse + str_x = str(x) + return str_x == str_x[::-1] diff --git a/solutions/tests/test_is_palindrome.py b/solutions/tests/test_is_palindrome.py new file mode 100644 index 000000000..4b1f2608b --- /dev/null +++ b/solutions/tests/test_is_palindrome.py @@ -0,0 +1,42 @@ +import unittest +from solutions.is_palindrome import Solution + + +class TestIsPalindrome(unittest.TestCase): + """ + Unit tests for the is_palindrome function in the Solution class. + """ + + def setUp(self): + """ + Set up the test case environment by initializing a Solution object. + """ + self.solution = Solution() + + def test_positive_palindrome(self): + """ + Test that the function returns True for a positive palindrome number. + """ + self.assertTrue(self.solution.is_palindrome(121)) + + def test_negative_number(self): + """ + Test that the function returns False for a negative number. + """ + self.assertFalse(self.solution.is_palindrome(-121)) + + def test_non_palindrome(self): + """ + Test that the function returns False for a number that is not a palindrome. + """ + self.assertFalse(self.solution.is_palindrome(123)) + + def test_single_digit(self): + """ + Test that the function returns True for a single-digit number. + """ + self.assertTrue(self.solution.is_palindrome(7)) + + +if __name__ == "__main__": + unittest.main() From 7278b3715c5588f81535c6a692e75604238b8962 Mon Sep 17 00:00:00 2001 From: matopcheg Date: Wed, 8 Jan 2025 17:56:32 +0200 Subject: [PATCH 093/175] add comments, docstrings; describe logic; change file name --- solutions/is_palindrome.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/solutions/is_palindrome.py b/solutions/is_palindrome.py index 49d2978c5..a5a93a7ee 100644 --- a/solutions/is_palindrome.py +++ b/solutions/is_palindrome.py @@ -1,3 +1,7 @@ +""" +This module provides a solution for checking if a number is a palindrome. +""" + class Solution(object): def is_palindrome(self, x: int) -> bool: """ From 5faee3d7095d5a83bb615563ccd124e1d80663cd Mon Sep 17 00:00:00 2001 From: matopcheg Date: Wed, 8 Jan 2025 17:57:43 +0200 Subject: [PATCH 094/175] fix ruff formatting --- solutions/is_palindrome.py | 1 + 1 file changed, 1 insertion(+) diff --git a/solutions/is_palindrome.py b/solutions/is_palindrome.py index a5a93a7ee..339a15dcc 100644 --- a/solutions/is_palindrome.py +++ b/solutions/is_palindrome.py @@ -2,6 +2,7 @@ This module provides a solution for checking if a number is a palindrome. """ + class Solution(object): def is_palindrome(self, x: int) -> bool: """ From 9239f78bd33e1f331a481d78f52379797aa8f8c2 Mon Sep 17 00:00:00 2001 From: matopcheg Date: Thu, 9 Jan 2025 14:08:32 +0200 Subject: [PATCH 095/175] change line length --- collaboration/constraints.md | 38 +++++++++++++++++++-------------- collaboration/learning_goals.md | 4 ++-- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 90571457f..bf70292e3 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -1,6 +1,7 @@ # ![Alt Text](../assets/task-planner.png) Constraints -> In this readme, we explain potential **constraints** that limit our productivity and achievement throughout the project. +> In this readme, we explain potential **constraints** that +limit our productivity and achievement throughout the project. ## ![Alt Text](../assets/outdoor.png) Constraints @@ -8,35 +9,36 @@ ### _Salem πŸ‘€_ -| Constraint | Type | Description | +| Constraint | Type | Description| |:-------------------:|:--------:|:--------------------------------------------------:| -| Power & internet πŸ›œ | External | I have limited hours when power is available. | -| Deadlines ❌ | External | I have college deadlines in addition to MET program deadlines. | +| Power & internet πŸ›œ | External | I have limited hours when power is available.| +| Deadlines ❌ | External | I have college deadlines in addition to MET program deadlines.| ### Nagham | Constraint | Type | Description | -|:-------------------:|:--------:|:--------------------------------------------------:| -| Internet πŸ›œ | External | Internet is not always available. | -| Time Zone Differences πŸ•’ | External | It causes conflicts and delays progress. | +|:-------------------:|:--------:|:---------------------------------:| +| Internet πŸ›œ | External | Internet is not always available. | +| Time Zone Differences πŸ•’ | External | It causes conflicts and delays progress.| ### Nelson -| Constraint | Type | Description | +| Constraint | Type | Description| |:-------------------:|:--------:|:---------------------------------------------:| | Deadline issues ❌ | External | I am preparing my application for college. | | GitHub knowledge ❓ | Internal | I do not know how to use GitHub effectively.| ### Matvii 😊 -| Constraint | Type | Description | -|:-------------------:|:--------:|:--------------------------------------------------:| -| Deadlines ❌ | External | University exams. | -| Power & internet πŸ›œ | External | I might not have unlimited access to electricity. | +| Constraint | Type | Description| +|:-------------------:|:--------:|:--------------------------:| +| Deadlines ❌| External | University exams.| +| Power & internet πŸ›œ| External | I might not have unlimited access to electricity.| #### Summary > Summary of External constraints. + - **Connectivity issues**: Some team members may experience unreliable network connections impacting real-time collaboration @@ -66,8 +68,12 @@ ## ![indoor](../assets/scope.png) Internal: Voluntary -blablab + -- **Coding style & conventions**: Agree on a set of guidelines for consistency across the codebase. -- **Code review checklist**: Create a checklist to ensure thorough reviews while accommodating varying skill levels. -- **Desired hours to work per week**: Establish a flexible schedule that considers team members' availability, possibly utilizing asynchronous communication. +- **Coding style & conventions**: Agree on a set of guidelines +for consistency across the codebase. +- **Code review checklist**: Create a checklist to ensure thorough reviews +while accommodating varying skill levels. +- **Desired hours to work per week**: Establish a flexible schedule that considers +team members' availability, possibly utilizing asynchronous communication. diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 8968fc727..105615875 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -61,7 +61,7 @@ | πŸ› οΈMaster Git and GitHub | Master version control and teamwork | ![20%](https://progress-bar.xyz/20) | | πŸ’»Refine Coding Practices | Write cleanand well-documented code | ![70%](https://progress-bar.xyz/70) | -### Nilson's objectives +### Nelson's objectives ### Matvii's objectives @@ -69,6 +69,6 @@ |------------------------------------|----------------| ----------------| | Fully understand how GIT system works |Practice more and more to became fully aware of how the GIT and GitHub work | ![40%](https://progress-bar.xyz/40) | | Level up my English speaking skill |Communication with a team helps a lot!| ![50%](https://progress-bar.xyz/50) | -| Learn how to review any code |Choose each code and describe it to myself | ![55%](https://progress-bar.xyz/55) | +| Learn how to review any code |Choose each code and describe it to myself | ![60%](https://progress-bar.xyz/55) | --- From 68f7bee8f25a4c1c5e90fd92921ee6f3b703ab2c Mon Sep 17 00:00:00 2001 From: matopcheg Date: Thu, 9 Jan 2025 14:12:47 +0200 Subject: [PATCH 096/175] delete trailing spaces --- collaboration/constraints.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index bf70292e3..47775bdd2 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -1,6 +1,6 @@ # ![Alt Text](../assets/task-planner.png) Constraints -> In this readme, we explain potential **constraints** that +> In this readme, we explain potential **constraints** that limit our productivity and achievement throughout the project. ## ![Alt Text](../assets/outdoor.png) Constraints @@ -68,12 +68,12 @@ limit our productivity and achievement throughout the project. ## ![indoor](../assets/scope.png) Internal: Voluntary -blablab -- **Coding style & conventions**: Agree on a set of guidelines +- **Coding style & conventions**: Agree on a set of guidelines for consistency across the codebase. -- **Code review checklist**: Create a checklist to ensure thorough reviews +- **Code review checklist**: Create a checklist to ensure thorough reviews while accommodating varying skill levels. -- **Desired hours to work per week**: Establish a flexible schedule that considers -team members' availability, possibly utilizing asynchronous communication. +- **Desired hours to work per week**: Establish a flexible schedule that +considers team members' availability, possibly utilizing asynchronous communication. From 1aa706a179a8165d86ce880e1b68a77ab1ef04c3 Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Thu, 9 Jan 2025 14:17:10 +0200 Subject: [PATCH 097/175] Fix issue in constraints --- assets/internal-voluntary-constraints.png | Bin 15208 -> 19400 bytes collaboration/constraints.md | 44 +++++++++++----------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/assets/internal-voluntary-constraints.png b/assets/internal-voluntary-constraints.png index fafd1ada06d1ffb071c32b328d01b92d8c5b721e..069ee71342d436f0856b3e3807098701a869e71f 100644 GIT binary patch literal 19400 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 diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 47775bdd2..7d4b7e78c 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -1,7 +1,6 @@ # ![Alt Text](../assets/task-planner.png) Constraints -> In this readme, we explain potential **constraints** that -limit our productivity and achievement throughout the project. +> In this readme, we explain potential **constraints** that limit our productivity and achievement throughout the project. ## ![Alt Text](../assets/outdoor.png) Constraints @@ -9,36 +8,34 @@ limit our productivity and achievement throughout the project. ### _Salem πŸ‘€_ -| Constraint | Type | Description| +| Constraint | Type | Description | |:-------------------:|:--------:|:--------------------------------------------------:| -| Power & internet πŸ›œ | External | I have limited hours when power is available.| -| Deadlines ❌ | External | I have college deadlines in addition to MET program deadlines.| +| Power & internet πŸ›œ | External | I have limited hours when power is available. | +| Deadlines ❌ | External | I have college deadlines in addition to MET program deadlines. | ### Nagham | Constraint | Type | Description | -|:-------------------:|:--------:|:---------------------------------:| -| Internet πŸ›œ | External | Internet is not always available. | -| Time Zone Differences πŸ•’ | External | It causes conflicts and delays progress.| +|:-------------------:|:--------:|:--------------------------------------------------:| +| Internet πŸ›œ | External | Internet is not always available. | +| Time Zone Differences πŸ•’ | External | It causes conflicts and delays progress. | ### Nelson -| Constraint | Type | Description| +| Constraint | Type | Description | |:-------------------:|:--------:|:---------------------------------------------:| | Deadline issues ❌ | External | I am preparing my application for college. | | GitHub knowledge ❓ | Internal | I do not know how to use GitHub effectively.| ### Matvii 😊 -| Constraint | Type | Description| -|:-------------------:|:--------:|:--------------------------:| -| Deadlines ❌| External | University exams.| -| Power & internet πŸ›œ| External | I might not have unlimited access to electricity.| +| Constraint | Type | Description | +|:-------------------:|:--------:|:--------------------------------------------------:| +| Deadlines ❌ | External | University exams. | +| Power & internet πŸ›œ | External | I might not have unlimited access to electricity. | #### Summary -> Summary of External constraints. - - **Connectivity issues**: Some team members may experience unreliable network connections impacting real-time collaboration @@ -68,12 +65,13 @@ limit our productivity and achievement throughout the project. ## ![indoor](../assets/scope.png) Internal: Voluntary - +blablab -- **Coding style & conventions**: Agree on a set of guidelines -for consistency across the codebase. -- **Code review checklist**: Create a checklist to ensure thorough reviews -while accommodating varying skill levels. -- **Desired hours to work per week**: Establish a flexible schedule that -considers team members' availability, possibly utilizing asynchronous communication. +- **Collaboration Constraints**: +- **Quality Assurance Constraints**: +- **Documentation Constraints**: +- **Coding style & conventions**: Agree on a set of guidelines for consistency + across the codebase. +- **Working hours**: Establish a flexible schedule that + considers team members' availability, possibly utilizing asynchronous communication. From ce8b40f6716d8416989908a9e723eba73ad172ad Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Thu, 9 Jan 2025 23:20:57 +0100 Subject: [PATCH 098/175] Update constraints.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just added a sticker on my name πŸ˜… --- collaboration/constraints.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 7d4b7e78c..446b9a316 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -20,7 +20,7 @@ | Internet πŸ›œ | External | Internet is not always available. | | Time Zone Differences πŸ•’ | External | It causes conflicts and delays progress. | -### Nelson +### Nelson 😎 | Constraint | Type | Description | |:-------------------:|:--------:|:---------------------------------------------:| From ac5431402e6c4a541215225ce954b33a73a060ef Mon Sep 17 00:00:00 2001 From: FKN237 Date: Fri, 10 Jan 2025 00:40:28 +0100 Subject: [PATCH 099/175] wow --- collaboration/constraints.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 446b9a316..aab092b75 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -1,6 +1,7 @@ # ![Alt Text](../assets/task-planner.png) Constraints -> In this readme, we explain potential **constraints** that limit our productivity and achievement throughout the project. +> In this readme, we explain potential **constraints** that limit our +productivity and achievement throughout the project. ## ![Alt Text](../assets/outdoor.png) Constraints @@ -8,31 +9,31 @@ ### _Salem πŸ‘€_ -| Constraint | Type | Description | +| Constraint | Type | Description | |:-------------------:|:--------:|:--------------------------------------------------:| -| Power & internet πŸ›œ | External | I have limited hours when power is available. | -| Deadlines ❌ | External | I have college deadlines in addition to MET program deadlines. | +| Power & internet πŸ›œ | External | I have limited hours when power isavailable.| +| Deadlines ❌| External | I have college deadlines in addition to MET program deadlines.| ### Nagham | Constraint | Type | Description | |:-------------------:|:--------:|:--------------------------------------------------:| -| Internet πŸ›œ | External | Internet is not always available. | -| Time Zone Differences πŸ•’ | External | It causes conflicts and delays progress. | +| Internet πŸ›œ | External | Internet is not always available. | +| Time Zone Differences πŸ•’ | External | It causes conflicts and delays progress.| ### Nelson 😎 -| Constraint | Type | Description | +| Constraint | Type | Description | |:-------------------:|:--------:|:---------------------------------------------:| | Deadline issues ❌ | External | I am preparing my application for college. | | GitHub knowledge ❓ | Internal | I do not know how to use GitHub effectively.| ### Matvii 😊 -| Constraint | Type | Description | +| Constraint | Type | Description | |:-------------------:|:--------:|:--------------------------------------------------:| -| Deadlines ❌ | External | University exams. | -| Power & internet πŸ›œ | External | I might not have unlimited access to electricity. | +| Deadlines ❌ | External | University exams. | +| Power & internet πŸ›œ| External | I might not have unlimited access to electricity.| #### Summary From 6f0d2f2d53a5122734a3a3a86a35e5f2415941af Mon Sep 17 00:00:00 2001 From: FKN237 Date: Fri, 10 Jan 2025 01:03:08 +0100 Subject: [PATCH 100/175] Adding my personal learning goals --- collaboration/learning_goals.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 105615875..a545fe0d5 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -63,6 +63,12 @@ ### Nelson's objectives +| **Goal** | **Description** | **Progress** | +|------------------------------------|-----------------|--------------| +| πŸ‘¨πŸ½β€πŸ’»Strengthen my Python skills | Learn Documentation and Testing + code | ![55%](https://progress-bar.xyz/35)| +| πŸ› οΈMaster Git and GitHub | Master version control and teamwork | ![20%](https://progress-bar.xyz/15) | +| πŸ‘«Collaboarative work | Increase my collaborative work skills | ![70%](https://progress-bar.xyz/45) | + ### Matvii's objectives | **Goal** | **Description** | **Progress** | From 46bbf22c91e43e4059579c982a975dfee95004fe Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Fri, 10 Jan 2025 16:20:51 +0200 Subject: [PATCH 101/175] Fix markdown issues --- collaboration/constraints.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 7d4b7e78c..73d5cbb2b 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -1,6 +1,7 @@ # ![Alt Text](../assets/task-planner.png) Constraints -> In this readme, we explain potential **constraints** that limit our productivity and achievement throughout the project. +> In this readme, we explain potential **constraints** that limit our +> productivity and achievement throughout the project. ## ![Alt Text](../assets/outdoor.png) Constraints @@ -8,31 +9,31 @@ ### _Salem πŸ‘€_ -| Constraint | Type | Description | +| Constraint | Type | Description| |:-------------------:|:--------:|:--------------------------------------------------:| -| Power & internet πŸ›œ | External | I have limited hours when power is available. | -| Deadlines ❌ | External | I have college deadlines in addition to MET program deadlines. | +| Power & internet πŸ›œ | External | I have limited hours when power is available.| +| Deadlines ❌ | External | I have college deadlines and MET program deadlines.| ### Nagham | Constraint | Type | Description | |:-------------------:|:--------:|:--------------------------------------------------:| -| Internet πŸ›œ | External | Internet is not always available. | -| Time Zone Differences πŸ•’ | External | It causes conflicts and delays progress. | +| Internet πŸ›œ | External | Internet is not always available.| +| Time Zone Differences πŸ•’ | External | It causes conflicts and delays progress.| ### Nelson -| Constraint | Type | Description | +| Constraint | Type | Description| |:-------------------:|:--------:|:---------------------------------------------:| | Deadline issues ❌ | External | I am preparing my application for college. | | GitHub knowledge ❓ | Internal | I do not know how to use GitHub effectively.| ### Matvii 😊 -| Constraint | Type | Description | +| Constraint | Type | Description| |:-------------------:|:--------:|:--------------------------------------------------:| -| Deadlines ❌ | External | University exams. | -| Power & internet πŸ›œ | External | I might not have unlimited access to electricity. | +| Deadlines ❌ | External | University exams.| +| Power & internet πŸ›œ | External | I might not have unlimited access to electricity.| #### Summary From f447c4b1a7aaf1c56d8d578b77717a88406b048e Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Fri, 10 Jan 2025 16:38:07 +0200 Subject: [PATCH 102/175] Add minion_game solution --- solutions/minion_game.py | 56 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 solutions/minion_game.py diff --git a/solutions/minion_game.py b/solutions/minion_game.py new file mode 100644 index 000000000..4a2470156 --- /dev/null +++ b/solutions/minion_game.py @@ -0,0 +1,56 @@ +def minion_game(text): + """ + Determines the winner of the Minion Game based on the input string. + + The Minion Game is played between two players, Kevin and Stuart, where: + - Kevin scores points for substrings starting with vowels ('a', 'e', 'i', 'o', 'u'). + - Stuart scores points for substrings starting with consonants. + + The points are awarded based on the number of substrings that start at each index of the string. + For example, if the string is 'banana', substrings starting at index 0, 1, 2, etc., are considered. + + Args: + text (str): The input string to play the Minion Game with. The string is converted to lowercase to ensure case-insensitivity. + + Returns: + tuple or str: + - If there is a winner, returns a tuple with the winner's name ('Kevin' or 'Stuart') and their score. + - If it's a draw, returns 'Draw'. + + Example: + + >>> minion_game("banana") + ('Stuart', 12) + + >>> minion_game("a") + ('Kevin', 1) + + >>> minion_game("b") + ('Stuart', 1) + + >>> minion_game("aeiou") + ('Kevin', 15) + + """ + kevin_score = 0 + stuart_score = 0 + vowels = {'a', 'e', 'i', 'o', 'u'} + n = len(text) + + for i in range(n): + if text[i] in vowels: + kevin_score += n - i + else: + stuart_score += n - i + + if kevin_score > stuart_score: + return "Kevin", kevin_score + elif stuart_score > kevin_score: + return "Stuart", stuart_score + else: + return "Draw" + + +if __name__ == "__main__": + import doctest + doctest.testmod() From 77316725a4ff012e21dba438553e7712446e061c Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Fri, 10 Jan 2025 16:56:50 +0200 Subject: [PATCH 103/175] Fix ci checks issue --- solutions/minion_game.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/solutions/minion_game.py b/solutions/minion_game.py index 4a2470156..54a92b95c 100644 --- a/solutions/minion_game.py +++ b/solutions/minion_game.py @@ -1,3 +1,4 @@ + def minion_game(text): """ Determines the winner of the Minion Game based on the input string. @@ -49,8 +50,3 @@ def minion_game(text): return "Stuart", stuart_score else: return "Draw" - - -if __name__ == "__main__": - import doctest - doctest.testmod() From 06757f5488270eb5cba8b038d7352f528c6c2d8c Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Fri, 10 Jan 2025 17:04:23 +0200 Subject: [PATCH 104/175] Reformat solution with ruff --- solutions/minion_game.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/solutions/minion_game.py b/solutions/minion_game.py index 54a92b95c..dc424b9a9 100644 --- a/solutions/minion_game.py +++ b/solutions/minion_game.py @@ -1,4 +1,3 @@ - def minion_game(text): """ Determines the winner of the Minion Game based on the input string. @@ -14,36 +13,36 @@ def minion_game(text): text (str): The input string to play the Minion Game with. The string is converted to lowercase to ensure case-insensitivity. Returns: - tuple or str: + tuple or str: - If there is a winner, returns a tuple with the winner's name ('Kevin' or 'Stuart') and their score. - If it's a draw, returns 'Draw'. Example: - + >>> minion_game("banana") ('Stuart', 12) - + >>> minion_game("a") ('Kevin', 1) - + >>> minion_game("b") ('Stuart', 1) - + >>> minion_game("aeiou") ('Kevin', 15) - + """ kevin_score = 0 stuart_score = 0 - vowels = {'a', 'e', 'i', 'o', 'u'} + vowels = {"a", "e", "i", "o", "u"} n = len(text) - + for i in range(n): if text[i] in vowels: kevin_score += n - i else: stuart_score += n - i - + if kevin_score > stuart_score: return "Kevin", kevin_score elif stuart_score > kevin_score: From 87031c6bf509f11211b7f833a2030ccc7184f0d5 Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Fri, 10 Jan 2025 17:04:23 +0200 Subject: [PATCH 105/175] update --- collaboration/learning_goals.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index a545fe0d5..9203d13d1 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -61,6 +61,8 @@ | πŸ› οΈMaster Git and GitHub | Master version control and teamwork | ![20%](https://progress-bar.xyz/20) | | πŸ’»Refine Coding Practices | Write cleanand well-documented code | ![70%](https://progress-bar.xyz/70) | +--- + ### Nelson's objectives | **Goal** | **Description** | **Progress** | @@ -69,6 +71,8 @@ | πŸ› οΈMaster Git and GitHub | Master version control and teamwork | ![20%](https://progress-bar.xyz/15) | | πŸ‘«Collaboarative work | Increase my collaborative work skills | ![70%](https://progress-bar.xyz/45) | +--- + ### Matvii's objectives | **Goal** | **Description** | **Progress** | From 2f66209acfe819c1da81a4cc283b645e35451d99 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Fri, 10 Jan 2025 23:31:06 +0100 Subject: [PATCH 106/175] Create generate_triangular_numbers.py --- solutions/generate_triangular_numbers.py | 57 ++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 solutions/generate_triangular_numbers.py diff --git a/solutions/generate_triangular_numbers.py b/solutions/generate_triangular_numbers.py new file mode 100644 index 000000000..c712fd070 --- /dev/null +++ b/solutions/generate_triangular_numbers.py @@ -0,0 +1,57 @@ +""" +This module provides functions to generate triangular numbers. + +A triangular number is the sum of consecutive natural numbers starting from 1. +The nth triangular number can be calculated using the formula: n * (n + 1) / 2. + +This module offers the following functionality: + +- `generate_triangular_numbers(n)`: Generates a list of the first n triangular numbers. + +Created on XX XX XX +@author: Nelson Fodjo & Gemini AI +""" + +def generate_triangular_numbers(n): + + """ + Generates a list of the first n triangular numbers. + + Args: + n: The number of triangular numbers to generate (positive integer). + + Returns: + A list containing the first n triangular numbers. + + Raises: + ValueError: If n is not a positive integer. + + >>> generate_triangular_numbers(5) + [1, 3, 6, 10, 15] + + >>> generate_triangular_numbers(1) + [1] + + >>> generate_triangular_numbers(10) + [1, 3, 6, 10, 15, 21, 28, 36, 45, 55] + + >>> generate_triangular_numbers(0) + ValueError: n must be a positive integer + + >>> generate_triangular_numbers(-3) + ValueError: n must be a positive integer + + >>> generate_triangular_numbers('five') + ValueError: n must be a positive integer + """ + + if not isinstance(n, int): + raise ValueError("n must be a positive integer") + if n <= 0: + raise ValueError("n must be a positive integer") + + triangular_numbers = [] + + for i in range(1, n + 1): + triangular_numbers.append(i * (i + 1) // 2) + return triangular_numbers From 11317611735ecae1df6b6cc3422342a1df8466ff Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Fri, 10 Jan 2025 23:41:58 +0100 Subject: [PATCH 107/175] Create test_generate_triangular_numbers.py --- .../tests/test_generate_triangular_numbers.py | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 solutions/tests/test_generate_triangular_numbers.py diff --git a/solutions/tests/test_generate_triangular_numbers.py b/solutions/tests/test_generate_triangular_numbers.py new file mode 100644 index 000000000..e40ad8cf4 --- /dev/null +++ b/solutions/tests/test_generate_triangular_numbers.py @@ -0,0 +1,90 @@ +""" +Unit tests for the generate_triangular_numbers function. + +This code tests the functionality of the generate_triangular_numbers function +from the solutions.generate_triangular_numbers module. It verifies that the +function correctly generates triangular numbers for valid inputs and raises +appropriate exceptions for invalid inputs. + +A triangular number is defined as the sum of the first n natural numbers, +calculated using the formula: n * (n + 1) / 2. + +Author: Nelson +Created on: 10 01 2025 +""" + +import unittest +from solutions.generate_triangular_numbers import generate_triangular_numbers + + +class TestGenerateTriangularNumbers(unittest.TestCase): + """ + Unit test class for the generate_triangular_numbers function. + + This class contains tests to: + - Check correct behavior for valid inputs. + - Confirm proper error handling for invalid inputs. + - Verify edge cases. + """ + + def test_valid_inputs(self): + """ + Test the function with valid inputs. + + Ensures the function generates the correct list of triangular numbers + for various valid inputs. + """ + # Test case: Generate the first triangular number (n=1) + self.assertEqual(generate_triangular_numbers(1), [1]) + + # Test case: Generate the first 5 triangular numbers + self.assertEqual(generate_triangular_numbers(5), [1, 3, 6, 10, 15]) + + # Test case: Generate the first 10 triangular numbers + self.assertEqual( + generate_triangular_numbers(10), + [1, 3, 6, 10, 15, 21, 28, 36, 45, 55] + ) + + def test_invalid_inputs(self): + """ + Test the function with invalid inputs. + + Ensures the function raises a ValueError for: + - Non-positive integers (e.g., 0 or negative numbers). + - Non-integer inputs (e.g., strings or floats). + """ + # Test case: Input is zero + with self.assertRaises(ValueError): + generate_triangular_numbers(0) + + # Test case: Input is a negative integer + with self.assertRaises(ValueError): + generate_triangular_numbers(-5) + + # Test case: Input is a string + with self.assertRaises(ValueError): + generate_triangular_numbers("five") + + # Test case: Input is a float + with self.assertRaises(ValueError): + generate_triangular_numbers(3.5) + + def test_edge_cases(self): + """ + Test edge cases for the function. + + Verifies that the function handles the smallest valid input correctly. + """ + # Test case: Smallest valid input (n=1) + self.assertEqual(generate_triangular_numbers(1), [1]) + + +if __name__ == "__main__": + """ + Run the test suite. + + When executed as a script, this block will run all the test cases in the + TestGenerateTriangularNumbers class. + """ + unittest.main() From 3e195433c7fff8fdd4542b94703e330eb6c8c4e1 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sat, 11 Jan 2025 00:04:00 +0100 Subject: [PATCH 108/175] Update generate_triangular_numbers.py --- solutions/generate_triangular_numbers.py | 43 +++++++++++++----------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/solutions/generate_triangular_numbers.py b/solutions/generate_triangular_numbers.py index c712fd070..9e2178977 100644 --- a/solutions/generate_triangular_numbers.py +++ b/solutions/generate_triangular_numbers.py @@ -12,46 +12,51 @@ @author: Nelson Fodjo & Gemini AI """ -def generate_triangular_numbers(n): +def generate_triangular_numbers(n): """ Generates a list of the first n triangular numbers. Args: - n: The number of triangular numbers to generate (positive integer). + n (int): The number of triangular numbers to generate (positive integer). Returns: - A list containing the first n triangular numbers. + list: A list containing the first n triangular numbers. Raises: ValueError: If n is not a positive integer. - - >>> generate_triangular_numbers(5) - [1, 3, 6, 10, 15] - >>> generate_triangular_numbers(1) - [1] + Examples: + >>> generate_triangular_numbers(5) + [1, 3, 6, 10, 15] - >>> generate_triangular_numbers(10) - [1, 3, 6, 10, 15, 21, 28, 36, 45, 55] + >>> generate_triangular_numbers(1) + [1] - >>> generate_triangular_numbers(0) - ValueError: n must be a positive integer + >>> generate_triangular_numbers(10) + [1, 3, 6, 10, 15, 21, 28, 36, 45, 55] - >>> generate_triangular_numbers(-3) - ValueError: n must be a positive integer + >>> generate_triangular_numbers(0) + Traceback (most recent call last): + ... + ValueError: n must be a positive integer - >>> generate_triangular_numbers('five') - ValueError: n must be a positive integer - """ + >>> generate_triangular_numbers(-3) + Traceback (most recent call last): + ... + ValueError: n must be a positive integer + >>> generate_triangular_numbers("five") + Traceback (most recent call last): + ... + ValueError: n must be a positive integer + """ if not isinstance(n, int): raise ValueError("n must be a positive integer") if n <= 0: raise ValueError("n must be a positive integer") - + triangular_numbers = [] - for i in range(1, n + 1): triangular_numbers.append(i * (i + 1) // 2) return triangular_numbers From c15ab014eb6b26fc847519db684dfb1fef894f3a Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sat, 11 Jan 2025 00:07:30 +0100 Subject: [PATCH 109/175] Update test_generate_triangular_numbers.py From 59cf7a2654491ec3d53854c5e212bdba60ee7d0c Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sat, 11 Jan 2025 00:11:26 +0100 Subject: [PATCH 110/175] Update test_generate_triangular_numbers.py --- solutions/tests/test_generate_triangular_numbers.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/solutions/tests/test_generate_triangular_numbers.py b/solutions/tests/test_generate_triangular_numbers.py index e40ad8cf4..5a0ef86a5 100644 --- a/solutions/tests/test_generate_triangular_numbers.py +++ b/solutions/tests/test_generate_triangular_numbers.py @@ -13,6 +13,7 @@ Created on: 10 01 2025 """ + import unittest from solutions.generate_triangular_numbers import generate_triangular_numbers @@ -27,6 +28,7 @@ class TestGenerateTriangularNumbers(unittest.TestCase): - Verify edge cases. """ + def test_valid_inputs(self): """ Test the function with valid inputs. @@ -46,6 +48,7 @@ def test_valid_inputs(self): [1, 3, 6, 10, 15, 21, 28, 36, 45, 55] ) + def test_invalid_inputs(self): """ Test the function with invalid inputs. @@ -70,6 +73,7 @@ def test_invalid_inputs(self): with self.assertRaises(ValueError): generate_triangular_numbers(3.5) + def test_edge_cases(self): """ Test edge cases for the function. From c6f59db6b2c1a5eba54b8402d31af4039e04080c Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sat, 11 Jan 2025 00:15:15 +0100 Subject: [PATCH 111/175] Update test_generate_triangular_numbers.py --- solutions/tests/test_generate_triangular_numbers.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/solutions/tests/test_generate_triangular_numbers.py b/solutions/tests/test_generate_triangular_numbers.py index 5a0ef86a5..eaf52347e 100644 --- a/solutions/tests/test_generate_triangular_numbers.py +++ b/solutions/tests/test_generate_triangular_numbers.py @@ -13,7 +13,6 @@ Created on: 10 01 2025 """ - import unittest from solutions.generate_triangular_numbers import generate_triangular_numbers @@ -28,7 +27,6 @@ class TestGenerateTriangularNumbers(unittest.TestCase): - Verify edge cases. """ - def test_valid_inputs(self): """ Test the function with valid inputs. @@ -45,10 +43,9 @@ def test_valid_inputs(self): # Test case: Generate the first 10 triangular numbers self.assertEqual( generate_triangular_numbers(10), - [1, 3, 6, 10, 15, 21, 28, 36, 45, 55] + [1, 3, 6, 10, 15, 21, 28, 36, 45, 55], ) - def test_invalid_inputs(self): """ Test the function with invalid inputs. @@ -73,7 +70,6 @@ def test_invalid_inputs(self): with self.assertRaises(ValueError): generate_triangular_numbers(3.5) - def test_edge_cases(self): """ Test edge cases for the function. From 27a8e78d25f97eb8e1951eaa7775f7589d68e696 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sat, 11 Jan 2025 00:25:31 +0100 Subject: [PATCH 112/175] Update test_generate_triangular_numbers.py --- solutions/tests/test_generate_triangular_numbers.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/solutions/tests/test_generate_triangular_numbers.py b/solutions/tests/test_generate_triangular_numbers.py index eaf52347e..434a80433 100644 --- a/solutions/tests/test_generate_triangular_numbers.py +++ b/solutions/tests/test_generate_triangular_numbers.py @@ -14,10 +14,12 @@ """ import unittest + from solutions.generate_triangular_numbers import generate_triangular_numbers class TestGenerateTriangularNumbers(unittest.TestCase): + """ Unit test class for the generate_triangular_numbers function. @@ -28,12 +30,14 @@ class TestGenerateTriangularNumbers(unittest.TestCase): """ def test_valid_inputs(self): + """ Test the function with valid inputs. Ensures the function generates the correct list of triangular numbers for various valid inputs. """ + # Test case: Generate the first triangular number (n=1) self.assertEqual(generate_triangular_numbers(1), [1]) @@ -47,6 +51,7 @@ def test_valid_inputs(self): ) def test_invalid_inputs(self): + """ Test the function with invalid inputs. @@ -54,6 +59,7 @@ def test_invalid_inputs(self): - Non-positive integers (e.g., 0 or negative numbers). - Non-integer inputs (e.g., strings or floats). """ + # Test case: Input is zero with self.assertRaises(ValueError): generate_triangular_numbers(0) @@ -71,20 +77,24 @@ def test_invalid_inputs(self): generate_triangular_numbers(3.5) def test_edge_cases(self): + """ Test edge cases for the function. Verifies that the function handles the smallest valid input correctly. """ + # Test case: Smallest valid input (n=1) self.assertEqual(generate_triangular_numbers(1), [1]) if __name__ == "__main__": + """ Run the test suite. When executed as a script, this block will run all the test cases in the TestGenerateTriangularNumbers class. """ + unittest.main() From 1e28de1858aa24b2cf4e320d8e3df30719f049d0 Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sat, 11 Jan 2025 10:27:19 +0200 Subject: [PATCH 113/175] Fix bug lowercase --- solutions/minion_game.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solutions/minion_game.py b/solutions/minion_game.py index dc424b9a9..5630179ff 100644 --- a/solutions/minion_game.py +++ b/solutions/minion_game.py @@ -35,6 +35,7 @@ def minion_game(text): kevin_score = 0 stuart_score = 0 vowels = {"a", "e", "i", "o", "u"} + text = text.lower() n = len(text) for i in range(n): @@ -49,3 +50,4 @@ def minion_game(text): return "Stuart", stuart_score else: return "Draw" + From f3c74aa19f67401d24a91248e2fe0487f1e5c700 Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sat, 11 Jan 2025 12:27:31 +0200 Subject: [PATCH 114/175] Add Summary for solution --- .vscode/settings.json | 4 ++-- solutions/minion_game.py | 43 ++++++++++++++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 10 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 } } } diff --git a/solutions/minion_game.py b/solutions/minion_game.py index 5630179ff..75897f9da 100644 --- a/solutions/minion_game.py +++ b/solutions/minion_game.py @@ -1,14 +1,21 @@ -def minion_game(text): - """ - Determines the winner of the Minion Game based on the input string. +""" +This module contains a function minion_game which is the implementation of the Minion Game - The Minion Game is played between two players, Kevin and Stuart, where: +The Minion Game is played between two players, Kevin and Stuart, where: - Kevin scores points for substrings starting with vowels ('a', 'e', 'i', 'o', 'u'). - Stuart scores points for substrings starting with consonants. The points are awarded based on the number of substrings that start at each index of the string. For example, if the string is 'banana', substrings starting at index 0, 1, 2, etc., are considered. +Author: Salem Amassi + +""" + +def minion_game(text): + """ + Determines the winner of the Minion Game based on the input string. + Args: text (str): The input string to play the Minion Game with. The string is converted to lowercase to ensure case-insensitivity. @@ -32,17 +39,37 @@ def minion_game(text): ('Kevin', 15) """ + # check if the input is empty + if not text: + raise ValueError("Input must not be empty") + + # check if the input is numeric + if text.isnumeric(): + raise ValueError("Input must not be empty") + + + # define both players' scores kevin_score = 0 stuart_score = 0 + + # define vowels to check with vowels = {"a", "e", "i", "o", "u"} + + # convert the text to lower case text = text.lower() - n = len(text) - for i in range(n): + # get the length + text_length = len(text) + + # iterate the input and update scores + + for i in range(text_length): if text[i] in vowels: - kevin_score += n - i + kevin_score += text_length - i # add all other occurrences of character to kevin_score else: - stuart_score += n - i + stuart_score += text_length - i # add all other occurrences of character to stuart_score + + # evaluate the result if kevin_score > stuart_score: return "Kevin", kevin_score From 4f17c3d56dae26a0ea35c02b7c824eb9f11fb492 Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sat, 11 Jan 2025 12:30:33 +0200 Subject: [PATCH 115/175] Fix ruff formatting --- solutions/minion_game.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/solutions/minion_game.py b/solutions/minion_game.py index 75897f9da..fe60bd035 100644 --- a/solutions/minion_game.py +++ b/solutions/minion_game.py @@ -12,6 +12,7 @@ """ + def minion_game(text): """ Determines the winner of the Minion Game based on the input string. @@ -41,13 +42,12 @@ def minion_game(text): """ # check if the input is empty if not text: - raise ValueError("Input must not be empty") + raise ValueError("Input must not be empty") # check if the input is numeric if text.isnumeric(): raise ValueError("Input must not be empty") - # define both players' scores kevin_score = 0 stuart_score = 0 @@ -55,19 +55,23 @@ def minion_game(text): # define vowels to check with vowels = {"a", "e", "i", "o", "u"} - # convert the text to lower case + # convert the text to lower case text = text.lower() - # get the length + # get the length text_length = len(text) # iterate the input and update scores for i in range(text_length): if text[i] in vowels: - kevin_score += text_length - i # add all other occurrences of character to kevin_score + kevin_score += ( + text_length - i + ) # add all other occurrences of character to kevin_score else: - stuart_score += text_length - i # add all other occurrences of character to stuart_score + stuart_score += ( + text_length - i + ) # add all other occurrences of character to stuart_score # evaluate the result @@ -77,4 +81,3 @@ def minion_game(text): return "Stuart", stuart_score else: return "Draw" - From a28e3b26654ce01a354e8d39b6c8e1c2b3ad0390 Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sat, 11 Jan 2025 12:31:34 +0200 Subject: [PATCH 116/175] Add minion_game tests --- solutions/tests/test_minion_game.py | 87 +++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 solutions/tests/test_minion_game.py diff --git a/solutions/tests/test_minion_game.py b/solutions/tests/test_minion_game.py new file mode 100644 index 000000000..a9a16d0c9 --- /dev/null +++ b/solutions/tests/test_minion_game.py @@ -0,0 +1,87 @@ +""" +Unit tests for the minion_game function in the minion_game module. + +This module contains a group of test cases to verify the correctness of the +minion_game function, which prints the name and score of the winner of the game. + +""" + +import unittest +import sys + +sys.path.append("../") +from minion_game import minion_game + + +class TestMinionGame(unittest.TestCase): + """ + Unit tests for the minion_game function. + """ + + def test_kevin_wins_with_vowels(self): + """ + Test if Kevin wins when there are more vowels at the start. + """ + result = minion_game("aeiou") + self.assertEqual(result, ("Kevin", 15)) + + def test_stuart_wins_with_consonants(self): + """ + Test if Stuart wins when there are more consonants at the start. + """ + result = minion_game("banana") + self.assertEqual(result, ("Stuart", 12)) + + def test_draw(self): + """ + Test if the game results in a draw when scores are equal. + """ + + result = minion_game("BANANANAAAS") + self.assertEqual(result, "Draw") + + def test_single_character_vowel(self): + """ + Test if Kevin wins with a single vowel character. + """ + result = minion_game("a") + self.assertEqual(result, ("Kevin", 1)) + + def test_single_character_consonant(self): + """ + Test if Stuart wins with a single consonant character. + """ + result = minion_game("b") + self.assertEqual(result, ("Stuart", 1)) + + def test_empty_string(self): + """ + Test case for empty input (should raise ValueError). + """ + with self.assertRaises(ValueError): + minion_game("") + + def test_numeric_input(self): + """ + Test case for numeric input (should raise ValueError). + """ + with self.assertRaises(ValueError): + minion_game("122343") + + def test_all_vowels(self): + """ + Test boundary case where the input is all vowels. + """ + result = minion_game("aeiouaeiou") + self.assertEqual(result, ("Kevin", 55)) + + def test_all_consonants(self): + """ + Test boundary case where the input is all consonants. + """ + result = minion_game("bcdfg") + self.assertEqual(result, ("Stuart", 15)) + + +if __name__ == "__main__": + unittest.main() From 34fbe07383aa6b9f3688dcc3d5f0de0ef6244f2c Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sat, 11 Jan 2025 12:33:24 +0200 Subject: [PATCH 117/175] Fix import issue --- solutions/tests/test_minion_game.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_minion_game.py b/solutions/tests/test_minion_game.py index a9a16d0c9..fbcd901fa 100644 --- a/solutions/tests/test_minion_game.py +++ b/solutions/tests/test_minion_game.py @@ -10,7 +10,7 @@ import sys sys.path.append("../") -from minion_game import minion_game +from solutions.minion_game import minion_game class TestMinionGame(unittest.TestCase): From a8bd6bff087a16801ad2bd77455dba0b75be76d9 Mon Sep 17 00:00:00 2001 From: matopcheg Date: Sat, 11 Jan 2025 12:42:00 +0200 Subject: [PATCH 118/175] add retrospective, in progress --- collaboration/retrospective.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/collaboration/retrospective.md b/collaboration/retrospective.md index 74e18813b..4c85065f4 100644 --- a/collaboration/retrospective.md +++ b/collaboration/retrospective.md @@ -1,23 +1,44 @@ + + # Retrospective ## Stop Doing +- Writing incomplete commit messages ❌ +- Doing too many commits for minor changes ❌ + ## Continue Doing +- Checking the project board regularly. +- Asking teammates if any help is needed. +- Maintaining a clean and structured repository with clear README documentation. +- Following the rule: 1 task = 1 branch. + ## Start Doing +- Optimize ammount of branches, commits to avoid cluttering the project. + ## Lessons Learned +- Effective use of pull requests helped improve code quality and catch bugs early βœ… +- Frequent syncing with the remote repository avoided merge conflicts βœ… ______________________________________________________________________ ## Strategy vs. Board ### What parts of your plan went as expected? +Pull requests were reviewed and merged according to the workflow plan. + ### What parts of your plan did not work out? +Overall, we completed our project quota. While some minor ideas were not fully implemented, +we kept the ones with potential and iterated on them as the project progressed. + ### Did you need to add things that weren't in your strategy? + ### Or remove extra steps? +- Stopped requiring a review for very small, trivial changes to save time. From ccaac76a8aa0c4b968f7187d912de54bece32bcc Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sat, 11 Jan 2025 13:21:42 +0200 Subject: [PATCH 119/175] Add sum_digits solution --- solutions/sum_digits.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 solutions/sum_digits.py diff --git a/solutions/sum_digits.py b/solutions/sum_digits.py new file mode 100644 index 000000000..f7eec0b9a --- /dev/null +++ b/solutions/sum_digits.py @@ -0,0 +1,38 @@ +""" +This module contains a function sum_digits + +It uses recursion to solve the sum of digits of n + +""" + + +def sum_digits(n): + """ + Calculate the sum of the digits of a given non-negative integer using recursion. + + Args: + n (int): A non-negative integer whose digits will be summed. + + Returns: + int: The sum of the digits of the given integer. + + Examples: + >>> sum_digits(123) + 6 + >>> sum_digits(0) + 0 + >>> sum_digits(9876) + 30 + >>> sum_digits(456) + 15 + """ + + if not n.isnumeric(): + raise ValueError("input must be number") + if n == "": + raise ValueError("input must not be empty") + + if n == 0: + return 0 + else: + return n % 10 + sum_digits(n // 10) From 4ff6d667d598470f3856201ddc19ad1ec05f10ad Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sat, 11 Jan 2025 13:45:52 +0200 Subject: [PATCH 120/175] Add validation function --- solutions/sum_digits.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/solutions/sum_digits.py b/solutions/sum_digits.py index f7eec0b9a..91d840dc2 100644 --- a/solutions/sum_digits.py +++ b/solutions/sum_digits.py @@ -27,12 +27,13 @@ def sum_digits(n): 15 """ - if not n.isnumeric(): - raise ValueError("input must be number") - if n == "": - raise ValueError("input must not be empty") + validate_input(n) if n == 0: return 0 else: return n % 10 + sum_digits(n // 10) + +def validate_input(n): + if not isinstance(n, int) or n < 0: + raise ValueError("Input must be a non-negative integer.") From 0b7d037be009c3f6733a01ce9916e28d22ff7c8c Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sat, 11 Jan 2025 13:47:22 +0200 Subject: [PATCH 121/175] Fix formatting issue --- solutions/sum_digits.py | 1 + 1 file changed, 1 insertion(+) diff --git a/solutions/sum_digits.py b/solutions/sum_digits.py index 91d840dc2..91c099d22 100644 --- a/solutions/sum_digits.py +++ b/solutions/sum_digits.py @@ -34,6 +34,7 @@ def sum_digits(n): else: return n % 10 + sum_digits(n // 10) + def validate_input(n): if not isinstance(n, int) or n < 0: raise ValueError("Input must be a non-negative integer.") From a048a661b7d8eb7b6707053f2626c0dbf60e94cf Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sat, 11 Jan 2025 13:52:07 +0200 Subject: [PATCH 122/175] Add sum_digits test --- solutions/tests/test_sum_digits.py | 55 ++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 solutions/tests/test_sum_digits.py diff --git a/solutions/tests/test_sum_digits.py b/solutions/tests/test_sum_digits.py new file mode 100644 index 000000000..b5a79854e --- /dev/null +++ b/solutions/tests/test_sum_digits.py @@ -0,0 +1,55 @@ +""" +Unit tests for the sum_digits function. + +This test suite validates the functionality of the sum_digits function, ensuring +it correctly computes the sum of the digits for various types of inputs and handles +invalid inputs appropriately. +""" + +import unittest +import sys + +sys.path.append("../") +from sum_digits import sum_digits # Replace 'your_module' with the actual module name + + +class TestSumDigits(unittest.TestCase): + def test_single_digit(self): + """Test sum_digits with a single-digit input.""" + self.assertEqual(sum_digits(9), 9) + + def test_multiple_digits(self): + """Test sum_digits with a multi-digit input.""" + self.assertEqual(sum_digits(456), 15) + + def test_large_number(self): + """Test sum_digits with a large number input.""" + self.assertEqual(sum_digits(123456789), 45) + + def test_edge_case(self): + """Test sum_digits with an edge case where digits are mixed (e.g., 101).""" + self.assertEqual(sum_digits(101), 2) + + def test_negative_input(self): + """Test sum_digits raises ValueError for negative input.""" + with self.assertRaises(ValueError): + sum_digits(-1) + + def test_string_input(self): + """Test sum_digits raises ValueError when input is a string.""" + with self.assertRaises(ValueError): + sum_digits("123") + + def test_none_input(self): + """Test sum_digits raises ValueError when input is None.""" + with self.assertRaises(ValueError): + sum_digits(None) + + def test_float_input(self): + """Test sum_digits raises ValueError when input is a float.""" + with self.assertRaises(ValueError): + sum_digits(12.34) + + +if __name__ == "__main__": + unittest.main() From ecded1b3b506600300ea8b4e0051f8490f373fcb Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sat, 11 Jan 2025 13:55:52 +0200 Subject: [PATCH 123/175] Fix import issue --- solutions/tests/test_sum_digits.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/solutions/tests/test_sum_digits.py b/solutions/tests/test_sum_digits.py index b5a79854e..ea89ba99c 100644 --- a/solutions/tests/test_sum_digits.py +++ b/solutions/tests/test_sum_digits.py @@ -8,9 +8,10 @@ import unittest import sys +import os -sys.path.append("../") -from sum_digits import sum_digits # Replace 'your_module' with the actual module name +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) +from solutions.sum_digits import sum_digits class TestSumDigits(unittest.TestCase): From 002c4b3de6e2c56a74079d3e501c7fa69691e844 Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sat, 11 Jan 2025 13:57:08 +0200 Subject: [PATCH 124/175] Fix formatting issue --- solutions/tests/test_sum_digits.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_sum_digits.py b/solutions/tests/test_sum_digits.py index ea89ba99c..c200df59f 100644 --- a/solutions/tests/test_sum_digits.py +++ b/solutions/tests/test_sum_digits.py @@ -11,7 +11,7 @@ import os sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) -from solutions.sum_digits import sum_digits +from solutions.sum_digits import sum_digits class TestSumDigits(unittest.TestCase): From b0b9cd8f05a766e2a5d00c2429ce60ad0ca36edb Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sat, 11 Jan 2025 13:58:55 +0200 Subject: [PATCH 125/175] Modify arg name --- solutions/sum_digits.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/solutions/sum_digits.py b/solutions/sum_digits.py index 91c099d22..feb038c5b 100644 --- a/solutions/sum_digits.py +++ b/solutions/sum_digits.py @@ -6,12 +6,12 @@ """ -def sum_digits(n): +def sum_digits(num: int): """ Calculate the sum of the digits of a given non-negative integer using recursion. Args: - n (int): A non-negative integer whose digits will be summed. + num (int): A non-negative integer whose digits will be summed. Returns: int: The sum of the digits of the given integer. @@ -27,14 +27,14 @@ def sum_digits(n): 15 """ - validate_input(n) + validate_input(num) - if n == 0: + if num == 0: return 0 else: - return n % 10 + sum_digits(n // 10) + return num % 10 + sum_digits(num // 10) -def validate_input(n): - if not isinstance(n, int) or n < 0: +def validate_input(num): + if not isinstance(num, int) or num < 0: raise ValueError("Input must be a non-negative integer.") From 3eabb5d5216fe52b02e35f09da2e82c3ca84d171 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sat, 11 Jan 2025 19:24:44 +0100 Subject: [PATCH 126/175] Update test_generate_triangular_numbers.py --- .../tests/test_generate_triangular_numbers.py | 44 +++---------------- 1 file changed, 5 insertions(+), 39 deletions(-) diff --git a/solutions/tests/test_generate_triangular_numbers.py b/solutions/tests/test_generate_triangular_numbers.py index 434a80433..2735f2ef2 100644 --- a/solutions/tests/test_generate_triangular_numbers.py +++ b/solutions/tests/test_generate_triangular_numbers.py @@ -1,3 +1,6 @@ +import unittest +from solutions.generate_triangular_numbers import generate_triangular_numbers + """ Unit tests for the generate_triangular_numbers function. @@ -6,20 +9,14 @@ function correctly generates triangular numbers for valid inputs and raises appropriate exceptions for invalid inputs. -A triangular number is defined as the sum of the first n natural numbers, +A triangular number is defined as the sum of the first n natural numbers, calculated using the formula: n * (n + 1) / 2. Author: Nelson Created on: 10 01 2025 """ -import unittest - -from solutions.generate_triangular_numbers import generate_triangular_numbers - - class TestGenerateTriangularNumbers(unittest.TestCase): - """ Unit test class for the generate_triangular_numbers function. @@ -30,28 +27,17 @@ class TestGenerateTriangularNumbers(unittest.TestCase): """ def test_valid_inputs(self): - """ Test the function with valid inputs. Ensures the function generates the correct list of triangular numbers for various valid inputs. """ - - # Test case: Generate the first triangular number (n=1) self.assertEqual(generate_triangular_numbers(1), [1]) - - # Test case: Generate the first 5 triangular numbers self.assertEqual(generate_triangular_numbers(5), [1, 3, 6, 10, 15]) - - # Test case: Generate the first 10 triangular numbers - self.assertEqual( - generate_triangular_numbers(10), - [1, 3, 6, 10, 15, 21, 28, 36, 45, 55], - ) + self.assertEqual(generate_triangular_numbers(10), [1, 3, 6, 10, 15, 21, 28, 36, 45, 55]) def test_invalid_inputs(self): - """ Test the function with invalid inputs. @@ -59,42 +45,22 @@ def test_invalid_inputs(self): - Non-positive integers (e.g., 0 or negative numbers). - Non-integer inputs (e.g., strings or floats). """ - - # Test case: Input is zero with self.assertRaises(ValueError): generate_triangular_numbers(0) - - # Test case: Input is a negative integer with self.assertRaises(ValueError): generate_triangular_numbers(-5) - - # Test case: Input is a string with self.assertRaises(ValueError): generate_triangular_numbers("five") - - # Test case: Input is a float with self.assertRaises(ValueError): generate_triangular_numbers(3.5) def test_edge_cases(self): - """ Test edge cases for the function. Verifies that the function handles the smallest valid input correctly. """ - - # Test case: Smallest valid input (n=1) self.assertEqual(generate_triangular_numbers(1), [1]) - if __name__ == "__main__": - - """ - Run the test suite. - - When executed as a script, this block will run all the test cases in the - TestGenerateTriangularNumbers class. - """ - unittest.main() From 682dddf0dfb319fc25b056fee5ff83cd4bf4e916 Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Sat, 11 Jan 2025 21:45:01 +0200 Subject: [PATCH 127/175] update constraints --- collaboration/constraints.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 5db9bece5..d78129b5d 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -69,9 +69,9 @@ blablab -- **Collaboration Constraints**: -- **Quality Assurance Constraints**: -- **Documentation Constraints**: +- **Collaboration Constraints**: Set roles, use tools, and ensure teamwork. +- **Quality Assurance Constraints**: Test, review, and automate checks. +- **Documentation Constraints**: Maintain clear, and up-to-date documentation. - **Coding style & conventions**: Agree on a set of guidelines for consistency across the codebase. - **Working hours**: Establish a flexible schedule that From d1e244d0ed7491a2ded717228e2fa8b3055dc71f Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Sat, 11 Jan 2025 21:48:30 +0200 Subject: [PATCH 128/175] Fix errors --- collaboration/retrospective.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/collaboration/retrospective.md b/collaboration/retrospective.md index 4c85065f4..54726a173 100644 --- a/collaboration/retrospective.md +++ b/collaboration/retrospective.md @@ -15,30 +15,33 @@ - Asking teammates if any help is needed. - Maintaining a clean and structured repository with clear README documentation. - Following the rule: 1 task = 1 branch. - + ## Start Doing - Optimize ammount of branches, commits to avoid cluttering the project. ## Lessons Learned -- Effective use of pull requests helped improve code quality and catch bugs early βœ… +- Effective use of pull requests helped improve code quality +- and catch bugs early βœ… - Frequent syncing with the remote repository avoided merge conflicts βœ… + ______________________________________________________________________ ## Strategy vs. Board ### What parts of your plan went as expected? -Pull requests were reviewed and merged according to the workflow plan. +Pull requests were reviewed and merged according to the workflow plan. ### What parts of your plan did not work out? -Overall, we completed our project quota. While some minor ideas were not fully implemented, +Overall, we completed our project quota. While some minor ideas were not fully implemented, we kept the ones with potential and iterated on them as the project progressed. ### Did you need to add things that weren't in your strategy? ### Or remove extra steps? + - Stopped requiring a review for very small, trivial changes to save time. From b2a3adaae12065aa0079d6270eded13f27fb1074 Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Sat, 11 Jan 2025 21:52:14 +0200 Subject: [PATCH 129/175] Correct a spelling mistake --- collaboration/retrospective.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collaboration/retrospective.md b/collaboration/retrospective.md index 54726a173..e8bc2b166 100644 --- a/collaboration/retrospective.md +++ b/collaboration/retrospective.md @@ -18,7 +18,7 @@ ## Start Doing -- Optimize ammount of branches, commits to avoid cluttering the project. +- Optimize amount of branches, commits to avoid cluttering the project. ## Lessons Learned From 36fdfb91f1310a61f98954ae1fa8a2f48046e9ff Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Sat, 11 Jan 2025 22:01:16 +0200 Subject: [PATCH 130/175] Update retpspective --- collaboration/retrospective.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/collaboration/retrospective.md b/collaboration/retrospective.md index e8bc2b166..81e99587e 100644 --- a/collaboration/retrospective.md +++ b/collaboration/retrospective.md @@ -6,8 +6,8 @@ ## Stop Doing -- Writing incomplete commit messages ❌ -- Doing too many commits for minor changes ❌ +- Writing incomplete commit messages +- Doing too many commits for minor changes ## Continue Doing @@ -15,16 +15,26 @@ - Asking teammates if any help is needed. - Maintaining a clean and structured repository with clear README documentation. - Following the rule: 1 task = 1 branch. +- Respecting and appreciating each other’s contributions and ideas. +- Leveraging teamwork to solve complex challenges more effectively. ## Start Doing - Optimize amount of branches, commits to avoid cluttering the project. +- Practicing and honing skills through regular coding exercises and challenges. +- Writing detailed notes during development for improved knowledge retention. ## Lessons Learned -- Effective use of pull requests helped improve code quality -- and catch bugs early βœ… -- Frequent syncing with the remote repository avoided merge conflicts βœ… +- **Effective pull request management**: Improved code quality and helped catch + bugs early. + +- **Frequent remote repository syncing**: Prevented merge conflicts +and streamlined collaboration. +- **Teamwork triumphs**: Collaborative efforts accelerated development + and enhanced overall project quality. +- **Respect wins**: Valuing diverse perspectives fostered creativity + and innovation within the team. ______________________________________________________________________ @@ -33,6 +43,8 @@ ______________________________________________________________________ ### What parts of your plan went as expected? Pull requests were reviewed and merged according to the workflow plan. +Deadlines were met consistently, showcasing strong planning and execution. +Team members actively supported one another, ensuring no one felt stuck or overwhelmed. ### What parts of your plan did not work out? From d8a6fcd188e9bed538fdbb53ddcbb2fc2a5b3ab6 Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Sat, 11 Jan 2025 22:20:09 +0200 Subject: [PATCH 131/175] update retospective --- collaboration/retrospective.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/collaboration/retrospective.md b/collaboration/retrospective.md index 81e99587e..33fa3d5f9 100644 --- a/collaboration/retrospective.md +++ b/collaboration/retrospective.md @@ -52,7 +52,9 @@ Overall, we completed our project quota. While some minor ideas were not fully i we kept the ones with potential and iterated on them as the project progressed. ### Did you need to add things that weren't in your strategy? - + +- Implemented a process for promptly resolving CI check issues. +- Established a process for efficiently handling merge conflicts. ### Or remove extra steps? From 665ada739d6d051c094badcfb1fef8c9a6a2a242 Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Sat, 11 Jan 2025 22:53:53 +0200 Subject: [PATCH 132/175] Update retrospective --- collaboration/retrospective.md | 56 +++++++++++++++++----------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/collaboration/retrospective.md b/collaboration/retrospective.md index 33fa3d5f9..a7081159f 100644 --- a/collaboration/retrospective.md +++ b/collaboration/retrospective.md @@ -9,53 +9,53 @@ - Writing incomplete commit messages - Doing too many commits for minor changes -## Continue Doing +## Continue Doing πŸ”„ -- Checking the project board regularly. -- Asking teammates if any help is needed. -- Maintaining a clean and structured repository with clear README documentation. -- Following the rule: 1 task = 1 branch. -- Respecting and appreciating each other’s contributions and ideas. -- Leveraging teamwork to solve complex challenges more effectively. +- Checking the project board regularly. πŸ“… +- Asking teammates if any help is needed. 🀝 +- Maintaining a clean and structured repository with clear README documentation.πŸ“š +- Following the rule: 1 task = 1 branch.🌱 +- Respecting and appreciating each other’s contributions and ideas.πŸ™Œ +- Leveraging teamwork to solve complex challenges more effectively.πŸ’‘ -## Start Doing +## Start DoingπŸš€ -- Optimize amount of branches, commits to avoid cluttering the project. -- Practicing and honing skills through regular coding exercises and challenges. -- Writing detailed notes during development for improved knowledge retention. +- Optimize amount of branches, commits to avoid cluttering the project.πŸ—‚οΈ +- Practicing and honing skills through regular coding exercises and challenges.πŸ’» +- Writing detailed notes during development for improved knowledge retention.πŸ“ -## Lessons Learned +## Lessons LearnedπŸ’‘ - **Effective pull request management**: Improved code quality and helped catch - bugs early. + bugs early.πŸ› - **Frequent remote repository syncing**: Prevented merge conflicts -and streamlined collaboration. +and streamlined collaboration.πŸ”„ - **Teamwork triumphs**: Collaborative efforts accelerated development - and enhanced overall project quality. + and enhanced overall project quality.🀝 - **Respect wins**: Valuing diverse perspectives fostered creativity - and innovation within the team. + and innovation within the team.🌟 ______________________________________________________________________ -## Strategy vs. Board +## Strategy vs. BoardπŸ—‚οΈ -### What parts of your plan went as expected? +### What parts of your plan went as expected?βœ… -Pull requests were reviewed and merged according to the workflow plan. -Deadlines were met consistently, showcasing strong planning and execution. -Team members actively supported one another, ensuring no one felt stuck or overwhelmed. +Pull requests were reviewed and merged according to the workflow plan. πŸ› οΈ +Deadlines were met consistently, showcasing strong planning and execution.⏰ +Team members actively supported one another, ensuring no one felt stuck or overwhelmed.πŸ’¬ -### What parts of your plan did not work out? +### What parts of your plan did not work out?❌ Overall, we completed our project quota. While some minor ideas were not fully implemented, -we kept the ones with potential and iterated on them as the project progressed. +we kept the ones with potential and iterated on them as the project progressed. πŸ”„ -### Did you need to add things that weren't in your strategy? +### Did you need to add things that weren't in your strategy?πŸ”§ -- Implemented a process for promptly resolving CI check issues. -- Established a process for efficiently handling merge conflicts. +- Implemented a process for promptly resolving CI check issues.πŸ” +- Established a process for efficiently handling merge conflicts.πŸ”€ -### Or remove extra steps? +### Or remove extra steps?❓ -- Stopped requiring a review for very small, trivial changes to save time. +- Stopped requiring a review for very small, trivial changes to save time.⏳ From 2f6f2deb9d45b86200c64150f6c0afdcdf58a4a6 Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Sat, 11 Jan 2025 23:02:44 +0200 Subject: [PATCH 133/175] Update retrospective --- collaboration/retrospective.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/collaboration/retrospective.md b/collaboration/retrospective.md index a7081159f..a8b50c35e 100644 --- a/collaboration/retrospective.md +++ b/collaboration/retrospective.md @@ -4,10 +4,10 @@ # Retrospective -## Stop Doing +## Stop Doing🚫 -- Writing incomplete commit messages -- Doing too many commits for minor changes +- Writing incomplete commit messages ✏️ +- Doing too many commits for minor changesπŸ“ ## Continue Doing πŸ”„ From 34901feb53076ee5175ff634a1a873cddc1b9c3f Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Sat, 11 Jan 2025 23:27:48 +0200 Subject: [PATCH 134/175] Update retrospective --- collaboration/retrospective.md | 54 +++++++++++++++++----------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/collaboration/retrospective.md b/collaboration/retrospective.md index a8b50c35e..dad5c7f77 100644 --- a/collaboration/retrospective.md +++ b/collaboration/retrospective.md @@ -6,56 +6,56 @@ ## Stop Doing🚫 -- Writing incomplete commit messages ✏️ -- Doing too many commits for minor changesπŸ“ +- Writing incomplete commit messages +- Doing too many commits for minor changes ## Continue Doing πŸ”„ -- Checking the project board regularly. πŸ“… -- Asking teammates if any help is needed. 🀝 -- Maintaining a clean and structured repository with clear README documentation.πŸ“š -- Following the rule: 1 task = 1 branch.🌱 -- Respecting and appreciating each other’s contributions and ideas.πŸ™Œ -- Leveraging teamwork to solve complex challenges more effectively.πŸ’‘ +- Checking the project board regularly. +- Asking teammates if any help is needed. +- Maintaining a clean and structured repository with clear README documentation. +- Following the rule: 1 task = 1 branch. +- Respecting and appreciating each other’s contributions and ideas. +- Leveraging teamwork to solve complex challenges more effectively. ## Start DoingπŸš€ -- Optimize amount of branches, commits to avoid cluttering the project.πŸ—‚οΈ -- Practicing and honing skills through regular coding exercises and challenges.πŸ’» -- Writing detailed notes during development for improved knowledge retention.πŸ“ +- Optimize amount of branches, commits to avoid cluttering the project. +- Practicing and honing skills through regular coding exercises and challenges. +- Writing detailed notes during development for improved knowledge retention. ## Lessons LearnedπŸ’‘ - **Effective pull request management**: Improved code quality and helped catch - bugs early.πŸ› + bugs early. - **Frequent remote repository syncing**: Prevented merge conflicts -and streamlined collaboration.πŸ”„ +and streamlined collaboration. - **Teamwork triumphs**: Collaborative efforts accelerated development - and enhanced overall project quality.🀝 + and enhanced overall project quality. - **Respect wins**: Valuing diverse perspectives fostered creativity - and innovation within the team.🌟 + and innovation within the team. ______________________________________________________________________ ## Strategy vs. BoardπŸ—‚οΈ -### What parts of your plan went as expected?βœ… +### What parts of your plan went as expected? -Pull requests were reviewed and merged according to the workflow plan. πŸ› οΈ -Deadlines were met consistently, showcasing strong planning and execution.⏰ -Team members actively supported one another, ensuring no one felt stuck or overwhelmed.πŸ’¬ +- Pull requests were reviewed and merged according to the workflow plan. +- Deadlines were met consistently, showcasing strong planning and execution. +- Team members actively supported one another, ensuring no one felt stuck or overwhelmed. -### What parts of your plan did not work out?❌ +### What parts of your plan did not work out? -Overall, we completed our project quota. While some minor ideas were not fully implemented, -we kept the ones with potential and iterated on them as the project progressed. πŸ”„ +- Some minor ideas were not fully implemented as planned. +- Some tasks took longer than expected due to unforeseen challenges and dependencies. -### Did you need to add things that weren't in your strategy?πŸ”§ +### Did you need to add things that weren't in your strategy? -- Implemented a process for promptly resolving CI check issues.πŸ” -- Established a process for efficiently handling merge conflicts.πŸ”€ +- Implemented a process for promptly resolving CI check issues. +- Established a process for efficiently handling merge conflicts. -### Or remove extra steps?❓ +### Or remove extra steps? -- Stopped requiring a review for very small, trivial changes to save time.⏳ +- Stopped requiring a review for very small, trivial changes to save time. From e9b6fe34a4a933a846113ecf7dfe092c862a9bd7 Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Sat, 11 Jan 2025 23:50:44 +0200 Subject: [PATCH 135/175] Add constraints summary --- collaboration/constraints.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index d78129b5d..e0c82b0e9 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -37,9 +37,14 @@ #### Summary -- **Connectivity issues**: Some team members may experience - unreliable network connections - impacting real-time collaboration +- **Connectivity Issues:** Some team members experience unreliable network connections, + impacting real-time collaboration. +- **Time Zone Differences:** Varying time zones cause scheduling conflicts + and delays in progress. +- **External Deadlines:** Academic deadlines like university exams + and college applications put pressure on team members' time. +- **Technical Skills:** Some team members may need additional support + to effectively use tools like GitHub. ## ![indoor](../assets/limited-access.png) Internal: Involuntary From 65239a4820519fd6c9b70e7493784af60f92025f Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Sun, 12 Jan 2025 00:22:58 +0200 Subject: [PATCH 136/175] Update Norms --- collaboration/README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/collaboration/README.md b/collaboration/README.md index 52b522e7b..2f62a50b2 100644 --- a/collaboration/README.md +++ b/collaboration/README.md @@ -6,7 +6,7 @@ > efficient resource use, and maintaining high-quality standards. We achieve > this by making clear communication, mutual respect, and adaptability. > Our goal is to **Grow** through **Collaboration**.\ -> In **404s**, Together, we code. Together, we grow. +> In **404s**, Together, we code. Together, we grow.🌱🀝 @@ -15,40 +15,40 @@ ### Team work -#### Clear Communication +#### Clear CommunicationπŸ—£οΈ > **Share updates and challenges with the group.**\ > **Use easy tools for async communication.**\ > **Be mindful of everyone's working hours in our international team.** -#### Collaborate, Don’t Compete +#### Collaborate, Don’t Compete🀝 > **Offer help when needed, share resources, and brainstorm together.**\ > **Celebrate success by acknowledging everyone’s contributions.** -#### Respect Diverse Skill Levels +#### Respect Diverse Skill LevelsπŸ§‘β€πŸ« > **Try to help explain concepts for other team members.**\ > **Offer constructive feedback when reviewing solutions.** -#### Respect the Group's Decisions +#### Respect the Group's DecisionsπŸ—³οΈ > **Ensure that decisions are made collectively and that everyone's voice is heard.**\ > **Stick to agreed-upon strategies, tools, and workflows to ensure consistency.** -#### Document and Share Knowledge +#### Document and Share KnowledgeπŸ“š > **Keep Notes in a shared place** --- ### Self-Development -#### Focus on Growth +#### Focus on Growth 🌱 > **Encourage Exploration new techniques that help improve your skills**\ > **Learn From Mistakes** -#### Adapt to Change +#### Adapt to Change πŸ”„ > **Be Flexible in new challenges, changes in direction, or adjusting deadlines**\ > **Adapt to Team Dynamics and be open for new changes in tools or strategies** @@ -56,12 +56,12 @@ ### Resource Development -#### Efficient Use of Time +#### Efficient Use of Time⏰ > **Time Management with agreed-on tools to keep things organized and planned ahead**\ > **Avoid Procrastination by sticking to deadlines as possible as we can** -#### Efficient Effort +#### Efficient Effort πŸ’‘ > **Work smart, not hard.** @@ -69,7 +69,7 @@ ### Quality Assurance -#### Maintain Code Quality +#### Maintain Code QualityπŸ” > **Review others’ code for quality and clarity and offer suggestions for improvement**\ > **Use Best Practices by following standard coding conventions** From 6a94ca3dfb513ace8c5111f6bfb5d80191db7536 Mon Sep 17 00:00:00 2001 From: naghambaba1 Date: Sun, 12 Jan 2025 00:52:46 +0200 Subject: [PATCH 137/175] Add Notes README --- notes/README.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/notes/README.md b/notes/README.md index 17e0f0ded..aa6702e53 100644 --- a/notes/README.md +++ b/notes/README.md @@ -1 +1,71 @@ # Notes +## How to Create a Branch + +Branches are essential to work on new features, bug fixes, + or experiments without affecting the main codebase. Here's how you can create + a branch: + +1. **Navigate to your repository:** Go to the main repository on GitHub. +2. **Create a new branch:** In your local repository, + use the command `git checkout -b ` to create and switch to a new branch. +3. **Push the branch to GitHub:** After making your changes, + push your branch to the remote repository using `git push origin `. +4. **Create a Pull Request (PR):** After pushing the branch, + go to GitHub, and create a PR to merge your changes. + +For more detailed information, refer to the official GitHub documentation on +For more detailed information, refer to the official GitHub documentation on +[Creating and Deleting Branches Within Your Repository](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-and-deleting-branches-within-your-repository). + +--- +## How to Create a Pull Request + +A Pull Request (PR) allows you to propose changes to the codebase. + Here's a general guide on how to create a pull request: + +1. **Fork the repository (if necessary):** If you are working on a forked repository, + ensure you have your own copy of the repository. +2. **Create a branch:** Start by creating a new branch to work on your feature +or bug fix. This ensures that your changes are isolated. +3. **Make your changes:** Modify the codebase as needed, ensuring to commit your + changes with meaningful messages. +4. **Push your changes:** Push your branch to the remote repository once you're + satisfied with your changes. +5. **Open a Pull Request:** Go to the repository's "Pull Requests" tab on GitHub + and click the "New Pull Request" button. Select your branch and the base branch + you want to merge into (usually `main` or `master`). +6. **Provide a description:** Describe what changes you made, why you made them, + and any additional context that may help the reviewers. +7. **Request a review:** Assign team members to review your PR and wait for + their feedback. +8. **Merge the PR:** After the review is complete, and if no conflicts exist, + the PR can be merged into the main codebase. + +For more detailed information, refer to the official GitHub documentation on + [Creating a Pull Request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). + + --- + +## How to Review a Pull Request + +Reviewing a pull request (PR) is an essential part of the collaborative process, + ensuring code quality and consistency. Here's how to review a PR: + +1. **Access the PR:** Go to the "Pull Requests" tab in the repository and + click on the PR you want to review. +2. **Understand the changes:** Read through the description provided by the author + and check the files changed tab to see the proposed changes. +3. **Review the code:** Look through the code changes, ensuring it aligns with + the coding standards, functionality, and overall project goals. You can +add comments or suggest changes. +4. **Test the changes (if applicable):** If necessary, pull the branch and test + the code locally to ensure everything works as expected. +5. **Leave Feedback:** You can leave comments or approve the PR directly. + If there are issues or improvements to be made, request changes + or leave comments for clarification. +6. **Approve or Request Changes:** Once you've reviewed the PR, you can either + approve it or request changes. If you're satisfied, approve it. + If something needs attention, request the necessary changes. + +For more detailed information, refer to the official GitHub documentation on + [Reviewing Proposed Changes in a Pull Request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/reviewing-proposed-changes-in-a-pull-request). From aca2c0727ad39511b2a0f49d67a5d240ed9296d8 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 00:13:30 +0100 Subject: [PATCH 138/175] Update test_generate_triangular_numbers.py --- solutions/tests/test_generate_triangular_numbers.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/solutions/tests/test_generate_triangular_numbers.py b/solutions/tests/test_generate_triangular_numbers.py index 2735f2ef2..04bc19c09 100644 --- a/solutions/tests/test_generate_triangular_numbers.py +++ b/solutions/tests/test_generate_triangular_numbers.py @@ -1,4 +1,5 @@ import unittest +sys.path.append("../") from solutions.generate_triangular_numbers import generate_triangular_numbers """ @@ -16,6 +17,7 @@ Created on: 10 01 2025 """ + class TestGenerateTriangularNumbers(unittest.TestCase): """ Unit test class for the generate_triangular_numbers function. @@ -62,5 +64,6 @@ def test_edge_cases(self): """ self.assertEqual(generate_triangular_numbers(1), [1]) + if __name__ == "__main__": unittest.main() From 730337ca138ee365127e27fc0cf983b9e3e73667 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 00:14:56 +0100 Subject: [PATCH 139/175] Update test_generate_triangular_numbers.py --- solutions/tests/test_generate_triangular_numbers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/solutions/tests/test_generate_triangular_numbers.py b/solutions/tests/test_generate_triangular_numbers.py index 04bc19c09..5d7e13399 100644 --- a/solutions/tests/test_generate_triangular_numbers.py +++ b/solutions/tests/test_generate_triangular_numbers.py @@ -1,5 +1,4 @@ import unittest -sys.path.append("../") from solutions.generate_triangular_numbers import generate_triangular_numbers """ From cf76a748560960b1621d291bc2547fc956458311 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 00:19:19 +0100 Subject: [PATCH 140/175] Update test_generate_triangular_numbers.py --- solutions/tests/test_generate_triangular_numbers.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/solutions/tests/test_generate_triangular_numbers.py b/solutions/tests/test_generate_triangular_numbers.py index 5d7e13399..bbc683835 100644 --- a/solutions/tests/test_generate_triangular_numbers.py +++ b/solutions/tests/test_generate_triangular_numbers.py @@ -1,6 +1,3 @@ -import unittest -from solutions.generate_triangular_numbers import generate_triangular_numbers - """ Unit tests for the generate_triangular_numbers function. @@ -17,6 +14,10 @@ """ +import unittest +from solutions.generate_triangular_numbers import generate_triangular_numbers + + class TestGenerateTriangularNumbers(unittest.TestCase): """ Unit test class for the generate_triangular_numbers function. @@ -27,7 +28,7 @@ class TestGenerateTriangularNumbers(unittest.TestCase): - Verify edge cases. """ - def test_valid_inputs(self): + def test_valid_inputs(self)-> None: """ Test the function with valid inputs. @@ -38,7 +39,7 @@ def test_valid_inputs(self): self.assertEqual(generate_triangular_numbers(5), [1, 3, 6, 10, 15]) self.assertEqual(generate_triangular_numbers(10), [1, 3, 6, 10, 15, 21, 28, 36, 45, 55]) - def test_invalid_inputs(self): + def test_invalid_inputs(self)-> None: """ Test the function with invalid inputs. @@ -55,7 +56,7 @@ def test_invalid_inputs(self): with self.assertRaises(ValueError): generate_triangular_numbers(3.5) - def test_edge_cases(self): + def test_edge_cases(self)-> None: """ Test edge cases for the function. From 04c608748d3db5b515792dea4f8182c17e7b2769 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 00:28:48 +0100 Subject: [PATCH 141/175] Update test_generate_triangular_numbers.py --- .../tests/test_generate_triangular_numbers.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/solutions/tests/test_generate_triangular_numbers.py b/solutions/tests/test_generate_triangular_numbers.py index bbc683835..e2f66efc8 100644 --- a/solutions/tests/test_generate_triangular_numbers.py +++ b/solutions/tests/test_generate_triangular_numbers.py @@ -1,19 +1,3 @@ -""" -Unit tests for the generate_triangular_numbers function. - -This code tests the functionality of the generate_triangular_numbers function -from the solutions.generate_triangular_numbers module. It verifies that the -function correctly generates triangular numbers for valid inputs and raises -appropriate exceptions for invalid inputs. - -A triangular number is defined as the sum of the first n natural numbers, -calculated using the formula: n * (n + 1) / 2. - -Author: Nelson -Created on: 10 01 2025 -""" - - import unittest from solutions.generate_triangular_numbers import generate_triangular_numbers From d5de4350b7f547cdfc7e2d4d47296e6b73bb9c83 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 00:40:31 +0100 Subject: [PATCH 142/175] Update test_generate_triangular_numbers.py --- .../tests/test_generate_triangular_numbers.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/solutions/tests/test_generate_triangular_numbers.py b/solutions/tests/test_generate_triangular_numbers.py index e2f66efc8..a9ea80a17 100644 --- a/solutions/tests/test_generate_triangular_numbers.py +++ b/solutions/tests/test_generate_triangular_numbers.py @@ -1,3 +1,11 @@ +""" +Unit tests for the generate_triangular_numbers function +in the solutions.generate_triangular_numbers module. + +This module contains a set of test cases to ensure the correctness of the +generate_triangular_numbers function, which generates triangular numbers for given inputs. +""" + import unittest from solutions.generate_triangular_numbers import generate_triangular_numbers @@ -12,7 +20,7 @@ class TestGenerateTriangularNumbers(unittest.TestCase): - Verify edge cases. """ - def test_valid_inputs(self)-> None: + def test_valid_inputs(self) -> None: """ Test the function with valid inputs. @@ -21,9 +29,12 @@ def test_valid_inputs(self)-> None: """ self.assertEqual(generate_triangular_numbers(1), [1]) self.assertEqual(generate_triangular_numbers(5), [1, 3, 6, 10, 15]) - self.assertEqual(generate_triangular_numbers(10), [1, 3, 6, 10, 15, 21, 28, 36, 45, 55]) + self.assertEqual( + generate_triangular_numbers(10), + [1, 3, 6, 10, 15, 21, 28, 36, 45, 55], + ) - def test_invalid_inputs(self)-> None: + def test_invalid_inputs(self) -> None: """ Test the function with invalid inputs. @@ -40,7 +51,7 @@ def test_invalid_inputs(self)-> None: with self.assertRaises(ValueError): generate_triangular_numbers(3.5) - def test_edge_cases(self)-> None: + def test_edge_cases(self) -> None: """ Test edge cases for the function. From 3b2f852863075e47635932b87c5087312646363f Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 01:14:36 +0100 Subject: [PATCH 143/175] Update generate_triangular_numbers.py --- solutions/generate_triangular_numbers.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/solutions/generate_triangular_numbers.py b/solutions/generate_triangular_numbers.py index 9e2178977..d415c1e0a 100644 --- a/solutions/generate_triangular_numbers.py +++ b/solutions/generate_triangular_numbers.py @@ -7,9 +7,6 @@ This module offers the following functionality: - `generate_triangular_numbers(n)`: Generates a list of the first n triangular numbers. - -Created on XX XX XX -@author: Nelson Fodjo & Gemini AI """ From aac956631365f3e4e7a50829098b9d562b331370 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 02:02:25 +0100 Subject: [PATCH 144/175] Add files via upload --- solutions/count_vowels.py | 20 ++++++++++++++++++++ solutions/fizz_buzz.py | 30 ++++++++++++++++++++++++++++++ solutions/reverse_string.py | 15 +++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 solutions/count_vowels.py create mode 100644 solutions/fizz_buzz.py create mode 100644 solutions/reverse_string.py diff --git a/solutions/count_vowels.py b/solutions/count_vowels.py new file mode 100644 index 000000000..142a86ebc --- /dev/null +++ b/solutions/count_vowels.py @@ -0,0 +1,20 @@ +def count_vowels(s): + """ + Counts the number of vowels in the given string. + + Parameters: + s (str): The string in which to count vowels. + + Returns: + int: The number of vowels in the string. + + Example: + >>> count_vowels("hello") + 2 + >>> count_vowels("Nelsona") + 3 + """ + vowels = "aeiouAEIOU" # Define vowels (both lowercase and uppercase) + return sum( + 1 for char in s if char in vowels + ) # Count vowels using a generator expression diff --git a/solutions/fizz_buzz.py b/solutions/fizz_buzz.py new file mode 100644 index 000000000..a4329a079 --- /dev/null +++ b/solutions/fizz_buzz.py @@ -0,0 +1,30 @@ +def fizz_buzz(n): + """ + Generates a list of numbers from 1 to n with the following rules: + - For multiples of 3, "Fizz" is added instead of the number. + - For multiples of 5, "Buzz" is added instead of the number. + - For multiples of both 3 and 5, "FizzBuzz" is added instead of the number. + + Parameters: + n (int): The upper limit of the range (inclusive) to generate. + + Returns: + list: A list containing the numbers and/or string representations according to the rules. + + Example: + >>> fizzbuzz(15) + [1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14, 'FizzBuzz'] + """ + results = [] # Initialize an empty list to store the results + for i in range(1, n + 1): + if i % 3 == 0 and i % 5 == 0: + results.append( + "FizzBuzz" + ) # Append "FizzBuzz" for multiples of both 3 and 5 + elif i % 3 == 0: + results.append("Fizz") # Append "Fizz" for multiples of 3 + elif i % 5 == 0: + results.append("Buzz") # Append "Buzz" for multiples of 5 + else: + results.append(i) # Append the number itself if not a multiple of 3 or 5 + return results # Return the list of results diff --git a/solutions/reverse_string.py b/solutions/reverse_string.py new file mode 100644 index 000000000..045d135ac --- /dev/null +++ b/solutions/reverse_string.py @@ -0,0 +1,15 @@ +def reverse_string(s): + """ + Reverses the given string. + + Parameters: + s (str): The string to be reversed. + + Returns: + str: The reversed string. + + Example: + >>> reverse_string("hello") + 'olleh' + """ + return s[::-1] # Return the reversed string using slicing From 310dbe6022a9315aefb7a080126c566c2c98c735 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 02:03:36 +0100 Subject: [PATCH 145/175] Add files via upload --- solutions/tests/test_count_vowels.py | 55 ++++++++++++++++++ solutions/tests/test_fizz_buzz.py | 77 ++++++++++++++++++++++++++ solutions/tests/test_reverse_string.py | 56 +++++++++++++++++++ 3 files changed, 188 insertions(+) create mode 100644 solutions/tests/test_count_vowels.py create mode 100644 solutions/tests/test_fizz_buzz.py create mode 100644 solutions/tests/test_reverse_string.py diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py new file mode 100644 index 000000000..043b86ed3 --- /dev/null +++ b/solutions/tests/test_count_vowels.py @@ -0,0 +1,55 @@ +import unittest + +from solutions.count_vowels import count_vowels # Import the count_vowels function + + +class TestCountVowels(unittest.TestCase): + """Test cases for the count_vowels function. + + This class contains unit tests for the count_vowels function to ensure + that it accurately counts the number of vowels in various input strings. + """ + + def test_count_vowels_normal(self): + """Test counting vowels in a normal string. + + This test checks that the function correctly counts the vowels in a + typical string with mixed characters. + """ + self.assertEqual(count_vowels("Nagham"), 2) + + def test_count_vowels_empty(self): + """Test counting vowels in an empty string. + + This test verifies that the function returns 0 when the input string + is empty. + """ + self.assertEqual(count_vowels(""), 0) + + def test_count_vowels_no_vowels(self): + """Test counting vowels in a string with no vowels. + + This test checks that the function returns 0 when there are no vowels + in the input string. + """ + self.assertEqual(count_vowels("bcdfghjklmnpqrstvwxyz"), 0) + + def test_count_vowels_case_insensitive(self): + """Test counting vowels in a case-insensitive manner. + + This test verifies that the function counts both uppercase and lowercase + vowels correctly. + """ + self.assertEqual(count_vowels("AbEcIdOfUg"), 5) + + def test_count_vowels_with_spaces(self): + """Test counting vowels in a string with spaces. + + This test checks that the function correctly counts vowels in a string + that contains spaces and punctuation. + """ + self.assertEqual(count_vowels("Hello World!"), 3) + + +if __name__ == "__main__": + unittest.main() diff --git a/solutions/tests/test_fizz_buzz.py b/solutions/tests/test_fizz_buzz.py new file mode 100644 index 000000000..124eb14cd --- /dev/null +++ b/solutions/tests/test_fizz_buzz.py @@ -0,0 +1,77 @@ +import unittest + +from solutions.fizz_buzz import fizz_buzz + + +class TestFizzBuzz(unittest.TestCase): + """Test cases for the fizzbuzz function. + + This class contains unit tests for the fizzbuzz function to ensure + that it produces the expected output for various input values. + """ + + def test_fizzbuzz_15(self): + """Test FizzBuzz for n = 15. + + This test checks that the output for n=15 matches the expected + list which includes Fizz, Buzz, and FizzBuzz at the correct + positions. + """ + expected = [ + 1, + 2, + "Fizz", + 4, + "Buzz", + "Fizz", + 7, + 8, + "Fizz", + "Buzz", + 11, + "Fizz", + 13, + 14, + "FizzBuzz", + ] + self.assertEqual(fizz_buzz(15), expected) + + def test_fizzbuzz_3(self): + """Test FizzBuzz for n = 3. + + This test checks that for n=3, the output should return + a list containing the numbers 1, 2, and 'Fizz'. + """ + expected = [1, 2, "Fizz"] + self.assertEqual(fizz_buzz(3), expected) + + def test_fizzbuzz_5(self): + """Test FizzBuzz for n = 5. + + This test verifies that for n=5, the output list includes + numbers 1, 2, 'Fizz', 4, and 'Buzz'. + """ + expected = [1, 2, "Fizz", 4, "Buzz"] + self.assertEqual(fizz_buzz(5), expected) + + def test_fizzbuzz_1(self): + """Test FizzBuzz for n = 1. + + This test checks that for n=1, the output should simply be + a list containing the number 1. + """ + expected = [1] + self.assertEqual(fizz_buzz(1), expected) + + def test_fizzbuzz_0(self): + """Test FizzBuzz for n = 0. + + This test checks that for n=0, the output should be an + empty list since there are no numbers to include. + """ + expected = [] + self.assertEqual(fizz_buzz(0), expected) + + +if __name__ == "__main__": + unittest.main() diff --git a/solutions/tests/test_reverse_string.py b/solutions/tests/test_reverse_string.py new file mode 100644 index 000000000..b0e906522 --- /dev/null +++ b/solutions/tests/test_reverse_string.py @@ -0,0 +1,56 @@ +import unittest +from solutions.reverse_string import ( + reverse_string, +) # Import the reverse_string function + + +class TestReverseString(unittest.TestCase): + """Test cases for the reverse_string function. + + This class contains unit tests for the reverse_string function to ensure + that it correctly reverses strings under various scenarios. + """ + + def test_reverse_normal(self): + """Test reversing a normal string. + + This test checks that the function correctly reverses a typical string + with multiple characters. + """ + self.assertEqual(reverse_string("hello"), "olleh") + + def test_reverse_empty(self): + """Test reversing an empty string. + + This test verifies that the function returns an empty string when + the input is empty. + """ + self.assertEqual(reverse_string(""), "") + + def test_reverse_single_character(self): + """Test reversing a single character string. + + This test checks that the function returns the same character when + the input is a single character string. + """ + self.assertEqual(reverse_string("a"), "a") + + def test_reverse_palindrome(self): + """Test reversing a palindrome. + + This test verifies that the function returns the same string when + the input is a palindrome. + """ + self.assertEqual(reverse_string("madam"), "madam") + + def test_reverse_spaces(self): + """Test reversing a string with spaces. + + This test checks that the function correctly reverses a string that + contains spaces, ensuring that the spaces are also reversed. + """ + self.assertEqual(reverse_string("hello world"), "dlrow olleh") + + +if __name__ == "__main__": + unittest.main() From d9a1a37a04d0b7ef67e1c39a09a8b93be6e33099 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 02:05:41 +0100 Subject: [PATCH 146/175] Update fizz_buzz.py From aac38adf36df331bc9bab1db4d6ffeeecc8411fe Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 02:06:23 +0100 Subject: [PATCH 147/175] Update fizz_buzz.py --- solutions/fizz_buzz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/fizz_buzz.py b/solutions/fizz_buzz.py index a4329a079..eea2d3986 100644 --- a/solutions/fizz_buzz.py +++ b/solutions/fizz_buzz.py @@ -12,7 +12,7 @@ def fizz_buzz(n): list: A list containing the numbers and/or string representations according to the rules. Example: - >>> fizzbuzz(15) + >>> fizz_buzz(15) [1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14, 'FizzBuzz'] """ results = [] # Initialize an empty list to store the results From 6657a8519ec5aba983950d1202013520a9ddfe29 Mon Sep 17 00:00:00 2001 From: matopcheg Date: Sun, 12 Jan 2025 08:55:04 +0200 Subject: [PATCH 148/175] solve #49 --- solutions/letter_combinations.py | 57 +++++++++++++++++++++ solutions/tests/test_letter_combinations.py | 41 +++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 solutions/letter_combinations.py create mode 100644 solutions/tests/test_letter_combinations.py diff --git a/solutions/letter_combinations.py b/solutions/letter_combinations.py new file mode 100644 index 000000000..318688315 --- /dev/null +++ b/solutions/letter_combinations.py @@ -0,0 +1,57 @@ +"""Module for generating letter combinations from a telephone keypad. + +This module defines a function that returns all possible letter +combinations for a string of digits in the range '2'..'9' inclusive. + +The mapping follows the typical telephone keypad layout: + 2 -> a, b, c + 3 -> d, e, f + 4 -> g, h, i + 5 -> j, k, l + 6 -> m, n, o + 7 -> p, q, r, s + 8 -> t, u, v + 9 -> w, x, y, z +""" + + +def letter_combinations(digits: str) -> list[str]: + """ + Return all possible letter combinations for the given digits. + + :param digits: str + :return: list[str] + + :raises AssertionError: If `digits` is not a string. + :raises AssertionError: If `digits` contains characters outside '2'..'9'. + :raises AssertionError: If `digits` is longer than 4 characters. """ + + assert isinstance(digits, str), "digits must be a string" + assert len(digits) <= 4, "digits can have at most 4 characters" + for digit in digits: + assert digit in "23456789", "All digits must be in range '2'..'9'" + + if not digits: + return [] + + phone_map = { + "2": "abc", + "3": "def", + "4": "ghi", + "5": "jkl", + "6": "mno", + "7": "pqrs", + "8": "tuv", + "9": "wxyz", + } + + result: list[str] = [] + + def backtrack(combination: str, remaining_digits: str) -> None: # recursive combinations + if not remaining_digits: + result.append(combination) + else: + for letter in phone_map[remaining_digits[0]]: + backtrack(combination + letter, remaining_digits[1:]) + backtrack("", digits) + return result diff --git a/solutions/tests/test_letter_combinations.py b/solutions/tests/test_letter_combinations.py new file mode 100644 index 000000000..a108389c5 --- /dev/null +++ b/solutions/tests/test_letter_combinations.py @@ -0,0 +1,41 @@ +import unittest +from solutions.letter_combinations import letter_combinations + + +class TestLetterCombinations(unittest.TestCase): + """Tests for the letter_combinations function using unittest.""" + + def test1(self): + """Test '23' returns the expected nine combinations.""" + expected = ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"] + self.assertEqual(sorted(letter_combinations("23")), sorted(expected)) + + def test2(self): + """Test empty string returns an empty list.""" + self.assertEqual(letter_combinations(""), []) + + def test3(self): + """Test '2' returns ['a', 'b', 'c'].""" + expected = ["a", "b", "c"] + self.assertEqual(letter_combinations("2"), expected) + + def test4(self): + """Test that digits outside '2'..'9' raise an AssertionError.""" + with self.assertRaises(AssertionError): + letter_combinations("1") + + def test5(self): + """Test that more than four digits raise an AssertionError.""" + with self.assertRaises(AssertionError): + letter_combinations("23456") + + def test6(self): + """ + Test '727' returns 48 distinct combinations. + Therefore, we'll just check the number of combinations to avoid overloading our code""" + result = letter_combinations("727") + self.assertEqual(len(result), 48) + + +if __name__ == "__main__": + unittest.main() From b191aaecdfd17c16cead0cfc45eaba63e3035fed Mon Sep 17 00:00:00 2001 From: matopcheg Date: Sun, 12 Jan 2025 08:56:20 +0200 Subject: [PATCH 149/175] ruff formatting --- solutions/letter_combinations.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/solutions/letter_combinations.py b/solutions/letter_combinations.py index 318688315..984e11266 100644 --- a/solutions/letter_combinations.py +++ b/solutions/letter_combinations.py @@ -24,7 +24,7 @@ def letter_combinations(digits: str) -> list[str]: :raises AssertionError: If `digits` is not a string. :raises AssertionError: If `digits` contains characters outside '2'..'9'. - :raises AssertionError: If `digits` is longer than 4 characters. """ + :raises AssertionError: If `digits` is longer than 4 characters.""" assert isinstance(digits, str), "digits must be a string" assert len(digits) <= 4, "digits can have at most 4 characters" @@ -47,11 +47,14 @@ def letter_combinations(digits: str) -> list[str]: result: list[str] = [] - def backtrack(combination: str, remaining_digits: str) -> None: # recursive combinations + def backtrack( + combination: str, remaining_digits: str + ) -> None: # recursive combinations if not remaining_digits: result.append(combination) else: for letter in phone_map[remaining_digits[0]]: backtrack(combination + letter, remaining_digits[1:]) + backtrack("", digits) return result From 144c8089fc37ab655bd3270bd35ce54c44559bf4 Mon Sep 17 00:00:00 2001 From: matopcheg Date: Sun, 12 Jan 2025 09:05:20 +0200 Subject: [PATCH 150/175] minor changes --- solutions/letter_combinations.py | 5 +---- solutions/tests/test_letter_combinations.py | 6 ++---- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/solutions/letter_combinations.py b/solutions/letter_combinations.py index 984e11266..ec8b3603c 100644 --- a/solutions/letter_combinations.py +++ b/solutions/letter_combinations.py @@ -1,9 +1,6 @@ """Module for generating letter combinations from a telephone keypad. -This module defines a function that returns all possible letter -combinations for a string of digits in the range '2'..'9' inclusive. - -The mapping follows the typical telephone keypad layout: +The mapping follows: 2 -> a, b, c 3 -> d, e, f 4 -> g, h, i diff --git a/solutions/tests/test_letter_combinations.py b/solutions/tests/test_letter_combinations.py index a108389c5..a4cea5999 100644 --- a/solutions/tests/test_letter_combinations.py +++ b/solutions/tests/test_letter_combinations.py @@ -1,7 +1,6 @@ import unittest from solutions.letter_combinations import letter_combinations - class TestLetterCombinations(unittest.TestCase): """Tests for the letter_combinations function using unittest.""" @@ -31,11 +30,10 @@ def test5(self): def test6(self): """ - Test '727' returns 48 distinct combinations. + Test '727' returns 48 distinct combinations. Therefore, we'll just check the number of combinations to avoid overloading our code""" - result = letter_combinations("727") + result = letter_combinations("727") #WYSI self.assertEqual(len(result), 48) - if __name__ == "__main__": unittest.main() From 6e6b57c3f918caf1c334b45d1ccbbd8b737d861f Mon Sep 17 00:00:00 2001 From: matopcheg Date: Sun, 12 Jan 2025 09:06:16 +0200 Subject: [PATCH 151/175] ruff formatting --- solutions/tests/test_letter_combinations.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/solutions/tests/test_letter_combinations.py b/solutions/tests/test_letter_combinations.py index a4cea5999..fdc4e91f0 100644 --- a/solutions/tests/test_letter_combinations.py +++ b/solutions/tests/test_letter_combinations.py @@ -1,6 +1,7 @@ import unittest from solutions.letter_combinations import letter_combinations + class TestLetterCombinations(unittest.TestCase): """Tests for the letter_combinations function using unittest.""" @@ -30,10 +31,11 @@ def test5(self): def test6(self): """ - Test '727' returns 48 distinct combinations. + Test '727' returns 48 distinct combinations. Therefore, we'll just check the number of combinations to avoid overloading our code""" - result = letter_combinations("727") #WYSI + result = letter_combinations("727") # WYSI self.assertEqual(len(result), 48) + if __name__ == "__main__": unittest.main() From b3894775f8bda2778d88ee24454b90005eeb8f50 Mon Sep 17 00:00:00 2001 From: matopcheg Date: Sun, 12 Jan 2025 09:24:16 +0200 Subject: [PATCH 152/175] add module docstring, minor changes --- solutions/letter_combinations.py | 10 +++++++++- solutions/tests/test_letter_combinations.py | 14 ++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/solutions/letter_combinations.py b/solutions/letter_combinations.py index ec8b3603c..9323c2b22 100644 --- a/solutions/letter_combinations.py +++ b/solutions/letter_combinations.py @@ -21,7 +21,15 @@ def letter_combinations(digits: str) -> list[str]: :raises AssertionError: If `digits` is not a string. :raises AssertionError: If `digits` contains characters outside '2'..'9'. - :raises AssertionError: If `digits` is longer than 4 characters.""" + :raises AssertionError: If `digits` is longer than 4 characters. + + >>> letter_combinations('23') + ['ad', 'ae', 'af', 'bd', 'be', 'bf', 'cd', 'ce', 'cf'] + >>> letter_combinations('2') + ['a', 'b', 'c'] + >>> letter_combinations('') + [] + """ assert isinstance(digits, str), "digits must be a string" assert len(digits) <= 4, "digits can have at most 4 characters" diff --git a/solutions/tests/test_letter_combinations.py b/solutions/tests/test_letter_combinations.py index fdc4e91f0..5bed2fc82 100644 --- a/solutions/tests/test_letter_combinations.py +++ b/solutions/tests/test_letter_combinations.py @@ -1,3 +1,5 @@ +"""Test file for the letter_combinations function using unittest.""" + import unittest from solutions.letter_combinations import letter_combinations @@ -5,31 +7,31 @@ class TestLetterCombinations(unittest.TestCase): """Tests for the letter_combinations function using unittest.""" - def test1(self): + def test1_check_23(self): """Test '23' returns the expected nine combinations.""" expected = ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"] self.assertEqual(sorted(letter_combinations("23")), sorted(expected)) - def test2(self): + def test_check_empty_string(self): """Test empty string returns an empty list.""" self.assertEqual(letter_combinations(""), []) - def test3(self): + def test_check_2(self): """Test '2' returns ['a', 'b', 'c'].""" expected = ["a", "b", "c"] self.assertEqual(letter_combinations("2"), expected) - def test4(self): + def test_check_boundary_cases(self): """Test that digits outside '2'..'9' raise an AssertionError.""" with self.assertRaises(AssertionError): letter_combinations("1") - def test5(self): + def test_out_of_limit(self): """Test that more than four digits raise an AssertionError.""" with self.assertRaises(AssertionError): letter_combinations("23456") - def test6(self): + def test_check_727(self): """ Test '727' returns 48 distinct combinations. Therefore, we'll just check the number of combinations to avoid overloading our code""" From 4430d28fef052ddca5a7d810916343a66803c345 Mon Sep 17 00:00:00 2001 From: matopcheg Date: Sun, 12 Jan 2025 09:24:45 +0200 Subject: [PATCH 153/175] add module docstring, minor changes, ruff formatting --- solutions/letter_combinations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/letter_combinations.py b/solutions/letter_combinations.py index 9323c2b22..c777fc24b 100644 --- a/solutions/letter_combinations.py +++ b/solutions/letter_combinations.py @@ -23,7 +23,7 @@ def letter_combinations(digits: str) -> list[str]: :raises AssertionError: If `digits` contains characters outside '2'..'9'. :raises AssertionError: If `digits` is longer than 4 characters. - >>> letter_combinations('23') + >>> letter_combinations('23') ['ad', 'ae', 'af', 'bd', 'be', 'bf', 'cd', 'ce', 'cf'] >>> letter_combinations('2') ['a', 'b', 'c'] From 0fd0cca4a8a84d41473cfe19160f3fc9b26f0fcb Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sun, 12 Jan 2025 11:30:25 +0200 Subject: [PATCH 154/175] Modify type annotation --- solutions/minion_game.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/minion_game.py b/solutions/minion_game.py index fe60bd035..499ab2760 100644 --- a/solutions/minion_game.py +++ b/solutions/minion_game.py @@ -13,7 +13,7 @@ """ -def minion_game(text): +def minion_game(text : str): """ Determines the winner of the Minion Game based on the input string. From b2e7dc8b7c112073f1b3bb77be23b65de4b2356d Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sun, 12 Jan 2025 11:33:42 +0200 Subject: [PATCH 155/175] Fix formatting issue --- solutions/minion_game.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/minion_game.py b/solutions/minion_game.py index 499ab2760..175b5580b 100644 --- a/solutions/minion_game.py +++ b/solutions/minion_game.py @@ -13,7 +13,7 @@ """ -def minion_game(text : str): +def minion_game(text: str): """ Determines the winner of the Minion Game based on the input string. From 12aec321be245731aa0330005416b630628e2d41 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 13:52:36 +0100 Subject: [PATCH 156/175] Update fizz_buzz.py --- solutions/fizz_buzz.py | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/solutions/fizz_buzz.py b/solutions/fizz_buzz.py index eea2d3986..d42bf48b0 100644 --- a/solutions/fizz_buzz.py +++ b/solutions/fizz_buzz.py @@ -1,9 +1,22 @@ -def fizz_buzz(n): +""" +This module contains the fizz_buzz function which generates a list +of numbers from 1 to n with specific substitutions for multiples +of 3 and/or 5. + +The function follows the FizzBuzz rules: +- For multiples of 3, "Fizz" is added. +- For multiples of 5, "Buzz" is added. +- For multiples of both 3 and 5, "FizzBuzz" is added. + +Example usage: +>>> fizz_buzz(15) +[1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14, 'FizzBuzz'] +""" + + +def fizz_buzz(n: int) -> list: """ - Generates a list of numbers from 1 to n with the following rules: - - For multiples of 3, "Fizz" is added instead of the number. - - For multiples of 5, "Buzz" is added instead of the number. - - For multiples of both 3 and 5, "FizzBuzz" is added instead of the number. + Generates a list of numbers from 1 to n with specific rules. Parameters: n (int): The upper limit of the range (inclusive) to generate. @@ -14,13 +27,18 @@ def fizz_buzz(n): Example: >>> fizz_buzz(15) [1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14, 'FizzBuzz'] + >>> fizz_buzz(3) + [1, 2, 'Fizz'] + >>> fizz_buzz(5) + [1, 2, 'Fizz', 4, 'Buzz'] """ + # Defensive assertion to check that n is a positive integer + assert isinstance(n, int) and n > 0, "Input must be a positive integer" + results = [] # Initialize an empty list to store the results for i in range(1, n + 1): if i % 3 == 0 and i % 5 == 0: - results.append( - "FizzBuzz" - ) # Append "FizzBuzz" for multiples of both 3 and 5 + results.append("FizzBuzz") # Append "FizzBuzz" for multiples of both 3 and 5 elif i % 3 == 0: results.append("Fizz") # Append "Fizz" for multiples of 3 elif i % 5 == 0: From faf955c0bad2ae1ad648a3c3df88fe11b24b0dcb Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sun, 12 Jan 2025 14:53:36 +0200 Subject: [PATCH 157/175] Update learning goals --- collaboration/learning_goals.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 9203d13d1..c24cadb1c 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -47,9 +47,9 @@ | **Goal** | **Description** | **Progress** | |------------------------------------|----------------| ----------------| -| πŸ› οΈ Unleash the Secrets of Git |Dive deep into Git and GitHub | ![50%](https://progress-bar.xyz/50) | -| ⚑ TDD: Your New Superpower | Use Test-Driven Development to code with confidence.| ![20%](https://progress-bar.xyz/20) | -| πŸŽ‰ Level Up Your Code Review Game | Collaborate with your my and grow stronger together.| ![10%](https://progress-bar.xyz/10) | +| πŸ› οΈ Unleash the Secrets of Git |Dive deep into Git and GitHub | ![90%](https://progress-bar.xyz/90) | +| ⚑ TDD: Your New Superpower | Use Test-Driven Development to code with confidence.| ![30%](https://progress-bar.xyz/30) | +| πŸŽ‰ Level Up Your Code Review Game | Collaborate with your my and grow stronger together.| ![70%](https://progress-bar.xyz/70) | --- From 24e3f4b2a08a94974a3a31745fe9f0d117e39851 Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sun, 12 Jan 2025 14:53:51 +0200 Subject: [PATCH 158/175] Update notes --- notes/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/notes/README.md b/notes/README.md index aa6702e53..29964413f 100644 --- a/notes/README.md +++ b/notes/README.md @@ -1,4 +1,17 @@ # Notes + +## Our Workflow + +- Create Issue +- add to project board +- create a branch +- push your code via vscode and create a pull request for it +- link the issue with your pull requests +- wait for someone to assign himself as reviewer and review it. +- after finish reviewing, merge the PR +- issue closed immediately, and make sure it also moved to the β€œDONE” + column on the project board + ## How to Create a Branch Branches are essential to work on new features, bug fixes, From bbcc15275686071a1c85deea3b7dd64ceb0614c8 Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sun, 12 Jan 2025 15:51:40 +0200 Subject: [PATCH 159/175] Update communication --- collaboration/communication.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/collaboration/communication.md b/collaboration/communication.md index 9346cbd46..fc913c03c 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -14,11 +14,10 @@ ______________________________________________________________________ ## Communication Schedule -| Meeting | Type| Frequency| How| The topic of discussion| -|----------------|-----|----------------|---------------|-----| -| Brain Storming | TBD | TBD| Google Meet | Group Norms| -| Collaboration | TBD | TBD| Google Meet | Constraints, learning goals| -| Collaboration | TBD | TBD| Google Meet | Communication| +| Meeting | Frequency| How| The topic of discussion| +|----------------|----------------|---------------|-----| +| Brain Storming | Weekly | Google Meet | Define norms, constraints, etc.| +| Fixing issues | On demand | slack, Whatsapp | Fix issues on code and github| ## Communication Channels @@ -38,7 +37,12 @@ ______________________________________________________________________ "channel": "Github issues/discussions", "purpose": "Discuss changes/code reviews", "frequency": "On demand" - } + }, + { + "channel": "Whatsapp", + "purpose": "Discuss general topics", + "frequency": "On demand" + }, ] ``` From 6a42c067194f05bdb95326c96513483676b3259e Mon Sep 17 00:00:00 2001 From: salemAmassi Date: Sun, 12 Jan 2025 16:15:49 +0200 Subject: [PATCH 160/175] Add points to retrospective --- collaboration/retrospective.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/collaboration/retrospective.md b/collaboration/retrospective.md index dad5c7f77..942471fc8 100644 --- a/collaboration/retrospective.md +++ b/collaboration/retrospective.md @@ -35,6 +35,8 @@ and streamlined collaboration. and enhanced overall project quality. - **Respect wins**: Valuing diverse perspectives fostered creativity and innovation within the team. +- **Strict to our rules**: we have should follow some rules we announced in the early + stage. ______________________________________________________________________ @@ -50,6 +52,8 @@ ______________________________________________________________________ - Some minor ideas were not fully implemented as planned. - Some tasks took longer than expected due to unforeseen challenges and dependencies. +- We have should divide big feature to smaller features with independent branches +like collaboration branch. ### Did you need to add things that weren't in your strategy? From 8a51d8a17fc7e12a336403cd58cae03ce0b1e3c7 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 21:46:02 +0100 Subject: [PATCH 161/175] Update fizz_buzz.py --- solutions/fizz_buzz.py | 38 +++++++++----------------------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/solutions/fizz_buzz.py b/solutions/fizz_buzz.py index d42bf48b0..fda334441 100644 --- a/solutions/fizz_buzz.py +++ b/solutions/fizz_buzz.py @@ -1,22 +1,9 @@ -""" -This module contains the fizz_buzz function which generates a list -of numbers from 1 to n with specific substitutions for multiples -of 3 and/or 5. - -The function follows the FizzBuzz rules: -- For multiples of 3, "Fizz" is added. -- For multiples of 5, "Buzz" is added. -- For multiples of both 3 and 5, "FizzBuzz" is added. - -Example usage: ->>> fizz_buzz(15) -[1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14, 'FizzBuzz'] -""" - - -def fizz_buzz(n: int) -> list: +def fizzbuzz(n: int) -> list: """ - Generates a list of numbers from 1 to n with specific rules. + Generates a list of numbers from 1 to n with the following rules: + - For multiples of 3, "Fizz" is added instead of the number. + - For multiples of 5, "Buzz" is added instead of the number. + - For multiples of both 3 and 5, "FizzBuzz" is added instead of the number. Parameters: n (int): The upper limit of the range (inclusive) to generate. @@ -25,24 +12,17 @@ def fizz_buzz(n: int) -> list: list: A list containing the numbers and/or string representations according to the rules. Example: - >>> fizz_buzz(15) + >>> fizzbuzz(15) [1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14, 'FizzBuzz'] - >>> fizz_buzz(3) - [1, 2, 'Fizz'] - >>> fizz_buzz(5) - [1, 2, 'Fizz', 4, 'Buzz'] """ - # Defensive assertion to check that n is a positive integer - assert isinstance(n, int) and n > 0, "Input must be a positive integer" - results = [] # Initialize an empty list to store the results for i in range(1, n + 1): if i % 3 == 0 and i % 5 == 0: results.append("FizzBuzz") # Append "FizzBuzz" for multiples of both 3 and 5 elif i % 3 == 0: - results.append("Fizz") # Append "Fizz" for multiples of 3 + results.append("Fizz") # Append "Fizz" for multiples of 3 elif i % 5 == 0: - results.append("Buzz") # Append "Buzz" for multiples of 5 + results.append("Buzz") # Append "Buzz" for multiples of 5 else: - results.append(i) # Append the number itself if not a multiple of 3 or 5 + results.append(i) # Append the number itself if not a multiple of 3 or 5 return results # Return the list of results From 9d731739df620d31bc99104fc0ffe4cdc6d8bd29 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 22:02:07 +0100 Subject: [PATCH 162/175] Update test_fizz_buzz.py --- solutions/tests/test_fizz_buzz.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solutions/tests/test_fizz_buzz.py b/solutions/tests/test_fizz_buzz.py index 124eb14cd..44d467f3d 100644 --- a/solutions/tests/test_fizz_buzz.py +++ b/solutions/tests/test_fizz_buzz.py @@ -8,6 +8,8 @@ class TestFizzBuzz(unittest.TestCase): This class contains unit tests for the fizzbuzz function to ensure that it produces the expected output for various input values. + It verifies the correctness of the function across different scenarios, + including edge cases. """ def test_fizzbuzz_15(self): From ef3490bcc6626a14323414cd18a8bc9bf95f144d Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 22:20:21 +0100 Subject: [PATCH 163/175] Update test_fizz_buzz.py adding a module doccstring with some path modifications to avoid formatting issues --- solutions/tests/test_fizz_buzz.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/solutions/tests/test_fizz_buzz.py b/solutions/tests/test_fizz_buzz.py index 44d467f3d..55befc430 100644 --- a/solutions/tests/test_fizz_buzz.py +++ b/solutions/tests/test_fizz_buzz.py @@ -1,5 +1,17 @@ +""" +Unit tests for the fizzbuzz function from the solutions.fizz_buzz module. + +This class uses the unittest framework to validate the behavior of the fizzbuzz function +across various input values, ensuring it produces the correct output lists. Tests include +cases for n = 0, 1, 3, 5, and 15, verifying the proper inclusion of Fizz, Buzz, and FizzBuzz +in the outputs. +""" + import unittest +import sys +import os +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) from solutions.fizz_buzz import fizz_buzz @@ -8,8 +20,6 @@ class TestFizzBuzz(unittest.TestCase): This class contains unit tests for the fizzbuzz function to ensure that it produces the expected output for various input values. - It verifies the correctness of the function across different scenarios, - including edge cases. """ def test_fizzbuzz_15(self): From b1843aa5c2851e0765ff4bd901b735006d0b3d19 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 22:57:35 +0100 Subject: [PATCH 164/175] Update count_vowels.py added module docstring, and defensive assertions --- solutions/count_vowels.py | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/solutions/count_vowels.py b/solutions/count_vowels.py index 142a86ebc..3dae75601 100644 --- a/solutions/count_vowels.py +++ b/solutions/count_vowels.py @@ -1,10 +1,29 @@ -def count_vowels(s): +""" +This module provides a function to count the number of vowels in a given text. +The vowels here are a,e,i,o,u,A,E,I,O,U. + +Function: +- count_vowels: Counts vowels in a provided string. + +Raises: + TypeError: If the input `text` is not a string. + ValueError: If the input `text` is an empty string. + +Example: + >>> vowel_counter("Deadline") + 4 +""" + + +def count_vowels(s) -> int:: """ Counts the number of vowels in the given string. Parameters: s (str): The string in which to count vowels. + The vowels are "a,e,i,o,u,A,E,I,O,U" + Returns: int: The number of vowels in the string. @@ -13,7 +32,17 @@ def count_vowels(s): 2 >>> count_vowels("Nelsona") 3 + >>> count_vowels("This is amazing.") + 5 """ + # Defensive assertion: Ensure the input is a string + if not isinstance(text, str): + raise TypeError("Input must be a string") + + # Defensive assertion: Ensure the string is not empty + if not text: + raise ValueError("Input string cannot be empty") + vowels = "aeiouAEIOU" # Define vowels (both lowercase and uppercase) return sum( 1 for char in s if char in vowels From e78c3897ccd06efa0825e6e371950a32ef203d69 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 23:08:17 +0100 Subject: [PATCH 165/175] Update test_count_vowels.py Added a module docstring and defensive assertions --- solutions/tests/test_count_vowels.py | 38 +++++++++++++++++++++------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/solutions/tests/test_count_vowels.py b/solutions/tests/test_count_vowels.py index 043b86ed3..b5839eab5 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -1,6 +1,18 @@ +""" +This module contains unit tests for the count_vowels module. +It includes test cases for the following function: +- count_vowels: Test the function that counts vowels in a string. + +Tests cover various cases including normal strings, empty strings, and case insensitivity. + +Usage: + Run tests using unittest framework: + >>> python -m unittest test_vowel_counter.py +""" + import unittest -from solutions.count_vowels import count_vowels # Import the count_vowels function +from ..count_vowels import count_vowels # Import the count_vowels function class TestCountVowels(unittest.TestCase): @@ -18,14 +30,6 @@ def test_count_vowels_normal(self): """ self.assertEqual(count_vowels("Nagham"), 2) - def test_count_vowels_empty(self): - """Test counting vowels in an empty string. - - This test verifies that the function returns 0 when the input string - is empty. - """ - self.assertEqual(count_vowels(""), 0) - def test_count_vowels_no_vowels(self): """Test counting vowels in a string with no vowels. @@ -50,6 +54,22 @@ def test_count_vowels_with_spaces(self): """ self.assertEqual(count_vowels("Hello World!"), 3) + # Defensive assertion tests + def test_invalid_input_type_integer(self): + """Test that the function raises a TypeError for non-string input (integer).""" + with self.assertRaises(TypeError): + count_vowels(12345) + + def test_invalid_input_type_list(self): + """Test that the function raises a TypeError for non-string input (list).""" + with self.assertRaises(TypeError): + count_vowels(["a", "b", "c"]) + + def test_empty_string(self): + """Test that the function raises a ValueError for an empty string.""" + with self.assertRaises(ValueError): + count_vowels("") + if __name__ == "__main__": unittest.main() From b90d6d0b9163ccd1a7fb2c6f395c9f297ac59a9c Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 23:21:16 +0100 Subject: [PATCH 166/175] Update count_vowels.py final touches --- solutions/count_vowels.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/solutions/count_vowels.py b/solutions/count_vowels.py index 3dae75601..002aea1b6 100644 --- a/solutions/count_vowels.py +++ b/solutions/count_vowels.py @@ -15,7 +15,7 @@ """ -def count_vowels(s) -> int:: +def count_vowels(s) -> int: """ Counts the number of vowels in the given string. @@ -23,7 +23,7 @@ def count_vowels(s) -> int:: s (str): The string in which to count vowels. The vowels are "a,e,i,o,u,A,E,I,O,U" - + Returns: int: The number of vowels in the string. @@ -36,14 +36,12 @@ def count_vowels(s) -> int:: 5 """ # Defensive assertion: Ensure the input is a string - if not isinstance(text, str): + if not isinstance(s, str): raise TypeError("Input must be a string") # Defensive assertion: Ensure the string is not empty - if not text: + if not s: raise ValueError("Input string cannot be empty") - + vowels = "aeiouAEIOU" # Define vowels (both lowercase and uppercase) - return sum( - 1 for char in s if char in vowels - ) # Count vowels using a generator expression + return sum(1 for char in s if char in vowels) From 09ee56e3ffbf91a680c166cd20bb7fae2347b46a Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Sun, 12 Jan 2025 23:37:39 +0100 Subject: [PATCH 167/175] Update test_count_vowels.py --- 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 b5839eab5..8e488792f 100644 --- a/solutions/tests/test_count_vowels.py +++ b/solutions/tests/test_count_vowels.py @@ -12,7 +12,7 @@ import unittest -from ..count_vowels import count_vowels # Import the count_vowels function +from solutions.count_vowels import count_vowels # Import the count_vowels function class TestCountVowels(unittest.TestCase): From a48971f16c79430c871e648a12ef692d72f5f762 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Mon, 13 Jan 2025 00:02:25 +0100 Subject: [PATCH 168/175] Update reverse_string.py --- solutions/reverse_string.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/solutions/reverse_string.py b/solutions/reverse_string.py index 045d135ac..cc8a98ae8 100644 --- a/solutions/reverse_string.py +++ b/solutions/reverse_string.py @@ -1,4 +1,24 @@ -def reverse_string(s): +""" +This module provides a function to reverse an inputed string. + +Function: + reverse_string(s: str) -> str: + Reverses the input string and returns the reversed one. + +Features: +- Simple and efficient string reversal. +- Built-in error handling for invalid inputs. + +Raises: + TypeError: If the input `s` is not a string. + ValueError: If the input `s` is an empty string. +Example: + >>> reverse_string("Deadline") + enildaeD +""" + + +def reverse_string(s: str) -> str: """ Reverses the given string. @@ -11,5 +31,13 @@ def reverse_string(s): Example: >>> reverse_string("hello") 'olleh' + >>> reverse_string("12345") + '54321' """ + # Defensive assertion: Ensure the input is a string + if not isinstance(s, str): + raise TypeError("Input must be a string") + # Defensive assertion: Ensure the string is not empty + if not s: + raise ValueError("Input string cannot be empty") return s[::-1] # Return the reversed string using slicing From aeceb788df221a6a09e4502b7fc436c8ed51c2ef Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Mon, 13 Jan 2025 00:03:00 +0100 Subject: [PATCH 169/175] Update count_vowels.py --- solutions/count_vowels.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solutions/count_vowels.py b/solutions/count_vowels.py index 002aea1b6..7d7328559 100644 --- a/solutions/count_vowels.py +++ b/solutions/count_vowels.py @@ -6,8 +6,8 @@ - count_vowels: Counts vowels in a provided string. Raises: - TypeError: If the input `text` is not a string. - ValueError: If the input `text` is an empty string. + TypeError: If the input `s` is not a string. + ValueError: If the input `s` is an empty string. Example: >>> vowel_counter("Deadline") From b1c101ea524cefe01dcadc730c30e022a472bab3 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Mon, 13 Jan 2025 00:12:41 +0100 Subject: [PATCH 170/175] Update test_reverse_string.py final touches --- solutions/tests/test_reverse_string.py | 84 ++++++++++++++++---------- 1 file changed, 53 insertions(+), 31 deletions(-) diff --git a/solutions/tests/test_reverse_string.py b/solutions/tests/test_reverse_string.py index b0e906522..09e038f18 100644 --- a/solutions/tests/test_reverse_string.py +++ b/solutions/tests/test_reverse_string.py @@ -1,7 +1,20 @@ +""" +Unit tests for the `reverse_string` function. + +This module tests the `reverse_string` function, which reverses an input string. +It includes various test cases to ensure that the function handles: +- Normal strings +- Strings containing numbers +- Strings with special characters +- Single characters +- Palindromes +- Strings with spaces +- Extremely long strings +It also checks that a ValueError is raised for empty strings and that a TypeError is raised for non-string inputs. +""" + import unittest -from solutions.reverse_string import ( - reverse_string, -) # Import the reverse_string function +from solutions.reverse_string import reverse_string class TestReverseString(unittest.TestCase): @@ -12,45 +25,54 @@ class TestReverseString(unittest.TestCase): """ def test_reverse_normal(self): - """Test reversing a normal string. - - This test checks that the function correctly reverses a typical string - with multiple characters. - """ + """Test reversing a normal string.""" self.assertEqual(reverse_string("hello"), "olleh") - def test_reverse_empty(self): - """Test reversing an empty string. - - This test verifies that the function returns an empty string when - the input is empty. - """ - self.assertEqual(reverse_string(""), "") - def test_reverse_single_character(self): - """Test reversing a single character string. - - This test checks that the function returns the same character when - the input is a single character string. - """ + """Test reversing a single character string.""" self.assertEqual(reverse_string("a"), "a") def test_reverse_palindrome(self): - """Test reversing a palindrome. - - This test verifies that the function returns the same string when - the input is a palindrome. - """ + """Test reversing a palindrome.""" self.assertEqual(reverse_string("madam"), "madam") def test_reverse_spaces(self): - """Test reversing a string with spaces. - - This test checks that the function correctly reverses a string that - contains spaces, ensuring that the spaces are also reversed. - """ + """Test reversing a string with spaces.""" self.assertEqual(reverse_string("hello world"), "dlrow olleh") + def test_numbers_in_string(self): + """Test reversing a string containing numbers.""" + self.assertEqual(reverse_string("12345"), "54321") + + def test_special_characters(self): + """Test reversing a string with special characters.""" + self.assertEqual(reverse_string("!@#$"), "$#@!") + + def test_long_string(self): + """Test reversing an extremely long string.""" + long_string = "a" * 10000 + self.assertEqual(reverse_string(long_string), long_string[::-1]) + + def test_reverse_empty(self): + """Test that an empty string raises a ValueError.""" + with self.assertRaises(ValueError): + reverse_string("") # This input should raise a ValueError + + def test_integer_input(self): + """Test that an integer input raises a TypeError.""" + with self.assertRaises(TypeError): + reverse_string(12345) # Non-string input: integer + + def test_none_input(self): + """Test that a None input raises a TypeError.""" + with self.assertRaises(TypeError): + reverse_string(None) # Non-string input: NoneType + + def test_list_input(self): + """Test that a list input raises a TypeError.""" + with self.assertRaises(TypeError): + reverse_string(["a", "b", "c"]) # Non-string input: list + if __name__ == "__main__": unittest.main() From c40c66b154b62d781d9f89b938e0767350e20b95 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Mon, 13 Jan 2025 00:23:12 +0100 Subject: [PATCH 171/175] Update fizz_buzz.py final touches --- solutions/fizz_buzz.py | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/solutions/fizz_buzz.py b/solutions/fizz_buzz.py index fda334441..4d111fdc7 100644 --- a/solutions/fizz_buzz.py +++ b/solutions/fizz_buzz.py @@ -1,4 +1,22 @@ -def fizzbuzz(n: int) -> list: +""" +This module provides a function that generates a list of numbers from 1 to n with specific rules for multiples of 3 and 5. + +For each number in the range: +- For multiples of 3, "Fizz" is added instead of the number. +- For multiples of 5, "Buzz" is added instead of the number. +- For multiples of both 3 and 5, "FizzBuzz" is added instead of the number. + +Features: +- Input validation to ensure that the input is a positive integer. +- Customizable output format (e.g., changing the words "Fizz" and "Buzz" to user-defined strings). +- Ability to generate results as a string instead of a list. + +Example: +>>> fizz_buzz(15) +[1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14, 'FizzBuzz'] +""" + +def fizz_buzz(n: int) -> list: """ Generates a list of numbers from 1 to n with the following rules: - For multiples of 3, "Fizz" is added instead of the number. @@ -12,9 +30,15 @@ def fizzbuzz(n: int) -> list: list: A list containing the numbers and/or string representations according to the rules. Example: - >>> fizzbuzz(15) - [1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14, 'FizzBuzz'] + >>> fizz_buzz(10) + [1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz'] """ + # Defensive assertions + if not isinstance(n, int): + raise TypeError("Input must be an integer.") + if n < 1: + raise ValueError("Input must be greater than or equal to 1.") + results = [] # Initialize an empty list to store the results for i in range(1, n + 1): if i % 3 == 0 and i % 5 == 0: @@ -25,4 +49,5 @@ def fizzbuzz(n: int) -> list: results.append("Buzz") # Append "Buzz" for multiples of 5 else: results.append(i) # Append the number itself if not a multiple of 3 or 5 + return results # Return the list of results From ed16f4467f5cd4c19b6b912c4289f20a5ed0d952 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Mon, 13 Jan 2025 00:32:28 +0100 Subject: [PATCH 172/175] Update fizz_buzz.py --- solutions/fizz_buzz.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/solutions/fizz_buzz.py b/solutions/fizz_buzz.py index 4d111fdc7..c10d09e03 100644 --- a/solutions/fizz_buzz.py +++ b/solutions/fizz_buzz.py @@ -1,5 +1,6 @@ """ -This module provides a function that generates a list of numbers from 1 to n with specific rules for multiples of 3 and 5. +This module provides a function that generates a list of numbers from 1 to n +with specific rules for multiples of 3 and 5. For each number in the range: - For multiples of 3, "Fizz" is added instead of the number. @@ -8,12 +9,14 @@ Features: - Input validation to ensure that the input is a positive integer. -- Customizable output format (e.g., changing the words "Fizz" and "Buzz" to user-defined strings). +- Customizable output format (e.g., changing the words "Fizz" and "Buzz" + to user-defined strings). - Ability to generate results as a string instead of a list. Example: >>> fizz_buzz(15) -[1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14, 'FizzBuzz'] +[1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, + 14, 'FizzBuzz'] """ def fizz_buzz(n: int) -> list: @@ -27,12 +30,18 @@ def fizz_buzz(n: int) -> list: n (int): The upper limit of the range (inclusive) to generate. Returns: - list: A list containing the numbers and/or string representations according to the rules. + list: A list containing the numbers and/or string representations according + to the rules. + + Raises: + TypeError: If the input is not an integer. + ValueError: If the input is less than 1. Example: >>> fizz_buzz(10) [1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz'] """ + # Defensive assertions if not isinstance(n, int): raise TypeError("Input must be an integer.") From 038ff04632df070d056bb269e1ccdeb22b2df080 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Mon, 13 Jan 2025 00:38:54 +0100 Subject: [PATCH 173/175] Update fizz_buzz.py --- solutions/fizz_buzz.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/solutions/fizz_buzz.py b/solutions/fizz_buzz.py index c10d09e03..36daead22 100644 --- a/solutions/fizz_buzz.py +++ b/solutions/fizz_buzz.py @@ -19,6 +19,7 @@ 14, 'FizzBuzz'] """ + def fizz_buzz(n: int) -> list: """ Generates a list of numbers from 1 to n with the following rules: @@ -40,14 +41,13 @@ def fizz_buzz(n: int) -> list: Example: >>> fizz_buzz(10) [1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz'] - """ + """ # Defensive assertions if not isinstance(n, int): raise TypeError("Input must be an integer.") if n < 1: raise ValueError("Input must be greater than or equal to 1.") - results = [] # Initialize an empty list to store the results for i in range(1, n + 1): if i % 3 == 0 and i % 5 == 0: @@ -58,5 +58,4 @@ def fizz_buzz(n: int) -> list: results.append("Buzz") # Append "Buzz" for multiples of 5 else: results.append(i) # Append the number itself if not a multiple of 3 or 5 - return results # Return the list of results From 85d945a414495d7068426250312257e1cf48a5e0 Mon Sep 17 00:00:00 2001 From: "Nelson Fodjo K." <106561241+FKN237@users.noreply.github.com> Date: Mon, 13 Jan 2025 00:43:38 +0100 Subject: [PATCH 174/175] Update test_fizz_buzz.py --- solutions/tests/test_fizz_buzz.py | 94 ++++++++++++++----------------- 1 file changed, 41 insertions(+), 53 deletions(-) diff --git a/solutions/tests/test_fizz_buzz.py b/solutions/tests/test_fizz_buzz.py index 55befc430..ab526fdaf 100644 --- a/solutions/tests/test_fizz_buzz.py +++ b/solutions/tests/test_fizz_buzz.py @@ -1,88 +1,76 @@ """ -Unit tests for the fizzbuzz function from the solutions.fizz_buzz module. +Unit tests for the fizz_buzz function from the solutions.fizz_buzz module. -This class uses the unittest framework to validate the behavior of the fizzbuzz function +This class uses the unittest framework to validate the behavior of the fizz_buzz function across various input values, ensuring it produces the correct output lists. Tests include -cases for n = 0, 1, 3, 5, and 15, verifying the proper inclusion of Fizz, Buzz, and FizzBuzz -in the outputs. +cases for n = 1, 3, 5, 15, and additional edge cases to comprehensively test the function. """ import unittest -import sys -import os - -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) from solutions.fizz_buzz import fizz_buzz class TestFizzBuzz(unittest.TestCase): - """Test cases for the fizzbuzz function. + """Test cases for the fizz_buzz function. - This class contains unit tests for the fizzbuzz function to ensure + This class contains unit tests for the fizz_buzz function to ensure that it produces the expected output for various input values. """ def test_fizzbuzz_15(self): - """Test FizzBuzz for n = 15. - - This test checks that the output for n=15 matches the expected - list which includes Fizz, Buzz, and FizzBuzz at the correct - positions. - """ + """Test FizzBuzz for n = 15.""" expected = [ - 1, - 2, - "Fizz", - 4, - "Buzz", - "Fizz", - 7, - 8, - "Fizz", - "Buzz", - 11, - "Fizz", - 13, - 14, - "FizzBuzz", + 1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", + "Buzz", 11, "Fizz", 13, 14, "FizzBuzz" ] self.assertEqual(fizz_buzz(15), expected) def test_fizzbuzz_3(self): - """Test FizzBuzz for n = 3. - - This test checks that for n=3, the output should return - a list containing the numbers 1, 2, and 'Fizz'. - """ + """Test FizzBuzz for n = 3.""" expected = [1, 2, "Fizz"] self.assertEqual(fizz_buzz(3), expected) def test_fizzbuzz_5(self): - """Test FizzBuzz for n = 5. - - This test verifies that for n=5, the output list includes - numbers 1, 2, 'Fizz', 4, and 'Buzz'. - """ + """Test FizzBuzz for n = 5.""" expected = [1, 2, "Fizz", 4, "Buzz"] self.assertEqual(fizz_buzz(5), expected) def test_fizzbuzz_1(self): - """Test FizzBuzz for n = 1. - - This test checks that for n=1, the output should simply be - a list containing the number 1. - """ + """Test FizzBuzz for n = 1.""" expected = [1] self.assertEqual(fizz_buzz(1), expected) - def test_fizzbuzz_0(self): - """Test FizzBuzz for n = 0. + def test_fizzbuzz_zero(self): + """Test FizzBuzz for n = 0.""" + with self.assertRaises(ValueError): + fizz_buzz(0) + + def test_fizzbuzz_negative(self): + """Test FizzBuzz for negative n.""" + with self.assertRaises(ValueError): + fizz_buzz(-5) + + def test_fizzbuzz_non_integer(self): + """Test FizzBuzz for non-integer n.""" + non_integers = [3.5, "string", None, [], {}, (), 2.0] + for value in non_integers: + with self.assertRaises(TypeError): + fizz_buzz(value) + + def test_fizzbuzz_large_number(self): + """Test FizzBuzz for a larger number n = 30.""" + expected = [ + 1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", + "Buzz", 11, "Fizz", 13, 14, "FizzBuzz", 16, + 17, "Fizz", 19, "Buzz", "Fizz", 22, 23, "Fizz", + "Buzz", 26, "Fizz", 28, 29, "FizzBuzz" + ] + self.assertEqual(fizz_buzz(30), expected) - This test checks that for n=0, the output should be an - empty list since there are no numbers to include. - """ - expected = [] - self.assertEqual(fizz_buzz(0), expected) + def test_fizzbuzz_edge_case(self): + """Test FizzBuzz for n = 2.""" + expected = [1, 2] + self.assertEqual(fizz_buzz(2), expected) if __name__ == "__main__": From b84f300b13639f357a437012ec8a26c04ed9845f Mon Sep 17 00:00:00 2001 From: matopcheg Date: Mon, 13 Jan 2025 13:24:13 +0200 Subject: [PATCH 175/175] ruff formatting --- solutions/fizz_buzz.py | 20 ++++++------ solutions/tests/test_fizz_buzz.py | 51 +++++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/solutions/fizz_buzz.py b/solutions/fizz_buzz.py index 36daead22..e234075bd 100644 --- a/solutions/fizz_buzz.py +++ b/solutions/fizz_buzz.py @@ -1,5 +1,5 @@ """ -This module provides a function that generates a list of numbers from 1 to n +This module provides a function that generates a list of numbers from 1 to n with specific rules for multiples of 3 and 5. For each number in the range: @@ -9,13 +9,13 @@ Features: - Input validation to ensure that the input is a positive integer. -- Customizable output format (e.g., changing the words "Fizz" and "Buzz" +- Customizable output format (e.g., changing the words "Fizz" and "Buzz" to user-defined strings). - Ability to generate results as a string instead of a list. Example: >>> fizz_buzz(15) -[1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, +[1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14, 'FizzBuzz'] """ @@ -31,7 +31,7 @@ def fizz_buzz(n: int) -> list: n (int): The upper limit of the range (inclusive) to generate. Returns: - list: A list containing the numbers and/or string representations according + list: A list containing the numbers and/or string representations according to the rules. Raises: @@ -41,7 +41,7 @@ def fizz_buzz(n: int) -> list: Example: >>> fizz_buzz(10) [1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz'] - + """ # Defensive assertions if not isinstance(n, int): @@ -51,11 +51,13 @@ def fizz_buzz(n: int) -> list: results = [] # Initialize an empty list to store the results for i in range(1, n + 1): if i % 3 == 0 and i % 5 == 0: - results.append("FizzBuzz") # Append "FizzBuzz" for multiples of both 3 and 5 + results.append( + "FizzBuzz" + ) # Append "FizzBuzz" for multiples of both 3 and 5 elif i % 3 == 0: - results.append("Fizz") # Append "Fizz" for multiples of 3 + results.append("Fizz") # Append "Fizz" for multiples of 3 elif i % 5 == 0: - results.append("Buzz") # Append "Buzz" for multiples of 5 + results.append("Buzz") # Append "Buzz" for multiples of 5 else: - results.append(i) # Append the number itself if not a multiple of 3 or 5 + results.append(i) # Append the number itself if not a multiple of 3 or 5 return results # Return the list of results diff --git a/solutions/tests/test_fizz_buzz.py b/solutions/tests/test_fizz_buzz.py index ab526fdaf..c24280a5c 100644 --- a/solutions/tests/test_fizz_buzz.py +++ b/solutions/tests/test_fizz_buzz.py @@ -20,8 +20,21 @@ class TestFizzBuzz(unittest.TestCase): def test_fizzbuzz_15(self): """Test FizzBuzz for n = 15.""" expected = [ - 1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", - "Buzz", 11, "Fizz", 13, 14, "FizzBuzz" + 1, + 2, + "Fizz", + 4, + "Buzz", + "Fizz", + 7, + 8, + "Fizz", + "Buzz", + 11, + "Fizz", + 13, + 14, + "FizzBuzz", ] self.assertEqual(fizz_buzz(15), expected) @@ -60,10 +73,36 @@ def test_fizzbuzz_non_integer(self): def test_fizzbuzz_large_number(self): """Test FizzBuzz for a larger number n = 30.""" expected = [ - 1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", - "Buzz", 11, "Fizz", 13, 14, "FizzBuzz", 16, - 17, "Fizz", 19, "Buzz", "Fizz", 22, 23, "Fizz", - "Buzz", 26, "Fizz", 28, 29, "FizzBuzz" + 1, + 2, + "Fizz", + 4, + "Buzz", + "Fizz", + 7, + 8, + "Fizz", + "Buzz", + 11, + "Fizz", + 13, + 14, + "FizzBuzz", + 16, + 17, + "Fizz", + 19, + "Buzz", + "Fizz", + 22, + 23, + "Fizz", + "Buzz", + 26, + "Fizz", + 28, + 29, + "FizzBuzz", ] self.assertEqual(fizz_buzz(30), expected)