From dbc274543286cd2b6f892096ae59d401e369fb6d Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Tue, 24 Dec 2024 22:01:18 +0400 Subject: [PATCH 001/151] Adding the group norms --- collaboration/guide/1_group_norms.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/collaboration/guide/1_group_norms.md b/collaboration/guide/1_group_norms.md index c7bd0e34e..9063c00c4 100644 --- a/collaboration/guide/1_group_norms.md +++ b/collaboration/guide/1_group_norms.md @@ -1,4 +1,16 @@ # Group Norms -Complete the _Group Norms_ assignment from the Code Review workshop and write -your norms summary and list in the [Collaboration README](../README.md) +## The summary + +Our group is committed to fostering trust, collaboration, and open communication by valuing diverse perspectives, respecting time, and embracing accountability. We aim to create a positive and inclusive environment where everyone feels supported, empowered to contribute, and aligned toward shared goals. We strive to build strong relationships and ensure collective growth where mistakes are treated as learning opportunities, and trust is rebuilt through consistent actions and open dialogue. Together, we are dedicated to making this a meaningful and enjoyable experience for all. + +## The Refine + +1. Build and Sustain Trust: Commit to creating a reliable and supportive environment where trust underpins all interactions. +2. Foster Open Communication: Ensure a culture where all voices are valued, and ideas, concerns, and feedback are openly shared. +3. Respect Time and Focus: Honor each other’s time by striving for purposeful and efficient communication and collaboration. +4. Promote Team Growth: Support collective learning, personal development, and the achievement of shared goals. +5. Encourage Inclusivity: Create a space where diverse perspectives are welcomed and everyone feels empowered to contribute. +6. Ensure Clarity and Alignment: Maintain shared understanding and alignment on goals, expectations, and progress. +7. Cultivate a Positive Team Culture: Build a collaborative and motivating environment that values both achievements and relationships. +8. Embrace Growth from Challenges: Approach mistakes and challenges as opportunities for learning and improvement. From 27e286a050896e172ddbb06f38664ee538cde584 Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Tue, 24 Dec 2024 22:06:12 +0400 Subject: [PATCH 002/151] fixing the linting issues --- collaboration/guide/1_group_norms.md | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/collaboration/guide/1_group_norms.md b/collaboration/guide/1_group_norms.md index 9063c00c4..4ee3425fc 100644 --- a/collaboration/guide/1_group_norms.md +++ b/collaboration/guide/1_group_norms.md @@ -6,11 +6,19 @@ Our group is committed to fostering trust, collaboration, and open communication ## The Refine -1. Build and Sustain Trust: Commit to creating a reliable and supportive environment where trust underpins all interactions. -2. Foster Open Communication: Ensure a culture where all voices are valued, and ideas, concerns, and feedback are openly shared. -3. Respect Time and Focus: Honor each other’s time by striving for purposeful and efficient communication and collaboration. -4. Promote Team Growth: Support collective learning, personal development, and the achievement of shared goals. -5. Encourage Inclusivity: Create a space where diverse perspectives are welcomed and everyone feels empowered to contribute. -6. Ensure Clarity and Alignment: Maintain shared understanding and alignment on goals, expectations, and progress. -7. Cultivate a Positive Team Culture: Build a collaborative and motivating environment that values both achievements and relationships. -8. Embrace Growth from Challenges: Approach mistakes and challenges as opportunities for learning and improvement. +1. Build and Sustain Trust: Commit to creating a reliable and supportive environment where trust +underpins all interactions. +2. Foster Open Communication: Ensure a culture where all voices are valued, and ideas, concerns, +and feedback are openly shared. +3. Respect Time and Focus: Honor each other’s time by striving for purposeful and efficient +communication and collaboration. +4. Promote Team Growth: Support collective learning, personal development, and the achievement +of shared goals. +5. Encourage Inclusivity: Create a space where diverse perspectives are welcomed and everyone +feels empowered to contribute. +6. Ensure Clarity and Alignment: Maintain shared understanding and alignment on goals, expectations, +and progress. +7. Cultivate a Positive Team Culture: Build a collaborative and motivating environment that values +both achievements and relationships. +8. Embrace Growth from Challenges: Approach mistakes and challenges as opportunities for learning +and improvement. From 32db1c420e19e5137adcb9eb83730d18b075dd01 Mon Sep 17 00:00:00 2001 From: mxz Date: Tue, 24 Dec 2024 20:48:44 +0200 Subject: [PATCH 003/151] fix the collaboration Readme file --- .vscode/settings.json | 5 +++- collaboration/README.md | 35 ++++++++++++++++++++++++++++ collaboration/guide/1_group_norms.md | 24 ++----------------- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 5a90e202f..30c6ea2e1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -113,5 +113,8 @@ }, // Enable/disable update table of contents on save - "markdown.extension.toc.updateOnSave": false + "markdown.extension.toc.updateOnSave": false, + "cSpell.words": [ + "Inclusivity" + ] } diff --git a/collaboration/README.md b/collaboration/README.md index 20889b951..64a2ebba7 100644 --- a/collaboration/README.md +++ b/collaboration/README.md @@ -1,5 +1,40 @@ # Collaboration +## The summary + +Our group is committed to fostering trust, collaboration, and open communication + by valuing diverse perspectives, respecting + time, and embracing accountability. We aim to create a positive and inclusive + environment where everyone feels supported, empowered to contribute, and aligned + toward shared goals. We strive to build strong relationships and ensure + collective growth where mistakes are treated as learning opportunities, and + trust is rebuilt through consistent actions and open dialogue. Together, we + are dedicated to making this a meaningful and enjoyable experience for all. +## The list + +1. Build and Sustain Trust: Commit to creating a reliable and supportive +environment where trust +underpins all interactions. +2. Foster Open Communication: Ensure a culture where all voices are valued, and + ideas, concerns, +and feedback are openly shared. +3. Respect Time and Focus: Honor each other’s time by striving for purposeful + and efficient +communication and collaboration. +4. Promote Team Growth: Support collective learning, personal development, and +the achievement +of shared goals. +5. Encourage Inclusivity: Create a space where diverse perspectives are +welcomed and everyone +feels empowered to contribute. +6. Ensure Clarity and Alignment: Maintain shared understanding and alignment on + goals, expectations, +and progress. +7. Cultivate a Positive Team Culture: Build a collaborative and motivating +environment that values +both achievements and relationships. +8. Embrace Growth from Challenges: Approach mistakes and challenges as +opportunities for learning and improvement. diff --git a/collaboration/guide/1_group_norms.md b/collaboration/guide/1_group_norms.md index 4ee3425fc..c7bd0e34e 100644 --- a/collaboration/guide/1_group_norms.md +++ b/collaboration/guide/1_group_norms.md @@ -1,24 +1,4 @@ # Group Norms -## The summary - -Our group is committed to fostering trust, collaboration, and open communication by valuing diverse perspectives, respecting time, and embracing accountability. We aim to create a positive and inclusive environment where everyone feels supported, empowered to contribute, and aligned toward shared goals. We strive to build strong relationships and ensure collective growth where mistakes are treated as learning opportunities, and trust is rebuilt through consistent actions and open dialogue. Together, we are dedicated to making this a meaningful and enjoyable experience for all. - -## The Refine - -1. Build and Sustain Trust: Commit to creating a reliable and supportive environment where trust -underpins all interactions. -2. Foster Open Communication: Ensure a culture where all voices are valued, and ideas, concerns, -and feedback are openly shared. -3. Respect Time and Focus: Honor each other’s time by striving for purposeful and efficient -communication and collaboration. -4. Promote Team Growth: Support collective learning, personal development, and the achievement -of shared goals. -5. Encourage Inclusivity: Create a space where diverse perspectives are welcomed and everyone -feels empowered to contribute. -6. Ensure Clarity and Alignment: Maintain shared understanding and alignment on goals, expectations, -and progress. -7. Cultivate a Positive Team Culture: Build a collaborative and motivating environment that values -both achievements and relationships. -8. Embrace Growth from Challenges: Approach mistakes and challenges as opportunities for learning -and improvement. +Complete the _Group Norms_ assignment from the Code Review workshop and write +your norms summary and list in the [Collaboration README](../README.md) From 3da9d0a24ca28a1344fc09cee05f70c0fd362552 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Mon, 30 Dec 2024 06:55:44 +0400 Subject: [PATCH 004/151] Adding the learning goals --- collaboration/learning_goals.md | 43 ++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/collaboration/learning_goals.md b/collaboration/learning_goals.md index 11c583d2b..511ec7f87 100644 --- a/collaboration/learning_goals.md +++ b/collaboration/learning_goals.md @@ -1,5 +1,42 @@ -# Learning Goals +# Learning Goals -## Collective +Our team comprises ten members with diverse backgrounds, including those new to +coding and others with significant experience. This variety presents an excellent +opportunity for mutual learning and growth. Below are the learning goals we have +collectively identified for these exercises: -## Individual +## Objectives for Team Members New to Coding + +- **Build foundational knowledge**: Understand the basics of data structures (DSs) + and algorithms. +- **Learn programming best practices**: Focus on writing clean, readable, and well- + documented code. +- **Practice problem-solving**: Develop confidence in tackling coding problems +step by step. +- **Gain exposure to code review**: Learn how to give and receive constructive feedback + to improve solutions. + +## Objectives for Experienced Team Members + +- **Strengthen advanced skills**: Dive deeper into complex DSs and algorithms to +enhance problem-solving capabilities. +- **Experiment with new approaches**: Explore and apply new programming language +features to refine solutions. +- **Focus on optimization**: Work on producing efficient and scalable code. +- **Mentor and collaborate**: Guide less experienced team members to create an +inclusive and supportive learning environment. + +## Shared Team Objectives + +- **Learn through collaboration**: Share knowledge and perspectives to maximize +learning outcomes for everyone. +- **Improve development speed**: Practice writing solutions faster while maintaining +quality. +- **Foster a culture of feedback**: Embrace multiple cycles of review to improve +individual and team skills. +- **Document solutions effectively**: Ensure every solution is well-commented and +easy to understand for future reference. + +These goals reflect our commitment to leveraging our diverse skills and experiences +to grow together as a team. We’ll revisit and refine these objectives as needed +to ensure alignment with our progress and expectations. From e4f3e8054d6fb2370213feab61644361095e5245 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Mon, 30 Dec 2024 07:37:12 +0400 Subject: [PATCH 005/151] Adding the Constraints --- collaboration/constraints.md | 95 ++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 32 deletions(-) diff --git a/collaboration/constraints.md b/collaboration/constraints.md index 24079505c..f1a506e49 100644 --- a/collaboration/constraints.md +++ b/collaboration/constraints.md @@ -1,34 +1,65 @@ -# Constraints - -Some boundaries around our project. - -## External - - - -## Internal: Involuntary - - - -## Internal: Voluntary - - +# Constraints + +This document outlines the constraints for our collaborative project, helping us +focus on realistic goals and effective teamwork. Each member will solve two +problems by writing Python code, documenting it, and testing it. Additionally, +every member will review two problems written by others. The repository is a +group effort, reflecting everyone's contributions. + +## External + + + +- **Project Deadlines**: The project must be completed by **January 10**, with +internal deadlines for milestones ensuring consistent progress. +- **Technologies**: The project requires Python, GitHub, VSCode, and linting +tools for coding, collaboration, and quality assurance. +- **Time Constraints**: Members have limited availability due to full-time jobs +and university schedules. + +## Internal: Involuntary + + + +- **Skill Levels**: The team includes members with a mix of beginner and experienced +skill levels, with most members new to coding. +- **Time Availability**: Each member can dedicate only a few hours per week due +to other commitments. + +## Internal: Voluntary + + + +- **Problem Solving**: Each member will solve two problems by writing Python +code, ensuring the solutions are well-documented and thoroughly tested. +- **Code Reviews**: Every member will review two problems written by others, +providing constructive feedback to enhance quality and learning. +- **Coding Conventions**: The team has agreed on consistent coding styles and a +code review checklist to maintain clarity and quality in the repository. +- **Repository Collaboration**: All members will contribute to a shared GitHub +repository, promoting teamwork and collective ownership of the project. +- **Scope Management**: Realistic project goals have been set to balance +learning opportunities with completing a high-quality final product. +- **Tools Commitment**: The team will use GitHub for version control, VSCode for +development, and Python linting tools to ensure clean, efficient code. +- **Feedback Cycles**: A process for iterative feedback and reviews has been +established to improve both individual skills and project outcomes. From 5e312da77d99f1f890df3f2ccdb3800b7dc242b3 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Mon, 30 Dec 2024 08:00:55 +0400 Subject: [PATCH 006/151] Adding the empty python file --- solutions/tests/test_fuel_gauge.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/tests/test_fuel_gauge.py diff --git a/solutions/tests/test_fuel_gauge.py b/solutions/tests/test_fuel_gauge.py new file mode 100644 index 000000000..e69de29bb From f09f7dcaa59f6c7f76402d88a8103ed0e7bca128 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Mon, 30 Dec 2024 08:24:06 +0400 Subject: [PATCH 007/151] Adding the Python file --- solutions/fuel_gauge.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/fuel_gauge.py diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py new file mode 100644 index 000000000..e69de29bb From 43918ea68d6fba3f6e38a0030c68fb04f0f4a296 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Mon, 30 Dec 2024 08:38:04 +0400 Subject: [PATCH 008/151] adding empty python files --- solutions/armstrong_number.py | 0 solutions/tests/test_armstrong_number.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/armstrong_number.py create mode 100644 solutions/tests/test_armstrong_number.py diff --git a/solutions/armstrong_number.py b/solutions/armstrong_number.py new file mode 100644 index 000000000..e69de29bb diff --git a/solutions/tests/test_armstrong_number.py b/solutions/tests/test_armstrong_number.py new file mode 100644 index 000000000..e69de29bb From 1b290f0bfff14ad61a1efd8426d040bfff7fe0ef Mon Sep 17 00:00:00 2001 From: Mayar-Agab Date: Mon, 30 Dec 2024 09:54:23 +0200 Subject: [PATCH 009/151] created the file for the arithmetic sequence test --- solutions/tests/test_arithmetic_sequence.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/tests/test_arithmetic_sequence.py diff --git a/solutions/tests/test_arithmetic_sequence.py b/solutions/tests/test_arithmetic_sequence.py new file mode 100644 index 000000000..e69de29bb From 75747e4120184ff9ef2aacaa538843cfb2efee9f Mon Sep 17 00:00:00 2001 From: Mayar-Agab Date: Mon, 30 Dec 2024 11:17:17 +0200 Subject: [PATCH 010/151] I added the test file test_even_number_count.py --- solutions/tests/test_even_number_count.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/tests/test_even_number_count.py diff --git a/solutions/tests/test_even_number_count.py b/solutions/tests/test_even_number_count.py new file mode 100644 index 000000000..e69de29bb From dcab675ff057752ea393682a6bf7b717024ec662 Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Mon, 30 Dec 2024 15:56:40 +0400 Subject: [PATCH 011/151] Added the anagrams problem with its test file --- solutions/anagrams.py | 34 ++++++++++++++++++++++++++++++++ solutions/tests/test_anagrams.py | 26 ++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 solutions/anagrams.py create mode 100644 solutions/tests/test_anagrams.py diff --git a/solutions/anagrams.py b/solutions/anagrams.py new file mode 100644 index 000000000..0cd75a3f3 --- /dev/null +++ b/solutions/anagrams.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Write a function that takes two strings as input and checks if they +are anagrams of each other. Anagrams are words or phrases made by +rearranging the letters of another, using all original letters +exactly once + +True if the two strings are anagrams, False otherwise + +""" + + +def is_anagrams(word1: str, word2: str) -> bool: + """ + Returns true or false if the two strings given are anagrams + of each other. + + Parameters: + word1: The first string + words2: The second string + + Returns -> bool: Either true or false of either the strings + are anagrams of each other or not. + + Raises: + AssertionError: if the parameters are not strings + + Examples: + >>> is_anagrams("anagram", "nagaram") + True + >>> is_anagrams("rat", "car") + False + """ diff --git a/solutions/tests/test_anagrams.py b/solutions/tests/test_anagrams.py new file mode 100644 index 000000000..71346393d --- /dev/null +++ b/solutions/tests/test_anagrams.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Test module for find_longest function. +Contains correct tests to help identify bugs in the implementation. + +Test categories: + - Standard cases: typical string lists + - Edge cases: empty strings, equal lengths + - Defensive tests: invalid inputs + +Created on 2024-12-06 +Author: Claude AI +""" + + +import unittest + +from ..anagrams import is_anagrams + + +class TestIsAnagram(unittest.TestCase): + """Test suite for the is_anagram function""" + # Standard test cases + def test_base(self): + pass From 4bddf02ef8f3e59546843c95a216a67e348dbb74 Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Mon, 30 Dec 2024 16:33:21 +0400 Subject: [PATCH 012/151] adding robot.py file as a problem with its corresponding test --- solutions/robot.py | 35 +++++++++++++++++++++++++++++++++++ solutions/tests/test_robot.py | 20 ++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 solutions/robot.py create mode 100644 solutions/tests/test_robot.py diff --git a/solutions/robot.py b/solutions/robot.py new file mode 100644 index 000000000..b6c033e2e --- /dev/null +++ b/solutions/robot.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +There is a robot on an m x n grid. The robot is initially located +at the top-left corner (i.e., grid[0][0]). The robot tries to move +to the bottom-right corner (i.e., grid[m - 1][n - 1]). The robot +can only move either down or right at any point in time. + +Given the two integers m and n, return the number of possible +unique paths that the robot can take to reach the bottom-right +corner. + +Constraints: The test cases are generated so that the answer will +be less than or equal to 2 * 109. +""" + +def robot(m_: int, n_: int) -> int: + """ + Returns the number of possible unique routes to reach the + most bottom-right corner + + Parameters: + m: The number of rows in the grid. + n: The number of columns in the grid. + + Returns -> The number of unique paths from the top-left corner + to the bottom-right corner. + + Raises: + AssertionError: if m and n are not integers or less than 1 + + Examples: + >>> robot(3, 7) + 28 + """ diff --git a/solutions/tests/test_robot.py b/solutions/tests/test_robot.py new file mode 100644 index 000000000..e1141b2eb --- /dev/null +++ b/solutions/tests/test_robot.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Test module for robot function. + +Test categories: + - Standard cases + - Edge cases + - Defensive tests + +""" + +import unittest + + +class TestRobot(unittest.TestCase): + """Test the robot function""" + + def test_base(self): + """A basic test""" From 509a789ee8375af80277bae955bb2ebb18be5a4d Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Mon, 30 Dec 2024 18:50:19 +0400 Subject: [PATCH 013/151] Quadratic Sequence File --- .vscode/settings.json | 4 ++-- solutions/quadratic_sequence.py | 14 ++++++++++++++ solutions/tests/test_quadratic_sequence.py | 4 ++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 solutions/quadratic_sequence.py create mode 100644 solutions/tests/test_quadratic_sequence.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/quadratic_sequence.py b/solutions/quadratic_sequence.py new file mode 100644 index 000000000..c3ccf46b5 --- /dev/null +++ b/solutions/quadratic_sequence.py @@ -0,0 +1,14 @@ +def quadratic_sequence(a, b, c, n): + """ + The function creates quadratic sequence, based on formula: A(n): an^2 + bn + c + + Parameters: + a (int): Coefficient of n^2 + b (int): Coefficient of n + c (int): Constant term + n (int): Number of terms to generate + + Returns: + List: List containing the quadratic sequence + + """ diff --git a/solutions/tests/test_quadratic_sequence.py b/solutions/tests/test_quadratic_sequence.py new file mode 100644 index 000000000..4bcf37a95 --- /dev/null +++ b/solutions/tests/test_quadratic_sequence.py @@ -0,0 +1,4 @@ +import unittest +from ..quadratic_sequence import quadratic_sequence + +class TestAsciiCode(unittest.TestCase): From b7c55a7c852cf177a980d4281e13677d639b416f Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Mon, 30 Dec 2024 19:00:57 +0400 Subject: [PATCH 014/151] Create harmonic_sequence file --- solutions/harmonic_sequence.py | 13 +++++++++++++ solutions/tests/test_harmonic_sequence.py | 4 ++++ 2 files changed, 17 insertions(+) create mode 100644 solutions/harmonic_sequence.py create mode 100644 solutions/tests/test_harmonic_sequence.py diff --git a/solutions/harmonic_sequence.py b/solutions/harmonic_sequence.py new file mode 100644 index 000000000..9e66dcb91 --- /dev/null +++ b/solutions/harmonic_sequence.py @@ -0,0 +1,13 @@ +def harmonic_sequence(a, d, n): + """ + The function creates harmonic sequence, based on formula: A(n): 1/ (a +(n-1) *d) + + Parameters: + a (int): First term + d (int): Common difference + n (int): Number of terms to generate + + Returns: + List: List containing the harmonic sequence + + """ diff --git a/solutions/tests/test_harmonic_sequence.py b/solutions/tests/test_harmonic_sequence.py new file mode 100644 index 000000000..2284aa3e9 --- /dev/null +++ b/solutions/tests/test_harmonic_sequence.py @@ -0,0 +1,4 @@ +import unittest +from ..harmonic_sequence import harmonic_sequence + +class TestAsciiCode(unittest.TestCase): From 095a353a68cb21c84836d652d07d53065dd28103 Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Mon, 30 Dec 2024 19:44:25 +0400 Subject: [PATCH 015/151] Harmonic Sequence code with test --- solutions/harmonic_sequence.py | 25 +++++++++++++++++++++ solutions/tests/test_harmonic_sequence.py | 27 +++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/solutions/harmonic_sequence.py b/solutions/harmonic_sequence.py index 9e66dcb91..0b4f77d94 100644 --- a/solutions/harmonic_sequence.py +++ b/solutions/harmonic_sequence.py @@ -10,4 +10,29 @@ def harmonic_sequence(a, d, n): Returns: List: List containing the harmonic sequence + Examples: + >>> harmonic_sequence(1, 1, 1) + [1.0] + >>> harmonic_sequence(1, 1, 0) + [] + >>> harmonic_sequence(0, 0, 5) + [0.0, 0.0, 0.0, 0.0, 0.0] + >>> harmonic_sequence(1, 1, -1) + [] + >>> harmonic_sequence(1, 1, 5) + [1.0, 0.5, 0.3333333333333333, 0.25, 0.2] + >>> harmonic_sequence(2, 2, 3) + [0.5, 0.3333333333333333, 0.25] + >>> harmonic_sequence(1, 5, 10) + [1.0, 0.2, 0.05, 0.02, 0.01, 0.004, 0.0016, 0.00064, 0.000256, 0.0001024] + """ + sequence = [] + if n <= 0: + return sequence + if a == 0 and d == 0: + return [0] * n + for i in range(1, n + 1): + term = 1 / (a + (i - 1) * d) + sequence.append(term) + return sequence diff --git a/solutions/tests/test_harmonic_sequence.py b/solutions/tests/test_harmonic_sequence.py index 2284aa3e9..c8f3f41ac 100644 --- a/solutions/tests/test_harmonic_sequence.py +++ b/solutions/tests/test_harmonic_sequence.py @@ -1,4 +1,31 @@ import unittest + from ..harmonic_sequence import harmonic_sequence + class TestAsciiCode(unittest.TestCase): + def test_min_input1(self): + """Test case when all inputs equal to 1""" + self.assertEqual(harmonic_sequence(1, 1, 1), [1.0]) + + def test_n_equal_0(self): + """Test case when n is equal to 0""" + self.assertEqual(harmonic_sequence(1, 1, 0), []) + + def test_a_and_d_equal_0(self): + """Test case when a and d are equal to 0""" + self.assertEqual(harmonic_sequence(0, 0, 5), [0, 0, 0, 0, 0]) + + def test_n_negative(self): + """Test case when n is negative""" + self.assertEqual(harmonic_sequence(1, 1, -1), []) + + def test_a_and_d_equal_1(self): + """Test a and d are equal 1""" + self.assertEqual( + harmonic_sequence(1, 1, 5), [1.0, 0.5, 0.3333333333333333, 0.25, 0.2] + ) + + def test_all_inputs_greater_than_1(self): + """Test when all inputs are integer and greater than 1""" + self.assertEqual(harmonic_sequence(2, 2, 3), [0.5, 0.25, 0.16666666666666666]) From d45fbfa0d5e9906804d09f45b88f670eb4954371 Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Mon, 30 Dec 2024 20:04:11 +0400 Subject: [PATCH 016/151] Add more tests and assert error --- solutions/harmonic_sequence.py | 6 +++ solutions/tests/test_harmonic_sequence.py | 49 +++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/solutions/harmonic_sequence.py b/solutions/harmonic_sequence.py index 0b4f77d94..1ec41d407 100644 --- a/solutions/harmonic_sequence.py +++ b/solutions/harmonic_sequence.py @@ -10,6 +10,9 @@ def harmonic_sequence(a, d, n): Returns: List: List containing the harmonic sequence + Assertions: + - a, d, n must be integer + Examples: >>> harmonic_sequence(1, 1, 1) [1.0] @@ -27,6 +30,9 @@ def harmonic_sequence(a, d, n): [1.0, 0.2, 0.05, 0.02, 0.01, 0.004, 0.0016, 0.00064, 0.000256, 0.0001024] """ + assert isinstance(a, int), "A must be integer" + assert isinstance(d, int), "D must be integer" + assert isinstance(n, int), "N must be integer" sequence = [] if n <= 0: return sequence diff --git a/solutions/tests/test_harmonic_sequence.py b/solutions/tests/test_harmonic_sequence.py index c8f3f41ac..b5bced429 100644 --- a/solutions/tests/test_harmonic_sequence.py +++ b/solutions/tests/test_harmonic_sequence.py @@ -1,9 +1,23 @@ +""" +Test module for alternate_elements function. +Contains intentionally buggy tests for debugging practice. + +Test categories: + - Standard cases: The input is a list of integers. + - Edge cases: The input is equal to 0 or 1. + - Defensive cases: wrong input types, assertions + +Created on 2024-12-30 +Author: Omnia Mustafa - Abdulgadir +""" + import unittest from ..harmonic_sequence import harmonic_sequence class TestAsciiCode(unittest.TestCase): + # Edge cases: def test_min_input1(self): """Test case when all inputs equal to 1""" self.assertEqual(harmonic_sequence(1, 1, 1), [1.0]) @@ -26,6 +40,41 @@ def test_a_and_d_equal_1(self): harmonic_sequence(1, 1, 5), [1.0, 0.5, 0.3333333333333333, 0.25, 0.2] ) + # Standard cases: def test_all_inputs_greater_than_1(self): """Test when all inputs are integer and greater than 1""" self.assertEqual(harmonic_sequence(2, 2, 3), [0.5, 0.25, 0.16666666666666666]) + + def test_n_is_large(self): + """Test when n is large""" + self.assertEqual( + harmonic_sequence(4, 3, 10), + [ + 0.25, + 0.125, + 0.08333333333333333, + 0.0625, + 0.05, + 0.041666666666666664, + 0.03571428571428571, + 0.03125, + 0.027777777777777776, + 0.025, + ], + ) + + # Defensive cases: + def wrong_input_a_type(self): + """Test when input a is not integer""" + with self.assertRaises(AssertionError): + harmonic_sequence("1", 1, 1) + + def wrong_input_d_type(self): + """Test when input d is not integer""" + with self.assertRaises(AssertionError): + harmonic_sequence(5, "Omnia", 10) + + def wrong_input_n_type(self): + """Test when input n is not integer""" + with self.assertRaises(AssertionError): + harmonic_sequence(1, 1, [1, 2, 3]) From f2a9ca481dd374d328e73cfa42b983830ca413fa Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Mon, 30 Dec 2024 20:09:31 +0400 Subject: [PATCH 017/151] Fix 1 test result --- solutions/tests/test_harmonic_sequence.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/solutions/tests/test_harmonic_sequence.py b/solutions/tests/test_harmonic_sequence.py index b5bced429..3db3f16c0 100644 --- a/solutions/tests/test_harmonic_sequence.py +++ b/solutions/tests/test_harmonic_sequence.py @@ -51,15 +51,15 @@ def test_n_is_large(self): harmonic_sequence(4, 3, 10), [ 0.25, - 0.125, - 0.08333333333333333, + 0.14285714285714285, + 0.1, + 0.07692307692307693, 0.0625, - 0.05, - 0.041666666666666664, + 0.05263157894736842, + 0.045454545454545456, + 0.04, 0.03571428571428571, - 0.03125, - 0.027777777777777776, - 0.025, + 0.03225806451612903, ], ) From ebe0c804176c26ea86f52870bc0142d5d09cdfba Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Mon, 30 Dec 2024 20:14:54 +0400 Subject: [PATCH 018/151] Add more comments --- solutions/harmonic_sequence.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/solutions/harmonic_sequence.py b/solutions/harmonic_sequence.py index 1ec41d407..c89689c1d 100644 --- a/solutions/harmonic_sequence.py +++ b/solutions/harmonic_sequence.py @@ -11,7 +11,9 @@ def harmonic_sequence(a, d, n): List: List containing the harmonic sequence Assertions: - - a, d, n must be integer + - a must be integer + - d must be integer + - n must be integer Examples: >>> harmonic_sequence(1, 1, 1) @@ -30,14 +32,20 @@ def harmonic_sequence(a, d, n): [1.0, 0.2, 0.05, 0.02, 0.01, 0.004, 0.0016, 0.00064, 0.000256, 0.0001024] """ + # Assert an error if any input is not integer assert isinstance(a, int), "A must be integer" assert isinstance(d, int), "D must be integer" assert isinstance(n, int), "N must be integer" + + # Create an empty list to save the sequence sequence = [] + # If n is less than or equal to 0, return empty list if n <= 0: return sequence + # If a and d are equal to 0, return a list of n zeros if a == 0 and d == 0: return [0] * n + # If all inputs are greater than 1, return the sequence for i in range(1, n + 1): term = 1 / (a + (i - 1) * d) sequence.append(term) From f71e319491e6985a337a25338520229a9ef208b2 Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Mon, 30 Dec 2024 20:38:33 +0400 Subject: [PATCH 019/151] Add more details in the documment --- solutions/harmonic_sequence.py | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/solutions/harmonic_sequence.py b/solutions/harmonic_sequence.py index c89689c1d..1a282c62e 100644 --- a/solutions/harmonic_sequence.py +++ b/solutions/harmonic_sequence.py @@ -16,20 +16,40 @@ def harmonic_sequence(a, d, n): - n must be integer Examples: + Edge cases: >>> harmonic_sequence(1, 1, 1) [1.0] >>> harmonic_sequence(1, 1, 0) [] >>> harmonic_sequence(0, 0, 5) - [0.0, 0.0, 0.0, 0.0, 0.0] + [0, 0, 0, 0, 0] >>> harmonic_sequence(1, 1, -1) [] >>> harmonic_sequence(1, 1, 5) [1.0, 0.5, 0.3333333333333333, 0.25, 0.2] + Standard cases: >>> harmonic_sequence(2, 2, 3) - [0.5, 0.3333333333333333, 0.25] - >>> harmonic_sequence(1, 5, 10) - [1.0, 0.2, 0.05, 0.02, 0.01, 0.004, 0.0016, 0.00064, 0.000256, 0.0001024] + [0.5, 0.25, 0.16666666666666666] + >>> harmonic_sequence(4, 3, 10) + [0.25, + 0.14285714285714285, + 0.1, + 0.07692307692307693, + 0.0625, + 0.05263157894736842, + 0.045454545454545456, + 0.04, + 0.03571428571428571, + 0.03225806451612903,] + Defensive cases: + >>> harmonic_sequence("1", 1, 1) + AssertionError: A must be integer + >>> harmonic_sequence(5, "Omnia", 10) + AssertionError: D must be integer + >>> harmonic_sequence(1, 1, [1, 2, 3]) + AssertionError: N must be integer + + """ # Assert an error if any input is not integer From 1ee1c5d543cf17a6b45e718b153ee57c64fd8190 Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Mon, 30 Dec 2024 21:42:44 +0400 Subject: [PATCH 020/151] Quadratic Sequence code --- solutions/quadratic_sequence.py | 54 ++++++++++++++++- solutions/tests/test_harmonic_sequence.py | 28 ++++++++- solutions/tests/test_quadratic_sequence.py | 70 +++++++++++++++++++++- 3 files changed, 146 insertions(+), 6 deletions(-) diff --git a/solutions/quadratic_sequence.py b/solutions/quadratic_sequence.py index c3ccf46b5..1156f59cb 100644 --- a/solutions/quadratic_sequence.py +++ b/solutions/quadratic_sequence.py @@ -1,6 +1,6 @@ def quadratic_sequence(a, b, c, n): """ - The function creates quadratic sequence, based on formula: A(n): an^2 + bn + c + The function creates quadratic sequence, based on formula: A(n): a*n^2 + b*n + c Parameters: a (int): Coefficient of n^2 @@ -9,6 +9,56 @@ def quadratic_sequence(a, b, c, n): n (int): Number of terms to generate Returns: - List: List containing the quadratic sequence + List: List containing the quadratic sequence + + Assertions: + - a must be integer + - b must be integer + - c must be integer + - n must be integer + + Examples: + Edge cases: + >>> quadratic_sequence(0, 0, 0, 0) + [] + >>> quadratic_sequence(5, 3, 2, 0) + [] + >>> quadratic_sequence(1, 1, 1, 1) + [3] + >>> quadratic_sequence(0, 5, 3, 2) + [8, 13] + >>> quadratic_sequence(5, 0, 3, 2) + [8, 23] + >>> quadratic_sequence(5, 3, 0, 2) + [8, 26] + Standard cases: + >>> quadratic_sequence(3, 3, 3, 3) + [9, 21, 39] + >>> quadratic_sequence(1, 2, 3, 4) + [6, 11, 18, 27] + Defensive cases: + >>> quadratic_sequence("1", 1, 1, 1) + AssertionError: A must be integer + >>> quadratic_sequence(5, "Omnia", 10, 6) + AssertionError: B must be integer + >>> quadratic_sequence(1, 5, [1, 2, 3], 8) + AssertionError: C must be integer + >>> quadratic_sequence(1, 1, 5, [1, 2, 3]) + AssertionError: N must be integer """ + # Assert error if inputs are not integers + assert isinstance(a, int), "A must be integer" + assert isinstance(b, int), "B must be integer" + assert isinstance(c, int), "C must be integer" + assert isinstance(n, int), "N must be integer" + # Create quadratic sequence + sequence = [] + # Return empty list if n is less than or equal to 0 + if n <= 0: + return sequence + # Create quadratic sequence + for i in range(1, n + 1): + term = (a * (i**2)) + (b * i) + c + sequence.append(term) + return sequence diff --git a/solutions/tests/test_harmonic_sequence.py b/solutions/tests/test_harmonic_sequence.py index 3db3f16c0..fd88aa993 100644 --- a/solutions/tests/test_harmonic_sequence.py +++ b/solutions/tests/test_harmonic_sequence.py @@ -1,6 +1,5 @@ """ -Test module for alternate_elements function. -Contains intentionally buggy tests for debugging practice. +Test module for harmonic_sequence function. Test categories: - Standard cases: The input is a list of integers. @@ -16,7 +15,30 @@ from ..harmonic_sequence import harmonic_sequence -class TestAsciiCode(unittest.TestCase): +class TestHarmonicSequence(unittest.TestCase): + """ + This class, `TestHarmonicSequence`, contains a set of test cases for the `harmonic_sequence` function. The test cases cover various scenarios, including edge cases, standard cases, and defensive cases. + + The edge cases include: + - When all inputs are equal to 1 + - When `n` is equal to 0 + - When `a` and `d` are equal to 0 + - When `n` is negative + - When `a` and `d` are equal to 1 + + The standard cases include: + - When all inputs are integers and greater than 1 + - When `n` is large + + The defensive cases include: + - When the input `a` is not an integer + - When the input `d` is not an integer + - When the input `n` is not an integer + + These test cases ensure that the `harmonic_sequence` function + behaves as expected under various input conditions. + """ + # Edge cases: def test_min_input1(self): """Test case when all inputs equal to 1""" diff --git a/solutions/tests/test_quadratic_sequence.py b/solutions/tests/test_quadratic_sequence.py index 4bcf37a95..d7e45171b 100644 --- a/solutions/tests/test_quadratic_sequence.py +++ b/solutions/tests/test_quadratic_sequence.py @@ -1,4 +1,72 @@ +""" +Test module for quadratic_sequence function. + +Test categories: + - Standard cases: The input is a list of integers. + - Edge cases: The input is equal to 0 or 1. + - Defensive cases: wrong input types, assertions + +Created on 2024-12-30 +Author: Omnia Mustafa - Abdulgadir +""" + import unittest + from ..quadratic_sequence import quadratic_sequence -class TestAsciiCode(unittest.TestCase): + +class TestQuadraticSequence(unittest.TestCase): + # Edge cases: + def test_all_inputs_are_0(self): + """Test case when all inputs equal to 0""" + self.assertEqual(quadratic_sequence(0, 0, 0, 0), []) + + def test_n_is_0(self): + """Test case when n is equal to 0""" + self.assertEqual(quadratic_sequence(5, 3, 2, 0), []) + + def test_all_inputs_are_1(self): + """Test case when all inputs equal to 1""" + self.assertEqual(quadratic_sequence(1, 1, 1, 1), [3]) + + def test_a_is_0(self): + """Test case when a is equal to 0""" + self.assertEqual(quadratic_sequence(0, 5, 3, 2), [8, 13]) + + def test_b_is_0(self): + """Test case when b is equal to 0""" + self.assertEqual(quadratic_sequence(5, 0, 3, 2), [8, 23]) + + def test_c_is_0(self): + """Test case when c is equal to 0""" + self.assertEqual(quadratic_sequence(5, 3, 0, 2), [8, 26]) + + # Standard cases: + def test_equal_inputs(self): + """Test case when all inputs are equal""" + self.assertEqual(quadratic_sequence(3, 3, 3, 3), [9, 21, 39]) + + def test_different_inputs(self): + """Test case when all inputs are different""" + self.assertEqual(quadratic_sequence(1, 2, 3, 4), [6, 11, 18, 27]) + + # Defensive cases: + def wrong_input_a_type(self): + """Test when input a is not integer""" + with self.assertRaises(AssertionError): + quadratic_sequence("1", 1, 1, 1) + + def wrong_input_b_type(self): + """Test when input b is not integer""" + with self.assertRaises(AssertionError): + quadratic_sequence(5, "Omnia", 10, 6) + + def wrong_input_c_type(self): + """Test when input c is not integer""" + with self.assertRaises(AssertionError): + quadratic_sequence(1, 5, [1, 2, 3], 8) + + def wrong_input_n_type(self): + """Test when input n is not integer""" + with self.assertRaises(AssertionError): + quadratic_sequence(1, 1, 5, [1, 2, 3]) From 979058f6ddf672c451285693c60a4601a8ee799d Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Tue, 31 Dec 2024 15:50:20 +0200 Subject: [PATCH 021/151] initial commit --- .vscode/settings.json | 4 +- solutions/test_5.txt | 1 + solutions/test_empty.txt | 0 solutions/test_multiple.txt | 3 ++ solutions/tests/test_word_count_from_file.py | 48 +++++++++++++++++ solutions/word_count_from_file.py | 56 ++++++++++++++++++++ 6 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 solutions/test_5.txt create mode 100644 solutions/test_empty.txt create mode 100644 solutions/test_multiple.txt create mode 100644 solutions/tests/test_word_count_from_file.py create mode 100644 solutions/word_count_from_file.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/test_5.txt b/solutions/test_5.txt new file mode 100644 index 000000000..9f4b6d8bf --- /dev/null +++ b/solutions/test_5.txt @@ -0,0 +1 @@ +This is a test file diff --git a/solutions/test_empty.txt b/solutions/test_empty.txt new file mode 100644 index 000000000..e69de29bb diff --git a/solutions/test_multiple.txt b/solutions/test_multiple.txt new file mode 100644 index 000000000..2c07b4bce --- /dev/null +++ b/solutions/test_multiple.txt @@ -0,0 +1,3 @@ +This is a test +when the file +has multiple lines diff --git a/solutions/tests/test_word_count_from_file.py b/solutions/tests/test_word_count_from_file.py new file mode 100644 index 000000000..408130238 --- /dev/null +++ b/solutions/tests/test_word_count_from_file.py @@ -0,0 +1,48 @@ +""" +Counts the number of words in a .txt file + +Parameters: + file_name (str) - The name of the file + +Returns -> The total number of words in the file + +Raises: AssertionError + + +""" + +import os +import sys +import unittest + +# Add the project root directory to sys.path +project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) +sys.path.append(project_root) + +from solutions.word_count_from_file import word_count_txt_file + + +class TestWordCountFromFile(unittest.TestCase): + """Test the words counting function""" + + def test_5(self): + """This method test if the function returns the correct number""" + self.assertEqual(word_count_txt_file("solutions/test_5.txt"), 5) + + def test_empty(self): + """This method test an empty file""" + self.assertEqual(word_count_txt_file("solutions/test_empty.txt"), 0) + + def test_multiple_lines(self): + """This method test when a file has multiple lines""" + self.assertEqual(word_count_txt_file("solutions/test_multiple.txt"), 10) + + def test_file_not_exist(self): + """This method test when a file has multiple lines""" + with self.assertRaises(AssertionError): + word_count_txt_file("not_exist.txt") + + def test_not_a_txt_file(self): + """It should raise an assertion error if the argument is not an integer""" + with self.assertRaises(AssertionError): + word_count_txt_file("test") diff --git a/solutions/word_count_from_file.py b/solutions/word_count_from_file.py new file mode 100644 index 000000000..034c77a89 --- /dev/null +++ b/solutions/word_count_from_file.py @@ -0,0 +1,56 @@ +""" +A Module for counting the number of words in a .txt file + +Module contents: + - .txt file: the file to read the content from + - Number: the number of words in the file + +created on 30 Dec 2024 +@author: saja abusafia +""" + +import os + + +def word_count_txt_file(file_name) -> int: + """ + The function counts the total number of words in a file + + Parameters: + String: file_name (str): the file name to read the content from + + Returns: + int n: The total number of words + + >>> word_count_txt_file("solutions/test_5.txt") + 5 + >>> word_count_txt_file("solutions/test_empty.txt") + 0 + >>> word_count_txt_file("solutions/test_multiple.txt") + 10 + """ + assert os.path.exists(file_name), f"Error: The file '{file_name}' does not exist." + assert file_name.endswith( + ".txt" + ), f"Error: The file '{file_name}' does not have a .txt extension." + + f = open(file_name, "r") + file_size = os.path.getsize(file_name) + if file_size == 0: + return 0 + + file_content = f.read() + + i = 0 + + for n in file_content: + if n == "": + i += 1 + break + elif n == " ": + i += 1 # Increment if the character is a space + elif n == "\n": + i += 1 # Increment if reaches the end of a file + + f.close() + return i From bb06938d7cfb93802ebc80c7ce27ecb73e712ac8 Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Tue, 31 Dec 2024 16:06:27 +0200 Subject: [PATCH 022/151] modifications for cl --- solutions/tests/test_word_count_from_file.py | 22 +++++++++----------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/solutions/tests/test_word_count_from_file.py b/solutions/tests/test_word_count_from_file.py index 408130238..aabbae8b2 100644 --- a/solutions/tests/test_word_count_from_file.py +++ b/solutions/tests/test_word_count_from_file.py @@ -1,3 +1,13 @@ +import os +import sys +import unittest + +# Add the project root directory to sys.path +project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) +sys.path.append(project_root) + +from solutions.word_count_from_file import word_count_txt_file + """ Counts the number of words in a .txt file @@ -7,20 +17,8 @@ Returns -> The total number of words in the file Raises: AssertionError - - """ -import os -import sys -import unittest - -# Add the project root directory to sys.path -project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) -sys.path.append(project_root) - -from solutions.word_count_from_file import word_count_txt_file - class TestWordCountFromFile(unittest.TestCase): """Test the words counting function""" From e8d40353d704794dc84814c5d6756fa7e2229360 Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Tue, 31 Dec 2024 19:21:18 +0400 Subject: [PATCH 023/151] Harmonic Sequence code --- solutions/harmonic_sequence.py | 69 +++++++++++++++++++- solutions/tests/test_harmonic_sequence.py | 76 +++++++++++++++++++++++ 2 files changed, 144 insertions(+), 1 deletion(-) diff --git a/solutions/harmonic_sequence.py b/solutions/harmonic_sequence.py index 9e66dcb91..53044c1b5 100644 --- a/solutions/harmonic_sequence.py +++ b/solutions/harmonic_sequence.py @@ -1,6 +1,10 @@ +"""Creates harmonic sequence, based on formula: A(n): 1/ (a +(n-1) *d)""" + + def harmonic_sequence(a, d, n): """ - The function creates harmonic sequence, based on formula: A(n): 1/ (a +(n-1) *d) + This function ,`harmonic_sequence`, creates a harmonic sequence, + based on formula: A(n): 1/ (a +(n-1) *d) Parameters: a (int): First term @@ -10,4 +14,67 @@ def harmonic_sequence(a, d, n): Returns: List: List containing the harmonic sequence + Assertions: + - a must be integer + - d must be integer + - n must be integer + + Examples: + Edge cases: + >>> harmonic_sequence(1, 1, 1) + [1.0] + >>> harmonic_sequence(1, 1, 0) + [] + >>> harmonic_sequence(0, 0, 5) + [0, 0, 0, 0, 0] + >>> harmonic_sequence(1, 1, -1) + [] + >>> harmonic_sequence(1, 1, 5) + [1.0, 0.5, 0.3333333333333333, 0.25, 0.2] + + + Standard cases: + >>> harmonic_sequence(2, 2, 3) + [0.5, 0.25, 0.16666666666666666] + >>> harmonic_sequence(4, 3, 10) + [0.25, + 0.14285714285714285, + 0.1, + 0.07692307692307693, + 0.0625, + 0.05263157894736842, + 0.045454545454545456, + 0.04, + 0.03571428571428571, + 0.03225806451612903,] + + + Defensive cases: + >>> harmonic_sequence("1", 1, 1) + AssertionError: A must be integer + >>> harmonic_sequence(5, "Omnia", 10) + AssertionError: D must be integer + >>> harmonic_sequence(1, 1, [1, 2, 3]) + AssertionError: N must be integer + + + """ + # Assert an error if any input is not integer + assert isinstance(a, int), "A must be integer" + assert isinstance(d, int), "D must be integer" + assert isinstance(n, int), "N must be integer" + + # Create an empty list to save the sequence + sequence = [] + # If n is less than or equal to 0, return empty list + if n <= 0: + return sequence + # If a and d are equal to 0, return a list of n zeros + if a == 0 and d == 0: + return [0] * n + # If all inputs are greater than 1, return the sequence + for i in range(1, n + 1): + term = 1 / (a + (i - 1) * d) + sequence.append(term) + return sequence diff --git a/solutions/tests/test_harmonic_sequence.py b/solutions/tests/test_harmonic_sequence.py index 2284aa3e9..3db3f16c0 100644 --- a/solutions/tests/test_harmonic_sequence.py +++ b/solutions/tests/test_harmonic_sequence.py @@ -1,4 +1,80 @@ +""" +Test module for alternate_elements function. +Contains intentionally buggy tests for debugging practice. + +Test categories: + - Standard cases: The input is a list of integers. + - Edge cases: The input is equal to 0 or 1. + - Defensive cases: wrong input types, assertions + +Created on 2024-12-30 +Author: Omnia Mustafa - Abdulgadir +""" + import unittest + from ..harmonic_sequence import harmonic_sequence + class TestAsciiCode(unittest.TestCase): + # Edge cases: + def test_min_input1(self): + """Test case when all inputs equal to 1""" + self.assertEqual(harmonic_sequence(1, 1, 1), [1.0]) + + def test_n_equal_0(self): + """Test case when n is equal to 0""" + self.assertEqual(harmonic_sequence(1, 1, 0), []) + + def test_a_and_d_equal_0(self): + """Test case when a and d are equal to 0""" + self.assertEqual(harmonic_sequence(0, 0, 5), [0, 0, 0, 0, 0]) + + def test_n_negative(self): + """Test case when n is negative""" + self.assertEqual(harmonic_sequence(1, 1, -1), []) + + def test_a_and_d_equal_1(self): + """Test a and d are equal 1""" + self.assertEqual( + harmonic_sequence(1, 1, 5), [1.0, 0.5, 0.3333333333333333, 0.25, 0.2] + ) + + # Standard cases: + def test_all_inputs_greater_than_1(self): + """Test when all inputs are integer and greater than 1""" + self.assertEqual(harmonic_sequence(2, 2, 3), [0.5, 0.25, 0.16666666666666666]) + + def test_n_is_large(self): + """Test when n is large""" + self.assertEqual( + harmonic_sequence(4, 3, 10), + [ + 0.25, + 0.14285714285714285, + 0.1, + 0.07692307692307693, + 0.0625, + 0.05263157894736842, + 0.045454545454545456, + 0.04, + 0.03571428571428571, + 0.03225806451612903, + ], + ) + + # Defensive cases: + def wrong_input_a_type(self): + """Test when input a is not integer""" + with self.assertRaises(AssertionError): + harmonic_sequence("1", 1, 1) + + def wrong_input_d_type(self): + """Test when input d is not integer""" + with self.assertRaises(AssertionError): + harmonic_sequence(5, "Omnia", 10) + + def wrong_input_n_type(self): + """Test when input n is not integer""" + with self.assertRaises(AssertionError): + harmonic_sequence(1, 1, [1, 2, 3]) From d722bb5da5a1b395228288e035726ca2222cf2bc Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Tue, 31 Dec 2024 19:38:39 +0400 Subject: [PATCH 024/151] Edit the document --- solutions/tests/test_harmonic_sequence.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/solutions/tests/test_harmonic_sequence.py b/solutions/tests/test_harmonic_sequence.py index 3db3f16c0..d168652c6 100644 --- a/solutions/tests/test_harmonic_sequence.py +++ b/solutions/tests/test_harmonic_sequence.py @@ -1,6 +1,5 @@ """ -Test module for alternate_elements function. -Contains intentionally buggy tests for debugging practice. +Test module for Harmonic sequence function. Test categories: - Standard cases: The input is a list of integers. @@ -16,7 +15,9 @@ from ..harmonic_sequence import harmonic_sequence -class TestAsciiCode(unittest.TestCase): +class TestHarmonicSequence(unittest.TestCase): + """Test Harmonic Sequence""" + # Edge cases: def test_min_input1(self): """Test case when all inputs equal to 1""" From 78d0453369c979c436cbaba9b53b563620e57b31 Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Tue, 31 Dec 2024 19:51:10 +0400 Subject: [PATCH 025/151] edit communication file --- .vscode/settings.json | 11 ++- collaboration/communication.md | 153 +++++++++++++++++++++++++++------ 2 files changed, 139 insertions(+), 25 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 252022b48..565c7bce2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -122,5 +122,14 @@ "source.fixAll.ruff": "explicit", "source.organizeImports.ruff": "explicit" } - } + }, + "cSpell.words": [ + "Gibril", + "Nouman", + "Osama", + "Rafaa", + "Reem", + "Safia", + "Tilal" + ] } diff --git a/collaboration/communication.md b/collaboration/communication.md index 484652e0f..2e86ae05e 100644 --- a/collaboration/communication.md +++ b/collaboration/communication.md @@ -9,39 +9,144 @@ # Communication -______________________________________________________________________ +As a team we agreed that we will make a poll in Slack +to check the validity of all the team, and will take the highest vote +as the meeting time. And before ending the meeting will discuss +about what do we want to do, what will be our next step +and what is the timeline for these tasks. +We use Google Meet as the meeting channel, +while Slack is the channel for quick questions, +meetings plans and friendly communication channel. +We use GitHub as the basic channel for coding, +rase a challenge or any professional communication. -## Communication Schedule +## Meeting Agendas -| Day | How | The topic of discussion | | --- | :-: | ----------------------- | -| | | | +### First Meeting -## Communication Channels +#### Date: December 20, 2024 -how often will we get in touch on each channel, and what we will discuss there: +##### Overview of the first meeting -- **Issues**: -- **Pull Requests**: -- **Slack/Discord**: -- **Video Calls**: +We held an introductory meeting where everyone introduced themselves. +Our main focus was on two documents: +"Defining Group Norms" and "Tools of Collaborative Development." -______________________________________________________________________ +##### Key Points of the first meeting -## Availability +- Defining Group Norms: +Members should contribute by answering the questions +in the brainstorm section, adding their responses as bullet points, +and commenting with their names. +- Tools of Collaborative Development: +Members should pick a subject from the document, +add three points, and write an explanation at the bottom. +- Next Steps: +Review and contribute to both documents. +Vote in the next meeting poll to schedule it. -### Availability for calling/messaging +### Second Meeting -| Day | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday | | ------- | :----: | :-----: | :-------: | :------: | :----: | :------: | :----: | -| _name_ | | | | | | | | +#### Date: December 21, 2024 -### How many hours everyone has per day +##### Overview of the second meeting -- name: _5h_; -- name: _6h_; -- name: _5h_; -- name: _4h_; -- name: _3h_; +In this meeting, we reviewed the "Defining Group Norms" +and "Tools of Collaborative Development" documents, +planned the repository, and discussed next steps for code review +and the group name. + +##### Key Points of the second meeting + +- Document Updates + Agreed on updates to the "Defining Group Norms" +and "Tools of Collaborative Development" documents. +Members who haven’t continued their contributions to the +"Tools of Collaborative Development" file should do so. +- Repository Progress: + Mohamed Tilal would summarize the brainstorming ideas +to be pushed later. +- Group Name: + Members should participate in the poll for the group name +and add suggestions if desired. +- Next Meeting Plans: + The next meeting would be a walkthrough with +Reem Osama on GitHub. + Problem selection for the code review will include suggestions +from Reem’s game. + Members should vote in the poll to finalize the next meeting time. + +### Third Meeting + +#### Date: December 24, 2024 + +##### Overview of the third meeting + +The meeting focused on a review session for GitHub +and the key functions we’ll use for the project. + +###### Key Points of the third meeting + +- GitHub Review: +Omnia Mustafa - Abdulgadir outlined the main +functions in a post in Slack. +Reem Osama provided a detailed file containing all the notes, +which would serve as a reference moving forward. +- Acknowledgment: +Special thanks to Reem Osama for her incredible effort +in the session and for preparing and sharing the notes. +Your contribution is greatly appreciated! +- Next Meeting: +Next meeting would focus on choosing the problems and +discussing our game plan moving forward. + +### Forth Meeting + +#### Date: December 25, 2024 + +##### Overview of the forth meeting + +This meeting was all about understanding each other's challenges +and identifying the person who will create a challenge for who. + +##### What's next + +- Omnia Mustafa - Abdulgadir wrote down everyone's experiences +and perspectives on programming. +- Reem Osama provided the link to find out +who will create the challenge for who. +- Once know the person, each person the team fill out +the second form to communicate their challenges. + +### Fifth Meeting + +#### Date: December 29, 2024 + +##### Overview of the fifth meeting + +The meeting focused on task assignments, +problem workflows, and planning the next steps. + +##### Key Points of the fifth meeting + +###### Task Assignments + +- Safia Gibril Nouman would assign two problems +to Reem Osama and Rafaa ALI. +- Ahmed would work on the Learning Goals and Constraints files. +- Omnia Mustafa - Abdulgadir would contribute to the Collaborative file. +- Reem Osama would collaborate on the README file. + +###### Problem Workflow + + By December 30, 2024, each member must: + +- Create a new Python file named after their assigned problem. +- Create a branch, add the file to it, and push it. +- Create an issue for the problem with the same name and add it to the project board. +After completing these steps, members have until January 2, 2025, +to solve their assigned problems, allowing the team to +start reviewing them afterward. ## Asking for Help @@ -50,5 +155,5 @@ stubbornly getting no where. Here is a general guide for when to ask for help based on how long you've been stuck on the same problem: 1. _0 -> 30 min_: Try on your own -1. _30 -> 60 min_: Ask your group for help -1. _60+ min_: Tag your coaches in Slack or GitHub +2. _30 -> 60 min_: Ask your group for help +3. _60+ min_: Tag your coaches in Slack or GitHub From b5c563a823caadbf66b27ac006337098b89bfdc9 Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Tue, 31 Dec 2024 20:35:17 +0400 Subject: [PATCH 026/151] Change document --- solutions/harmonic_sequence.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/solutions/harmonic_sequence.py b/solutions/harmonic_sequence.py index 53044c1b5..b4be1c27b 100644 --- a/solutions/harmonic_sequence.py +++ b/solutions/harmonic_sequence.py @@ -1,7 +1,12 @@ -"""Creates harmonic sequence, based on formula: A(n): 1/ (a +(n-1) *d)""" +"""Creates harmonic sequence, based on formula: A(n): 1/ (a +(n-1) *d) +given a, d and n are integers. and returns the list containing the harmonic sequence. +Created on 2024-12-30 +Author: Omnia Mustafa - Abdulgadir +""" -def harmonic_sequence(a, d, n): + +def harmonic_sequence(a: int, d: int, n: int) -> list: """ This function ,`harmonic_sequence`, creates a harmonic sequence, based on formula: A(n): 1/ (a +(n-1) *d) @@ -32,7 +37,6 @@ def harmonic_sequence(a, d, n): >>> harmonic_sequence(1, 1, 5) [1.0, 0.5, 0.3333333333333333, 0.25, 0.2] - Standard cases: >>> harmonic_sequence(2, 2, 3) [0.5, 0.25, 0.16666666666666666] @@ -48,7 +52,6 @@ def harmonic_sequence(a, d, n): 0.03571428571428571, 0.03225806451612903,] - Defensive cases: >>> harmonic_sequence("1", 1, 1) AssertionError: A must be integer @@ -56,9 +59,6 @@ def harmonic_sequence(a, d, n): AssertionError: D must be integer >>> harmonic_sequence(1, 1, [1, 2, 3]) AssertionError: N must be integer - - - """ # Assert an error if any input is not integer assert isinstance(a, int), "A must be integer" From 82e4751d1ae13263ecb9c3ec849a23331216cc46 Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Tue, 31 Dec 2024 20:50:39 +0400 Subject: [PATCH 027/151] fixed checks --- solutions/harmonic_sequence.py | 3 ++- solutions/tests/test_quadratic_sequence.py | 5 +---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/solutions/harmonic_sequence.py b/solutions/harmonic_sequence.py index b4be1c27b..66b373614 100644 --- a/solutions/harmonic_sequence.py +++ b/solutions/harmonic_sequence.py @@ -1,5 +1,6 @@ """Creates harmonic sequence, based on formula: A(n): 1/ (a +(n-1) *d) -given a, d and n are integers. and returns the list containing the harmonic sequence. +given a, d and n are integers. and returns +the list containing the harmonic sequence. Created on 2024-12-30 Author: Omnia Mustafa - Abdulgadir diff --git a/solutions/tests/test_quadratic_sequence.py b/solutions/tests/test_quadratic_sequence.py index 4bcf37a95..72bf3e2c4 100644 --- a/solutions/tests/test_quadratic_sequence.py +++ b/solutions/tests/test_quadratic_sequence.py @@ -1,4 +1 @@ -import unittest -from ..quadratic_sequence import quadratic_sequence - -class TestAsciiCode(unittest.TestCase): +from ..quadratic_sequence import quadratic_sequence # noqa: F401 From ba57371c6c0642e54852caa33bca8863d0f9b4fa Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Tue, 31 Dec 2024 21:05:14 +0400 Subject: [PATCH 028/151] update the checks --- solutions/harmonic_sequence.py | 80 --------------------- solutions/quadratic_sequence.py | 14 ---- solutions/tests/test_harmonic_sequence.py | 81 ---------------------- solutions/tests/test_quadratic_sequence.py | 4 -- 4 files changed, 179 deletions(-) delete mode 100644 solutions/harmonic_sequence.py delete mode 100644 solutions/quadratic_sequence.py delete mode 100644 solutions/tests/test_harmonic_sequence.py delete mode 100644 solutions/tests/test_quadratic_sequence.py diff --git a/solutions/harmonic_sequence.py b/solutions/harmonic_sequence.py deleted file mode 100644 index 53044c1b5..000000000 --- a/solutions/harmonic_sequence.py +++ /dev/null @@ -1,80 +0,0 @@ -"""Creates harmonic sequence, based on formula: A(n): 1/ (a +(n-1) *d)""" - - -def harmonic_sequence(a, d, n): - """ - This function ,`harmonic_sequence`, creates a harmonic sequence, - based on formula: A(n): 1/ (a +(n-1) *d) - - Parameters: - a (int): First term - d (int): Common difference - n (int): Number of terms to generate - - Returns: - List: List containing the harmonic sequence - - Assertions: - - a must be integer - - d must be integer - - n must be integer - - Examples: - Edge cases: - >>> harmonic_sequence(1, 1, 1) - [1.0] - >>> harmonic_sequence(1, 1, 0) - [] - >>> harmonic_sequence(0, 0, 5) - [0, 0, 0, 0, 0] - >>> harmonic_sequence(1, 1, -1) - [] - >>> harmonic_sequence(1, 1, 5) - [1.0, 0.5, 0.3333333333333333, 0.25, 0.2] - - - Standard cases: - >>> harmonic_sequence(2, 2, 3) - [0.5, 0.25, 0.16666666666666666] - >>> harmonic_sequence(4, 3, 10) - [0.25, - 0.14285714285714285, - 0.1, - 0.07692307692307693, - 0.0625, - 0.05263157894736842, - 0.045454545454545456, - 0.04, - 0.03571428571428571, - 0.03225806451612903,] - - - Defensive cases: - >>> harmonic_sequence("1", 1, 1) - AssertionError: A must be integer - >>> harmonic_sequence(5, "Omnia", 10) - AssertionError: D must be integer - >>> harmonic_sequence(1, 1, [1, 2, 3]) - AssertionError: N must be integer - - - - """ - # Assert an error if any input is not integer - assert isinstance(a, int), "A must be integer" - assert isinstance(d, int), "D must be integer" - assert isinstance(n, int), "N must be integer" - - # Create an empty list to save the sequence - sequence = [] - # If n is less than or equal to 0, return empty list - if n <= 0: - return sequence - # If a and d are equal to 0, return a list of n zeros - if a == 0 and d == 0: - return [0] * n - # If all inputs are greater than 1, return the sequence - for i in range(1, n + 1): - term = 1 / (a + (i - 1) * d) - sequence.append(term) - return sequence diff --git a/solutions/quadratic_sequence.py b/solutions/quadratic_sequence.py deleted file mode 100644 index c3ccf46b5..000000000 --- a/solutions/quadratic_sequence.py +++ /dev/null @@ -1,14 +0,0 @@ -def quadratic_sequence(a, b, c, n): - """ - The function creates quadratic sequence, based on formula: A(n): an^2 + bn + c - - Parameters: - a (int): Coefficient of n^2 - b (int): Coefficient of n - c (int): Constant term - n (int): Number of terms to generate - - Returns: - List: List containing the quadratic sequence - - """ diff --git a/solutions/tests/test_harmonic_sequence.py b/solutions/tests/test_harmonic_sequence.py deleted file mode 100644 index d168652c6..000000000 --- a/solutions/tests/test_harmonic_sequence.py +++ /dev/null @@ -1,81 +0,0 @@ -""" -Test module for Harmonic sequence function. - -Test categories: - - Standard cases: The input is a list of integers. - - Edge cases: The input is equal to 0 or 1. - - Defensive cases: wrong input types, assertions - -Created on 2024-12-30 -Author: Omnia Mustafa - Abdulgadir -""" - -import unittest - -from ..harmonic_sequence import harmonic_sequence - - -class TestHarmonicSequence(unittest.TestCase): - """Test Harmonic Sequence""" - - # Edge cases: - def test_min_input1(self): - """Test case when all inputs equal to 1""" - self.assertEqual(harmonic_sequence(1, 1, 1), [1.0]) - - def test_n_equal_0(self): - """Test case when n is equal to 0""" - self.assertEqual(harmonic_sequence(1, 1, 0), []) - - def test_a_and_d_equal_0(self): - """Test case when a and d are equal to 0""" - self.assertEqual(harmonic_sequence(0, 0, 5), [0, 0, 0, 0, 0]) - - def test_n_negative(self): - """Test case when n is negative""" - self.assertEqual(harmonic_sequence(1, 1, -1), []) - - def test_a_and_d_equal_1(self): - """Test a and d are equal 1""" - self.assertEqual( - harmonic_sequence(1, 1, 5), [1.0, 0.5, 0.3333333333333333, 0.25, 0.2] - ) - - # Standard cases: - def test_all_inputs_greater_than_1(self): - """Test when all inputs are integer and greater than 1""" - self.assertEqual(harmonic_sequence(2, 2, 3), [0.5, 0.25, 0.16666666666666666]) - - def test_n_is_large(self): - """Test when n is large""" - self.assertEqual( - harmonic_sequence(4, 3, 10), - [ - 0.25, - 0.14285714285714285, - 0.1, - 0.07692307692307693, - 0.0625, - 0.05263157894736842, - 0.045454545454545456, - 0.04, - 0.03571428571428571, - 0.03225806451612903, - ], - ) - - # Defensive cases: - def wrong_input_a_type(self): - """Test when input a is not integer""" - with self.assertRaises(AssertionError): - harmonic_sequence("1", 1, 1) - - def wrong_input_d_type(self): - """Test when input d is not integer""" - with self.assertRaises(AssertionError): - harmonic_sequence(5, "Omnia", 10) - - def wrong_input_n_type(self): - """Test when input n is not integer""" - with self.assertRaises(AssertionError): - harmonic_sequence(1, 1, [1, 2, 3]) diff --git a/solutions/tests/test_quadratic_sequence.py b/solutions/tests/test_quadratic_sequence.py deleted file mode 100644 index 4bcf37a95..000000000 --- a/solutions/tests/test_quadratic_sequence.py +++ /dev/null @@ -1,4 +0,0 @@ -import unittest -from ..quadratic_sequence import quadratic_sequence - -class TestAsciiCode(unittest.TestCase): From 6e5731ece5deb11b3d26a2b128064682838b4f80 Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Tue, 31 Dec 2024 21:22:30 +0400 Subject: [PATCH 029/151] Delete files error --- solutions/harmonic_sequence.py | 13 ------------- solutions/quadratic_sequence.py | 14 -------------- solutions/tests/test_harmonic_sequence.py | 4 ---- solutions/tests/test_quadratic_sequence.py | 4 ---- 4 files changed, 35 deletions(-) delete mode 100644 solutions/harmonic_sequence.py delete mode 100644 solutions/quadratic_sequence.py delete mode 100644 solutions/tests/test_harmonic_sequence.py delete mode 100644 solutions/tests/test_quadratic_sequence.py diff --git a/solutions/harmonic_sequence.py b/solutions/harmonic_sequence.py deleted file mode 100644 index 9e66dcb91..000000000 --- a/solutions/harmonic_sequence.py +++ /dev/null @@ -1,13 +0,0 @@ -def harmonic_sequence(a, d, n): - """ - The function creates harmonic sequence, based on formula: A(n): 1/ (a +(n-1) *d) - - Parameters: - a (int): First term - d (int): Common difference - n (int): Number of terms to generate - - Returns: - List: List containing the harmonic sequence - - """ diff --git a/solutions/quadratic_sequence.py b/solutions/quadratic_sequence.py deleted file mode 100644 index c3ccf46b5..000000000 --- a/solutions/quadratic_sequence.py +++ /dev/null @@ -1,14 +0,0 @@ -def quadratic_sequence(a, b, c, n): - """ - The function creates quadratic sequence, based on formula: A(n): an^2 + bn + c - - Parameters: - a (int): Coefficient of n^2 - b (int): Coefficient of n - c (int): Constant term - n (int): Number of terms to generate - - Returns: - List: List containing the quadratic sequence - - """ diff --git a/solutions/tests/test_harmonic_sequence.py b/solutions/tests/test_harmonic_sequence.py deleted file mode 100644 index 2284aa3e9..000000000 --- a/solutions/tests/test_harmonic_sequence.py +++ /dev/null @@ -1,4 +0,0 @@ -import unittest -from ..harmonic_sequence import harmonic_sequence - -class TestAsciiCode(unittest.TestCase): diff --git a/solutions/tests/test_quadratic_sequence.py b/solutions/tests/test_quadratic_sequence.py deleted file mode 100644 index 4bcf37a95..000000000 --- a/solutions/tests/test_quadratic_sequence.py +++ /dev/null @@ -1,4 +0,0 @@ -import unittest -from ..quadratic_sequence import quadratic_sequence - -class TestAsciiCode(unittest.TestCase): From 5d229b06a02408ddbc4b898770defc3affe932c2 Mon Sep 17 00:00:00 2001 From: Mayar-Agab Date: Tue, 31 Dec 2024 19:30:49 +0200 Subject: [PATCH 030/151] Added the test file and the python file for even_number_count --- solutions/even_number_count | 47 +++++++++++++++++++++ solutions/tests/test_even_number_count.py | 50 +++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 solutions/even_number_count diff --git a/solutions/even_number_count b/solutions/even_number_count new file mode 100644 index 000000000..63ea6c592 --- /dev/null +++ b/solutions/even_number_count @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A function that counts the number of even numbers in a countdown from n to 1 + +Module contents: + - even_number_count: generates a number for the amount of even numbers in the list. + +Created on Monday/ 30/ December/ 2024 +@author: Mayar Ali. +""" + +def even_number_count(number: list) -> int: + """Returns the number of even numbers on the list. + + Parameters: + int: list, the input list to process + + return - > int: indicating the number of even number in the list + + Raises: + AssertionError: + + Examples: + >>> even_number_count ([1]) + 0 + >>> even_number_count ([2,1]) + 1 + >>> even_number_count ([3,2,1]) + 1 + """ + assert isinstance(number,list) + for num in number: + assert isinstance(num,int) + + count = 0 + + for num in number: + if num % 2 ==0: + count +=1 + return count + +if __name__ == "__main__": + + print(even_number_count([1,2,3,4,5])) + + diff --git a/solutions/tests/test_even_number_count.py b/solutions/tests/test_even_number_count.py index e69de29bb..5d65f0a3c 100644 --- a/solutions/tests/test_even_number_count.py +++ b/solutions/tests/test_even_number_count.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Monday/ 30/ December/2024 +@author: Mayar Ali + +""" + +import unittest + +# --- imports & test class before documenting and testing --- + +# from ..TestEvenNumberCount import TestEvenNumberCount + +# class TestTestEvenNumberCount(unittest.TestCase): + +# --- imports & test class after documenting and testing --- + +from ..even_number_count import even_number_count # type: ignore + +class TestEvenNumberCount(unittest.TestCase): + """test the even_number_count function """ + + def test_0(self): + """It should return zero""" + self.assertEqual(even_number_count([1]), 0) + + def test_1(self): + """It should count the number of even numbers in a countdown from n to 1 """ + self.assertEqual(even_number_count([1,2]), 1) + + def test_2(self): + """It should count the number of even numbers in a countdown from n to 1 """ + self.assertEqual(even_number_count([1,2,3]), 1) + + def test_3(self): + """It should count the number of even numbers in a countdown from n to 1 """ + self.assertEqual(even_number_count([1,2,3,4]), 2) + + def test_4(self): + """It should count the number of even numbers in a countdown from n to 1 """ + self.assertEqual(even_number_count([1,2,3,4,5]), 2) + + def test_5(self): + """It should count the number of even numbers in a countdown from n to 1 """ + self.assertEqual(even_number_count([1,2,3,4,5,6]), [3]) + + def test_6(self): + """It should count the number of even numbers in a countdown from n to 1 """ + self.assertEqual(even_number_count([1,2,3,4,5,6,7]), [3]) \ No newline at end of file From ae56a11c7da8a3f6b3f4e6d533270b954170fd44 Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Tue, 31 Dec 2024 21:37:41 +0400 Subject: [PATCH 031/151] Delete unnessessory files --- solutions/harmonic_sequence.py | 72 --------------- solutions/tests/test_harmonic_sequence.py | 102 ---------------------- 2 files changed, 174 deletions(-) delete mode 100644 solutions/harmonic_sequence.py delete mode 100644 solutions/tests/test_harmonic_sequence.py diff --git a/solutions/harmonic_sequence.py b/solutions/harmonic_sequence.py deleted file mode 100644 index 1a282c62e..000000000 --- a/solutions/harmonic_sequence.py +++ /dev/null @@ -1,72 +0,0 @@ -def harmonic_sequence(a, d, n): - """ - The function creates harmonic sequence, based on formula: A(n): 1/ (a +(n-1) *d) - - Parameters: - a (int): First term - d (int): Common difference - n (int): Number of terms to generate - - Returns: - List: List containing the harmonic sequence - - Assertions: - - a must be integer - - d must be integer - - n must be integer - - Examples: - Edge cases: - >>> harmonic_sequence(1, 1, 1) - [1.0] - >>> harmonic_sequence(1, 1, 0) - [] - >>> harmonic_sequence(0, 0, 5) - [0, 0, 0, 0, 0] - >>> harmonic_sequence(1, 1, -1) - [] - >>> harmonic_sequence(1, 1, 5) - [1.0, 0.5, 0.3333333333333333, 0.25, 0.2] - Standard cases: - >>> harmonic_sequence(2, 2, 3) - [0.5, 0.25, 0.16666666666666666] - >>> harmonic_sequence(4, 3, 10) - [0.25, - 0.14285714285714285, - 0.1, - 0.07692307692307693, - 0.0625, - 0.05263157894736842, - 0.045454545454545456, - 0.04, - 0.03571428571428571, - 0.03225806451612903,] - Defensive cases: - >>> harmonic_sequence("1", 1, 1) - AssertionError: A must be integer - >>> harmonic_sequence(5, "Omnia", 10) - AssertionError: D must be integer - >>> harmonic_sequence(1, 1, [1, 2, 3]) - AssertionError: N must be integer - - - - """ - # Assert an error if any input is not integer - assert isinstance(a, int), "A must be integer" - assert isinstance(d, int), "D must be integer" - assert isinstance(n, int), "N must be integer" - - # Create an empty list to save the sequence - sequence = [] - # If n is less than or equal to 0, return empty list - if n <= 0: - return sequence - # If a and d are equal to 0, return a list of n zeros - if a == 0 and d == 0: - return [0] * n - # If all inputs are greater than 1, return the sequence - for i in range(1, n + 1): - term = 1 / (a + (i - 1) * d) - sequence.append(term) - return sequence diff --git a/solutions/tests/test_harmonic_sequence.py b/solutions/tests/test_harmonic_sequence.py deleted file mode 100644 index fd88aa993..000000000 --- a/solutions/tests/test_harmonic_sequence.py +++ /dev/null @@ -1,102 +0,0 @@ -""" -Test module for harmonic_sequence function. - -Test categories: - - Standard cases: The input is a list of integers. - - Edge cases: The input is equal to 0 or 1. - - Defensive cases: wrong input types, assertions - -Created on 2024-12-30 -Author: Omnia Mustafa - Abdulgadir -""" - -import unittest - -from ..harmonic_sequence import harmonic_sequence - - -class TestHarmonicSequence(unittest.TestCase): - """ - This class, `TestHarmonicSequence`, contains a set of test cases for the `harmonic_sequence` function. The test cases cover various scenarios, including edge cases, standard cases, and defensive cases. - - The edge cases include: - - When all inputs are equal to 1 - - When `n` is equal to 0 - - When `a` and `d` are equal to 0 - - When `n` is negative - - When `a` and `d` are equal to 1 - - The standard cases include: - - When all inputs are integers and greater than 1 - - When `n` is large - - The defensive cases include: - - When the input `a` is not an integer - - When the input `d` is not an integer - - When the input `n` is not an integer - - These test cases ensure that the `harmonic_sequence` function - behaves as expected under various input conditions. - """ - - # Edge cases: - def test_min_input1(self): - """Test case when all inputs equal to 1""" - self.assertEqual(harmonic_sequence(1, 1, 1), [1.0]) - - def test_n_equal_0(self): - """Test case when n is equal to 0""" - self.assertEqual(harmonic_sequence(1, 1, 0), []) - - def test_a_and_d_equal_0(self): - """Test case when a and d are equal to 0""" - self.assertEqual(harmonic_sequence(0, 0, 5), [0, 0, 0, 0, 0]) - - def test_n_negative(self): - """Test case when n is negative""" - self.assertEqual(harmonic_sequence(1, 1, -1), []) - - def test_a_and_d_equal_1(self): - """Test a and d are equal 1""" - self.assertEqual( - harmonic_sequence(1, 1, 5), [1.0, 0.5, 0.3333333333333333, 0.25, 0.2] - ) - - # Standard cases: - def test_all_inputs_greater_than_1(self): - """Test when all inputs are integer and greater than 1""" - self.assertEqual(harmonic_sequence(2, 2, 3), [0.5, 0.25, 0.16666666666666666]) - - def test_n_is_large(self): - """Test when n is large""" - self.assertEqual( - harmonic_sequence(4, 3, 10), - [ - 0.25, - 0.14285714285714285, - 0.1, - 0.07692307692307693, - 0.0625, - 0.05263157894736842, - 0.045454545454545456, - 0.04, - 0.03571428571428571, - 0.03225806451612903, - ], - ) - - # Defensive cases: - def wrong_input_a_type(self): - """Test when input a is not integer""" - with self.assertRaises(AssertionError): - harmonic_sequence("1", 1, 1) - - def wrong_input_d_type(self): - """Test when input d is not integer""" - with self.assertRaises(AssertionError): - harmonic_sequence(5, "Omnia", 10) - - def wrong_input_n_type(self): - """Test when input n is not integer""" - with self.assertRaises(AssertionError): - harmonic_sequence(1, 1, [1, 2, 3]) From 9465177a0b494063111947e8a89e759d308ecf71 Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Tue, 31 Dec 2024 21:39:08 +0400 Subject: [PATCH 032/151] Delete unnessessory files --- solutions/quadratic_sequence.py | 14 -------------- solutions/tests/test_quadratic_sequence.py | 1 - 2 files changed, 15 deletions(-) delete mode 100644 solutions/quadratic_sequence.py delete mode 100644 solutions/tests/test_quadratic_sequence.py diff --git a/solutions/quadratic_sequence.py b/solutions/quadratic_sequence.py deleted file mode 100644 index c3ccf46b5..000000000 --- a/solutions/quadratic_sequence.py +++ /dev/null @@ -1,14 +0,0 @@ -def quadratic_sequence(a, b, c, n): - """ - The function creates quadratic sequence, based on formula: A(n): an^2 + bn + c - - Parameters: - a (int): Coefficient of n^2 - b (int): Coefficient of n - c (int): Constant term - n (int): Number of terms to generate - - Returns: - List: List containing the quadratic sequence - - """ diff --git a/solutions/tests/test_quadratic_sequence.py b/solutions/tests/test_quadratic_sequence.py deleted file mode 100644 index 72bf3e2c4..000000000 --- a/solutions/tests/test_quadratic_sequence.py +++ /dev/null @@ -1 +0,0 @@ -from ..quadratic_sequence import quadratic_sequence # noqa: F401 From 05ce776c6cc8f2cbb817647ad470915fd6823cb7 Mon Sep 17 00:00:00 2001 From: Mayar-Agab Date: Tue, 31 Dec 2024 19:46:27 +0200 Subject: [PATCH 033/151] Resolved some errors --- solutions/{even_number_count => even_number_count.py} | 0 solutions/tests/test_even_number_count.py | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename solutions/{even_number_count => even_number_count.py} (100%) diff --git a/solutions/even_number_count b/solutions/even_number_count.py similarity index 100% rename from solutions/even_number_count rename to solutions/even_number_count.py diff --git a/solutions/tests/test_even_number_count.py b/solutions/tests/test_even_number_count.py index 5d65f0a3c..f594365bd 100644 --- a/solutions/tests/test_even_number_count.py +++ b/solutions/tests/test_even_number_count.py @@ -43,8 +43,8 @@ def test_4(self): def test_5(self): """It should count the number of even numbers in a countdown from n to 1 """ - self.assertEqual(even_number_count([1,2,3,4,5,6]), [3]) + self.assertEqual(even_number_count([1,2,3,4,5,6]), 3) def test_6(self): """It should count the number of even numbers in a countdown from n to 1 """ - self.assertEqual(even_number_count([1,2,3,4,5,6,7]), [3]) \ No newline at end of file + self.assertEqual(even_number_count([1,2,3,4,5,6,7]), 3) \ No newline at end of file From 85fa602b62d847693e9b04fe66b1cf748b67143a Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Tue, 31 Dec 2024 21:49:13 +0400 Subject: [PATCH 034/151] Updating the document of the test --- solutions/quadratic_sequence.py | 9 +++++++++ solutions/tests/test_quadratic_sequence.py | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/solutions/quadratic_sequence.py b/solutions/quadratic_sequence.py index 1156f59cb..2dbdd69da 100644 --- a/solutions/quadratic_sequence.py +++ b/solutions/quadratic_sequence.py @@ -1,3 +1,12 @@ +""" +The function is create quadratic sequence based on formula: A(n): a*n^2 + b*n + c +given a,b,c and n are integers.And returns the list containing the quadratic sequence. + +Created on 2024-12-30 +Author: Omnia Mustafa - Abdulgadir +""" + + def quadratic_sequence(a, b, c, n): """ The function creates quadratic sequence, based on formula: A(n): a*n^2 + b*n + c diff --git a/solutions/tests/test_quadratic_sequence.py b/solutions/tests/test_quadratic_sequence.py index d7e45171b..1b91eebc5 100644 --- a/solutions/tests/test_quadratic_sequence.py +++ b/solutions/tests/test_quadratic_sequence.py @@ -16,6 +16,11 @@ class TestQuadraticSequence(unittest.TestCase): + """ + The class is testing the function quadratic_sequence + in different cases and inputs + """ + # Edge cases: def test_all_inputs_are_0(self): """Test case when all inputs equal to 0""" From 06a88558acd2405f50328a2cac46373af0ce8744 Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Tue, 31 Dec 2024 19:52:28 +0200 Subject: [PATCH 035/151] edits --- solutions/tests/test_word_count_from_file.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/solutions/tests/test_word_count_from_file.py b/solutions/tests/test_word_count_from_file.py index aabbae8b2..2069cf19e 100644 --- a/solutions/tests/test_word_count_from_file.py +++ b/solutions/tests/test_word_count_from_file.py @@ -1,25 +1,26 @@ import os import sys -import unittest - -# Add the project root directory to sys.path -project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) -sys.path.append(project_root) - -from solutions.word_count_from_file import word_count_txt_file """ -Counts the number of words in a .txt file +Counts the number of words in a .txt file. Parameters: file_name (str) - The name of the file -Returns -> The total number of words in the file +Returns -> The total number of words in the file. Raises: AssertionError """ +import unittest + +project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) +sys.path.append(project_root) + +from solutions.word_count_from_file import word_count_txt_file + + class TestWordCountFromFile(unittest.TestCase): """Test the words counting function""" From 7a11a1c7aabd566d429b93854f0c636edd7d6c32 Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Tue, 31 Dec 2024 19:56:51 +0200 Subject: [PATCH 036/151] edits for cl --- solutions/tests/test_word_count_from_file.py | 3 +-- solutions/word_count_from_file.py | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/solutions/tests/test_word_count_from_file.py b/solutions/tests/test_word_count_from_file.py index 2069cf19e..9843cf3a2 100644 --- a/solutions/tests/test_word_count_from_file.py +++ b/solutions/tests/test_word_count_from_file.py @@ -1,5 +1,6 @@ import os import sys +import unittest """ Counts the number of words in a .txt file. @@ -13,8 +14,6 @@ """ -import unittest - project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) sys.path.append(project_root) diff --git a/solutions/word_count_from_file.py b/solutions/word_count_from_file.py index 034c77a89..f43770fc3 100644 --- a/solutions/word_count_from_file.py +++ b/solutions/word_count_from_file.py @@ -1,3 +1,5 @@ +import os + """ A Module for counting the number of words in a .txt file @@ -9,8 +11,6 @@ @author: saja abusafia """ -import os - def word_count_txt_file(file_name) -> int: """ From b639bd10ab00f16b714c503f55490f38fb9f33f8 Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Tue, 31 Dec 2024 20:01:15 +0200 Subject: [PATCH 037/151] edits --- solutions/tests/test_word_count_from_file.py | 1 - 1 file changed, 1 deletion(-) diff --git a/solutions/tests/test_word_count_from_file.py b/solutions/tests/test_word_count_from_file.py index 9843cf3a2..5307ce618 100644 --- a/solutions/tests/test_word_count_from_file.py +++ b/solutions/tests/test_word_count_from_file.py @@ -13,7 +13,6 @@ Raises: AssertionError """ - project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) sys.path.append(project_root) From 6fc464dddb9fcaeace558656a74a2979518c931a Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Tue, 31 Dec 2024 20:10:06 +0200 Subject: [PATCH 038/151] for E402 Module level import not at top of file --- solutions/tests/test_word_count_from_file.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/solutions/tests/test_word_count_from_file.py b/solutions/tests/test_word_count_from_file.py index 5307ce618..7885dc1ed 100644 --- a/solutions/tests/test_word_count_from_file.py +++ b/solutions/tests/test_word_count_from_file.py @@ -2,6 +2,11 @@ import sys import unittest +project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) +sys.path.append(project_root) + +from solutions.word_count_from_file import word_count_txt_file + """ Counts the number of words in a .txt file. @@ -13,11 +18,6 @@ Raises: AssertionError """ -project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) -sys.path.append(project_root) - -from solutions.word_count_from_file import word_count_txt_file - class TestWordCountFromFile(unittest.TestCase): """Test the words counting function""" From ea985a148f3cebb89e79804bdec2ea203a7a2cc4 Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Tue, 31 Dec 2024 20:16:43 +0200 Subject: [PATCH 039/151] final commit --- solutions/tests/test_word_count_from_file.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/solutions/tests/test_word_count_from_file.py b/solutions/tests/test_word_count_from_file.py index 7885dc1ed..74b239564 100644 --- a/solutions/tests/test_word_count_from_file.py +++ b/solutions/tests/test_word_count_from_file.py @@ -1,12 +1,5 @@ -import os -import sys import unittest -project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) -sys.path.append(project_root) - -from solutions.word_count_from_file import word_count_txt_file - """ Counts the number of words in a .txt file. @@ -18,6 +11,8 @@ Raises: AssertionError """ +from ..solutions.word_count_from_file import word_count_txt_file + class TestWordCountFromFile(unittest.TestCase): """Test the words counting function""" From 49bc6717e5456b4e659350b4634303f1f8458f91 Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Tue, 31 Dec 2024 20:18:04 +0200 Subject: [PATCH 040/151] modified files for cl --- solutions/tests/test_word_count_from_file.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/tests/test_word_count_from_file.py b/solutions/tests/test_word_count_from_file.py index 74b239564..50fc142fa 100644 --- a/solutions/tests/test_word_count_from_file.py +++ b/solutions/tests/test_word_count_from_file.py @@ -11,7 +11,7 @@ Raises: AssertionError """ -from ..solutions.word_count_from_file import word_count_txt_file +from ..word_count_from_file import word_count_txt_file class TestWordCountFromFile(unittest.TestCase): From e283b78bd99a930e9c4b8b16d20d9a4afeac7f0b Mon Sep 17 00:00:00 2001 From: Goutbi Date: Tue, 31 Dec 2024 22:23:13 +0400 Subject: [PATCH 041/151] adding the code without the tests --- solutions/fuel_gauge.py | 13 +++++++++++++ solutions/tests/test_fuel_gauge.py | 3 +++ 2 files changed, 16 insertions(+) diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py index e69de29bb..ed67fc240 100644 --- a/solutions/fuel_gauge.py +++ b/solutions/fuel_gauge.py @@ -0,0 +1,13 @@ +def fuel_gauge(x, y): + """ + + """ + if y == 0 or x > y: + raise ValueError("Invalid input: y must be greater than 0 (tank size can't be zero) and x must be less than or equal to y(fuel can't be more than the tank capacity).") + + percentage = (x / y) * 100 + if percentage >= 99: + return 'F' + elif percentage <= 1: + return 'E' + return int(percentage) diff --git a/solutions/tests/test_fuel_gauge.py b/solutions/tests/test_fuel_gauge.py index e69de29bb..9cd4d2a9e 100644 --- a/solutions/tests/test_fuel_gauge.py +++ b/solutions/tests/test_fuel_gauge.py @@ -0,0 +1,3 @@ +import unittest +from ..fuel_gauge import fuel_gauge + From f6bb3af2fac5eade5edadfd004782fd75049cc7f Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Tue, 31 Dec 2024 20:44:31 +0200 Subject: [PATCH 042/151] final commit --- solutions/tests/test_word_count_from_file.py | 4 ++-- solutions/word_count_from_file.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/solutions/tests/test_word_count_from_file.py b/solutions/tests/test_word_count_from_file.py index 50fc142fa..ea3b6dac8 100644 --- a/solutions/tests/test_word_count_from_file.py +++ b/solutions/tests/test_word_count_from_file.py @@ -1,5 +1,7 @@ import unittest +from ..word_count_from_file import word_count_txt_file + """ Counts the number of words in a .txt file. @@ -11,8 +13,6 @@ Raises: AssertionError """ -from ..word_count_from_file import word_count_txt_file - class TestWordCountFromFile(unittest.TestCase): """Test the words counting function""" diff --git a/solutions/word_count_from_file.py b/solutions/word_count_from_file.py index f43770fc3..2953073dc 100644 --- a/solutions/word_count_from_file.py +++ b/solutions/word_count_from_file.py @@ -29,7 +29,8 @@ def word_count_txt_file(file_name) -> int: >>> word_count_txt_file("solutions/test_multiple.txt") 10 """ - assert os.path.exists(file_name), f"Error: The file '{file_name}' does not exist." + + assert os.path.exists(file_name), f"Error:file '{file_name}' doesn't exist" assert file_name.endswith( ".txt" ), f"Error: The file '{file_name}' does not have a .txt extension." From 8014440ef8dbdc20f2470a77412ae21e1ea0c25b Mon Sep 17 00:00:00 2001 From: Mayar-Agab Date: Tue, 31 Dec 2024 21:42:12 +0200 Subject: [PATCH 043/151] made changes on tests --- .vscode/settings.json | 9 ++-- solutions/arithmetic_sequence.py | 55 +++++++++++++++++++++ solutions/tests/test_arithmetic_sequence.py | 35 +++++++++++++ 3 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 solutions/arithmetic_sequence.py diff --git a/.vscode/settings.json b/.vscode/settings.json index bbda5188d..89cc035cc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -119,8 +119,11 @@ "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" } - } + }, + "cSpell.words": [ + "Mayar" + ] } diff --git a/solutions/arithmetic_sequence.py b/solutions/arithmetic_sequence.py new file mode 100644 index 000000000..c4abfd644 --- /dev/null +++ b/solutions/arithmetic_sequence.py @@ -0,0 +1,55 @@ + + +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for generating a sequence for arithmetic numbers + +Module contents: + - arithmetic_sequence:generating a sequence of n arithmetic numbers. + +Created on Sunday/22/December/2024 +@author:Mayar Ali +""" + +#---before documenting and testing--- + + +def arithmetic_sequence(sequence_length: int) -> list: + """ + Generates a list in which the difference between consecutive terms is constant. + Parameters: + sequence_length:int, greater than zero + +Returns -list[int] with the first n number of the arithmetic sequence + +Raises: + AssertionError : if the argument is not an integer + AssertionError : if the argument is less or equal to zero + + Examples: + >>>arithmetic_sequence(0) + [1] + >>>arithmetic_sequence(5) + [0 ,1 ,5 ,9 ,13] + >>>arithmetic_sequence(11) + [0 ,1 ,5 ,9 ,13 ,17 ,21 ,25 ,29 ,33 ,37 ] + """ + assert isinstance(sequence_length, int) + assert sequence_length >= 0 + + if sequence_length ==0: + return[] + if sequence_length ==1: + return[1] + if sequence_length ==2: + return[0, 1] + sequence = [0, 1] + while len(sequence) < sequence_length: + sequence.append(sequence[-1] + 3) + + return sequence + +if __name__ == "__main__": + + print(arithmetic_sequence(10)) diff --git a/solutions/tests/test_arithmetic_sequence.py b/solutions/tests/test_arithmetic_sequence.py index e69de29bb..d0b113fd5 100644 --- a/solutions/tests/test_arithmetic_sequence.py +++ b/solutions/tests/test_arithmetic_sequence.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Monday/30/December/2024 +@author:Mayar Ali +""" +import unittest + +#---imports & test class before documenting and testing--- +# from ..arithmetic_sequence import arithmetic_sequence +# class TestArithmeticSequence(unittest.TestCase): +#---imports & test class after documenting and testing--- + +from ..arithmetic_sequence import arithmetic_sequence + +class TestArithmeticSequence(unittest.TestCase): + """Test the arithmetic_sequence function""" + + def test_0(self): + "It should evaluate 0 to []" + self.assertEqual(arithmetic_sequence(0), []) + + def test_1(self): + "Should evaluate 1 to [0]" + self.assertEqual(arithmetic_sequence(1), [1]) + + def test_2(self): + "Should evaluate 2 to [0,1]" + self.assertEqual(arithmetic_sequence(2) ,[0,1]) + + def test_3(self): + "Should evaluate 3 to [0, 1, 5]" + self.assertEqual(arithmetic_sequence(3) ,[0, 1, 4]) + + From da575ecb09e773d5cbd6576a8ade2bc9354f91ed Mon Sep 17 00:00:00 2001 From: ayhm01 Date: Tue, 31 Dec 2024 21:57:06 +0200 Subject: [PATCH 044/151] Added Empty File --- solutions/substitution_cipher.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/substitution_cipher.py diff --git a/solutions/substitution_cipher.py b/solutions/substitution_cipher.py new file mode 100644 index 000000000..e69de29bb From 2bc4f49413ad90180f65e674ebf3f6fd1aea1f5d Mon Sep 17 00:00:00 2001 From: Mayar-Agab Date: Tue, 31 Dec 2024 22:28:46 +0200 Subject: [PATCH 045/151] Added defensive cases --- solutions/tests/test_arithmetic_sequence.py | 22 ++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/solutions/tests/test_arithmetic_sequence.py b/solutions/tests/test_arithmetic_sequence.py index d0b113fd5..ee3b9ba1c 100644 --- a/solutions/tests/test_arithmetic_sequence.py +++ b/solutions/tests/test_arithmetic_sequence.py @@ -32,4 +32,24 @@ def test_3(self): "Should evaluate 3 to [0, 1, 5]" self.assertEqual(arithmetic_sequence(3) ,[0, 1, 4]) - +#defensive cases + + def test_0_less_than_0(self): + """It should raise an assertion error if the argument is less than 0""" + with self.assertRaises(AssertionError): + arithmetic_sequence(-1) + + def test_1_not_an_integer(self): + """It should raise an assertion error if the argument is not an integer""" + with self.assertRaises(AssertionError): + arithmetic_sequence(1.0) + + def test_2_not_an_integer(self): + """It should raise an assertion error if the argument is not an integer""" + with self.assertRaises(AssertionError): + arithmetic_sequence([1 ,2 ,3]) + + def test_3_not_an_integer(self): + """It should raise an assertion error if the argument is not an integer""" + with self.assertRaises(AssertionError): + arithmetic_sequence(["1" ,2 ,3]) From 01ceeee11d5b1bd21f753fe257877295ddd8cf24 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Wed, 1 Jan 2025 06:11:28 +0400 Subject: [PATCH 046/151] unittest added --- solutions/fuel_gauge.py | 14 ++++++------ solutions/tests/test_fuel_gauge.py | 34 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py index ed67fc240..5153aa255 100644 --- a/solutions/fuel_gauge.py +++ b/solutions/fuel_gauge.py @@ -1,13 +1,13 @@ def fuel_gauge(x, y): - """ - - """ + """ """ if y == 0 or x > y: - raise ValueError("Invalid input: y must be greater than 0 (tank size can't be zero) and x must be less than or equal to y(fuel can't be more than the tank capacity).") - + raise ValueError( + "Invalid input: y must be greater than 0 (tank size can't be zero) and x must be less than or equal to y(fuel can't be more than the tank capacity)." + ) + percentage = (x / y) * 100 if percentage >= 99: - return 'F' + return "F" elif percentage <= 1: - return 'E' + return "E" return int(percentage) diff --git a/solutions/tests/test_fuel_gauge.py b/solutions/tests/test_fuel_gauge.py index 9cd4d2a9e..446928b24 100644 --- a/solutions/tests/test_fuel_gauge.py +++ b/solutions/tests/test_fuel_gauge.py @@ -1,3 +1,37 @@ import unittest + from ..fuel_gauge import fuel_gauge + +class TestFuelGauge(unittest.TestCase): + """Test cases for the fuel_gauge function.""" + + def test_full(self): + """Test cases where the percentage is 99% or more.""" + self.assertEqual(fuel_gauge(99, 100), "F") + self.assertEqual(fuel_gauge(100, 100), "F") + + def test_empty(self): + """Test cases where the percentage is 1% or less.""" + self.assertEqual(fuel_gauge(1, 100), "E") + self.assertEqual( + fuel_gauge( + 0, + 100, + ), + "E", + ) + + def test_percentage(self): + """Test cases where the result is a percentage.""" + self.assertEqual(fuel_gauge(50, 100), 50) + self.assertEqual(fuel_gauge(25, 50), 50) + + def test_invalid_input(self): + """Test cases for invalid inputs.""" + with self.assertRaises(ValueError): + fuel_gauge(3, 0) + with self.assertRaises(ValueError): + fuel_gauge(4, 3) + with self.assertRaises(ValueError): + fuel_gauge("abc", "def") From 88ec7183d56a895554295facceed06ab3eba1540 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Wed, 1 Jan 2025 07:50:22 +0400 Subject: [PATCH 047/151] added unittests and comments --- solutions/fuel_gauge.py | 19 +++++++++++------ solutions/tests/test_fuel_gauge.py | 33 ++++++++++++------------------ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py index 5153aa255..551098ee9 100644 --- a/solutions/fuel_gauge.py +++ b/solutions/fuel_gauge.py @@ -1,13 +1,20 @@ def fuel_gauge(x, y): - """ """ + """ + This is a function that calculates the percentage of fuel in a tank. + + Parameters: + X= fuel in the tank (x value must be less than or equal to y) + Y= tank capacity (y value must be greater than 0)""" if y == 0 or x > y: - raise ValueError( - "Invalid input: y must be greater than 0 (tank size can't be zero) and x must be less than or equal to y(fuel can't be more than the tank capacity)." - ) + """This is a condition that checks if the tank size is zero or if the fuel is more than the tank capacity.""" + return "Invalid input" percentage = (x / y) * 100 - if percentage >= 99: + """This is a formula that calculates the percentage of fuel in the tank.""" + if percentage >= 90: return "F" - elif percentage <= 1: + elif percentage > 10: + return "M" + elif percentage <= 10: return "E" return int(percentage) diff --git a/solutions/tests/test_fuel_gauge.py b/solutions/tests/test_fuel_gauge.py index 446928b24..d1d8aed8a 100644 --- a/solutions/tests/test_fuel_gauge.py +++ b/solutions/tests/test_fuel_gauge.py @@ -7,31 +7,24 @@ class TestFuelGauge(unittest.TestCase): """Test cases for the fuel_gauge function.""" def test_full(self): - """Test cases where the percentage is 99% or more.""" - self.assertEqual(fuel_gauge(99, 100), "F") + """Test cases where the percentage is 90% or more it should result in F.""" + self.assertEqual(fuel_gauge(90, 100), "F") self.assertEqual(fuel_gauge(100, 100), "F") + self.assertEqual(fuel_gauge(97, 100), "F") def test_empty(self): - """Test cases where the percentage is 1% or less.""" - self.assertEqual(fuel_gauge(1, 100), "E") - self.assertEqual( - fuel_gauge( - 0, - 100, - ), - "E", - ) + """Test cases where the percentage is 10% or less it should result E.""" + self.assertEqual(fuel_gauge(10, 100), "E") + self.assertEqual(fuel_gauge(0, 100), "E") + self.assertEqual(fuel_gauge(2, 100), "E") def test_percentage(self): - """Test cases where the result is a percentage.""" - self.assertEqual(fuel_gauge(50, 100), 50) - self.assertEqual(fuel_gauge(25, 50), 50) + """Test cases where the result is between 90 and 10 it should be M.""" + self.assertEqual(fuel_gauge(71, 100), "M") + self.assertEqual(fuel_gauge(23, 100), "M") + self.assertEqual(fuel_gauge(10, 50), "M") def test_invalid_input(self): """Test cases for invalid inputs.""" - with self.assertRaises(ValueError): - fuel_gauge(3, 0) - with self.assertRaises(ValueError): - fuel_gauge(4, 3) - with self.assertRaises(ValueError): - fuel_gauge("abc", "def") + self.assertEqual(fuel_gauge(6, 0), "Invalid input") + self.assertEqual(fuel_gauge(7, -1), "Invalid input") From c75eb4a6132a11d7f699699b10b47dff4eff4a19 Mon Sep 17 00:00:00 2001 From: Mayar-Agab Date: Wed, 1 Jan 2025 17:47:03 +0200 Subject: [PATCH 048/151] added edge case --- solutions/tests/test_arithmetic_sequence.py | 114 +++++++++++++++++++- 1 file changed, 113 insertions(+), 1 deletion(-) diff --git a/solutions/tests/test_arithmetic_sequence.py b/solutions/tests/test_arithmetic_sequence.py index ee3b9ba1c..ab01b8bd4 100644 --- a/solutions/tests/test_arithmetic_sequence.py +++ b/solutions/tests/test_arithmetic_sequence.py @@ -11,7 +11,7 @@ # class TestArithmeticSequence(unittest.TestCase): #---imports & test class after documenting and testing--- -from ..arithmetic_sequence import arithmetic_sequence +from..arithmetic_sequence import arithmetic_sequence class TestArithmeticSequence(unittest.TestCase): """Test the arithmetic_sequence function""" @@ -53,3 +53,115 @@ def test_3_not_an_integer(self): """It should raise an assertion error if the argument is not an integer""" with self.assertRaises(AssertionError): arithmetic_sequence(["1" ,2 ,3]) + +#Edge case + + def test_a_big_number(self): + "Should evaluate 100 to [0, 1, 5]" + self.assertEqual( + arithmetic_sequence(100) , + [ + 0, + 1, + 4, + 7, + 10, + 13, + 16, + 19, + 22, + 25, + 28, + 31, + 34, + 37, + 40, + 43, + 46, + 49, + 52, + 55, + 58, + 61, + 64, + 67, + 70, + 73, + 76, + 79, + 82, + 85, + 88, + 91, + 94, + 97, + 100, + 103, + 106, + 109, + 112, + 115, + 118, + 121, + 124, + 127, + 130, + 133, + 136, + 139, + 142, + 145, + 148, + 151, + 154, + 157, + 160, + 163, + 166, + 169, + 172, + 175, + 178, + 181, + 184, + 187, + 190, + 193, + 196, + 199, + 202, + 205, + 208, + 211, + 214, + 217, + 220, + 223, + 226, + 229, + 232, + 235, + 238, + 241, + 244, + 247, + 250, + 253, + 256, + 259, + 262, + 265, + 268, + 271, + 274, + 277, + 280, + 283, + 286, + 289, + 292, + 295, + ] + ) + + From 81a399b2f346b9659a6af8dd587cdb0f26e22608 Mon Sep 17 00:00:00 2001 From: ayhm01 Date: Wed, 1 Jan 2025 18:14:36 +0200 Subject: [PATCH 049/151] added substitution cipher --- solutions/substitution_cipher.py | 61 ++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/solutions/substitution_cipher.py b/solutions/substitution_cipher.py index e69de29bb..3f742a1ca 100644 --- a/solutions/substitution_cipher.py +++ b/solutions/substitution_cipher.py @@ -0,0 +1,61 @@ +""" +Substitution Cipher +this code provides a function to encrypt text using a caesar cipher, +shifting lower and uppercase letter by a fixed value of 3 (as per the challenge) +""" + +# Author: AYHAM + +import string + + +def cipher(text: str) -> str: + """ + Parameters: + text (str): The text to be encrypted. + + Returns: + str: The encrypted text. + + >>> cipher("abc") + 'def' + >>> cipher("omnia") + 'rpqld' + >>> cipher("Hello!") + 'Khoor!' + """ + shift_value = 3 + + # Validate that the input is a string. + if not isinstance(text, str): + raise ValueError("Input text must be a string.") + + # Define lowercase and uppercase alphabets for shifting. + alphabets = [string.ascii_lowercase, string.ascii_uppercase] + + def shift_alphabet(alphabet: str) -> str: + return alphabet[shift_value:] + alphabet[:shift_value] + + # Generate shifted versions of the alphabets. + shifted_alphabets = tuple(map(shift_alphabet, alphabets)) + + # Combine original and shifted alphabets into strings for translation. + final_alphabet = "".join(alphabets) + final_shifted_alphabet = "".join(shifted_alphabets) + + # Create a translation table to map characters to their shifted counterparts. + table = str.maketrans(final_alphabet, final_shifted_alphabet) + return text.translate(table) + + +if __name__ == "__main__": + # Prompt the user for input text. + plain_text = input("Enter a word: ").strip() + + # Reprompt the user if the input is empty. + while not plain_text: + print("Input cannot be empty. Please enter a valid word.") + plain_text = input("Enter a word: ").strip() + + # Encrypt the input text and display the result. + print(f"Encrypted word: {cipher(plain_text)}") From 9ab033b10ae3ec7fb18c306bedeafcb6c9a4e111 Mon Sep 17 00:00:00 2001 From: RAFAA ALI Date: Wed, 1 Jan 2025 21:08:17 +0400 Subject: [PATCH 050/151] FooBar code --- .vscode/settings.json | 4 ++-- solutions/FooBar_code.py | 13 +++++++++++++ solutions/tests/test_FooBar_code.py | 10 ++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 solutions/FooBar_code.py create mode 100644 solutions/tests/test_FooBar_code.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/FooBar_code.py b/solutions/FooBar_code.py new file mode 100644 index 000000000..6d5c7595a --- /dev/null +++ b/solutions/FooBar_code.py @@ -0,0 +1,13 @@ +def FooBar_code(n: int): + assert isinstance(n, int), "N must be integer" + result = [] + for i in range(1, n + 1): + if i % 4 == 0 and i % 6 == 0: + result.append("FooBar") + elif i % 4 == 0: + result.append("foo") + elif i % 6 == 0: + result.append("Bar") + else: + result.append(i) + return result diff --git a/solutions/tests/test_FooBar_code.py b/solutions/tests/test_FooBar_code.py new file mode 100644 index 000000000..21d045247 --- /dev/null +++ b/solutions/tests/test_FooBar_code.py @@ -0,0 +1,10 @@ +import unittest + +from ..FooBar_code import FooBar_code + + +class TestFooBar(unittest.TestCase): + def test_int(self): + self.assertEqual( + FooBar_code(12), [1, 2, 3, "foo", 5, "Bar", 7, "foo", 9, 10, 11, "FooBar"] + ) From 5d5e16fca217411d6528de5a796461a06912989c Mon Sep 17 00:00:00 2001 From: Mayar-Agab Date: Wed, 1 Jan 2025 19:43:38 +0200 Subject: [PATCH 051/151] Extre changed and CI checks --- solutions/__init__.py | 1 - solutions/arithmetic_sequence.py | 64 ++++++++++----------- solutions/tests/__init__.py | 1 - solutions/tests/test_arithmetic_sequence.py | 38 ++++++------ 4 files changed, 47 insertions(+), 57 deletions(-) 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/arithmetic_sequence.py b/solutions/arithmetic_sequence.py index c4abfd644..fbab5c1fc 100644 --- a/solutions/arithmetic_sequence.py +++ b/solutions/arithmetic_sequence.py @@ -1,55 +1,53 @@ - - #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ A module for generating a sequence for arithmetic numbers -Module contents: +Module contents: - arithmetic_sequence:generating a sequence of n arithmetic numbers. Created on Sunday/22/December/2024 @author:Mayar Ali """ -#---before documenting and testing--- +# ---before documenting and testing--- def arithmetic_sequence(sequence_length: int) -> list: - """ - Generates a list in which the difference between consecutive terms is constant. - Parameters: - sequence_length:int, greater than zero - -Returns -list[int] with the first n number of the arithmetic sequence - -Raises: - AssertionError : if the argument is not an integer - AssertionError : if the argument is less or equal to zero - - Examples: - >>>arithmetic_sequence(0) - [1] - >>>arithmetic_sequence(5) - [0 ,1 ,5 ,9 ,13] - >>>arithmetic_sequence(11) - [0 ,1 ,5 ,9 ,13 ,17 ,21 ,25 ,29 ,33 ,37 ] + """ + list in which the difference between consecutive terms is constant. + Parameters: + sequence_length:int, greater than zero + + Returns -list[int] with the first n number of the arithmetic sequence + + Raises: + AssertionError : if the argument is not an integer + AssertionError : if the argument is less or equal to zero + + Examples: + >>>arithmetic_sequence(0) + [1] + >>>arithmetic_sequence(5) + [0 ,1 ,5 ,9 ,13] + >>>arithmetic_sequence(11) + [0 ,1 ,5 ,9 ,13 ,17 ,21 ,25 ,29 ,33 ,37 ] """ assert isinstance(sequence_length, int) assert sequence_length >= 0 - - if sequence_length ==0: - return[] - if sequence_length ==1: - return[1] - if sequence_length ==2: - return[0, 1] + + if sequence_length == 0: + return [] + if sequence_length == 1: + return [1] + if sequence_length == 2: + return [0, 1] sequence = [0, 1] while len(sequence) < sequence_length: - sequence.append(sequence[-1] + 3) - + sequence.append(sequence[-1] + 3) + return sequence + if __name__ == "__main__": - - print(arithmetic_sequence(10)) + print(arithmetic_sequence(20)) diff --git a/solutions/tests/__init__.py b/solutions/tests/__init__.py index 8b1378917..e69de29bb 100644 --- a/solutions/tests/__init__.py +++ b/solutions/tests/__init__.py @@ -1 +0,0 @@ - diff --git a/solutions/tests/test_arithmetic_sequence.py b/solutions/tests/test_arithmetic_sequence.py index ab01b8bd4..f1b305569 100644 --- a/solutions/tests/test_arithmetic_sequence.py +++ b/solutions/tests/test_arithmetic_sequence.py @@ -4,18 +4,19 @@ Created on Monday/30/December/2024 @author:Mayar Ali """ + import unittest -#---imports & test class before documenting and testing--- +# ---imports & test class before documenting and testing--- # from ..arithmetic_sequence import arithmetic_sequence # class TestArithmeticSequence(unittest.TestCase): -#---imports & test class after documenting and testing--- +# ---imports & test class after documenting and testing--- + +from ..arithmetic_sequence import arithmetic_sequence -from..arithmetic_sequence import arithmetic_sequence class TestArithmeticSequence(unittest.TestCase): """Test the arithmetic_sequence function""" - def test_0(self): "It should evaluate 0 to []" self.assertEqual(arithmetic_sequence(0), []) @@ -26,13 +27,13 @@ def test_1(self): def test_2(self): "Should evaluate 2 to [0,1]" - self.assertEqual(arithmetic_sequence(2) ,[0,1]) + self.assertEqual(arithmetic_sequence(2), [0, 1]) def test_3(self): "Should evaluate 3 to [0, 1, 5]" - self.assertEqual(arithmetic_sequence(3) ,[0, 1, 4]) + self.assertEqual(arithmetic_sequence(3), [0, 1, 4]) -#defensive cases + # defensive cases def test_0_less_than_0(self): """It should raise an assertion error if the argument is less than 0""" @@ -40,26 +41,21 @@ def test_0_less_than_0(self): arithmetic_sequence(-1) def test_1_not_an_integer(self): - """It should raise an assertion error if the argument is not an integer""" + """Should raise an assertion error if the argument is not an integer""" with self.assertRaises(AssertionError): - arithmetic_sequence(1.0) + arithmetic_sequence(1.0) def test_2_not_an_integer(self): - """It should raise an assertion error if the argument is not an integer""" - with self.assertRaises(AssertionError): - arithmetic_sequence([1 ,2 ,3]) - - def test_3_not_an_integer(self): - """It should raise an assertion error if the argument is not an integer""" + """Should raise an assertion error if the argument is not an integer""" with self.assertRaises(AssertionError): - arithmetic_sequence(["1" ,2 ,3]) + arithmetic_sequence(["1", 2, 3]) -#Edge case + # Edge case def test_a_big_number(self): "Should evaluate 100 to [0, 1, 5]" self.assertEqual( - arithmetic_sequence(100) , + arithmetic_sequence(100), [ 0, 1, @@ -161,7 +157,5 @@ def test_a_big_number(self): 289, 292, 295, - ] - ) - - + ], + ) From 6d777201ff3799a60fee8972f5fb178d78e23d06 Mon Sep 17 00:00:00 2001 From: Mayar-Agab Date: Wed, 1 Jan 2025 20:07:33 +0200 Subject: [PATCH 052/151] changed documentation --- solutions/tests/test_arithmetic_sequence.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/solutions/tests/test_arithmetic_sequence.py b/solutions/tests/test_arithmetic_sequence.py index f1b305569..026e2392c 100644 --- a/solutions/tests/test_arithmetic_sequence.py +++ b/solutions/tests/test_arithmetic_sequence.py @@ -17,6 +17,7 @@ class TestArithmeticSequence(unittest.TestCase): """Test the arithmetic_sequence function""" + def test_0(self): "It should evaluate 0 to []" self.assertEqual(arithmetic_sequence(0), []) @@ -41,7 +42,7 @@ def test_0_less_than_0(self): arithmetic_sequence(-1) def test_1_not_an_integer(self): - """Should raise an assertion error if the argument is not an integer""" + """Should raise an assertion error if the argument is a float""" with self.assertRaises(AssertionError): arithmetic_sequence(1.0) From 185b27979a83c135d291044fc4cbf071bb844452 Mon Sep 17 00:00:00 2001 From: Mayar-Agab Date: Wed, 1 Jan 2025 21:06:51 +0200 Subject: [PATCH 053/151] CI Checks --- solutions/__init__.py | 1 - solutions/even_number_count.py | 25 +-- solutions/tests/__init__.py | 1 - solutions/tests/test_even_number_count.py | 254 ++++++++++++++++++++-- 4 files changed, 251 insertions(+), 30 deletions(-) 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/even_number_count.py b/solutions/even_number_count.py index 63ea6c592..4f076d41c 100644 --- a/solutions/even_number_count.py +++ b/solutions/even_number_count.py @@ -4,23 +4,24 @@ A function that counts the number of even numbers in a countdown from n to 1 Module contents: - - even_number_count: generates a number for the amount of even numbers in the list. + - even_number_count: gen number for even numbers in the list. Created on Monday/ 30/ December/ 2024 @author: Mayar Ali. """ + def even_number_count(number: list) -> int: """Returns the number of even numbers on the list. Parameters: - int: list, the input list to process + int: list, the input list to process return - > int: indicating the number of even number in the list Raises: - AssertionError: - + AssertionError: + Examples: >>> even_number_count ([1]) 0 @@ -29,19 +30,17 @@ def even_number_count(number: list) -> int: >>> even_number_count ([3,2,1]) 1 """ - assert isinstance(number,list) + assert isinstance(number, list) for num in number: - assert isinstance(num,int) - + assert isinstance(num, int) + count = 0 for num in number: - if num % 2 ==0: - count +=1 + if num % 2 == 0: + count += 1 return count -if __name__ == "__main__": - - print(even_number_count([1,2,3,4,5])) - +if __name__ == "__main__": + print(even_number_count([1, 2, 3, 4, 5])) diff --git a/solutions/tests/__init__.py b/solutions/tests/__init__.py index 8b1378917..e69de29bb 100644 --- a/solutions/tests/__init__.py +++ b/solutions/tests/__init__.py @@ -1 +0,0 @@ - diff --git a/solutions/tests/test_even_number_count.py b/solutions/tests/test_even_number_count.py index f594365bd..303ee6a07 100644 --- a/solutions/tests/test_even_number_count.py +++ b/solutions/tests/test_even_number_count.py @@ -16,35 +16,259 @@ # --- imports & test class after documenting and testing --- -from ..even_number_count import even_number_count # type: ignore +from ..even_number_count import even_number_count # type: ignore + class TestEvenNumberCount(unittest.TestCase): - """test the even_number_count function """ + """test the even_number_count function""" def test_0(self): """It should return zero""" self.assertEqual(even_number_count([1]), 0) def test_1(self): - """It should count the number of even numbers in a countdown from n to 1 """ - self.assertEqual(even_number_count([1,2]), 1) + """Count the number of even numbers in a countdown from n to 1""" + self.assertEqual(even_number_count([1, 2]), 1) def test_2(self): - """It should count the number of even numbers in a countdown from n to 1 """ - self.assertEqual(even_number_count([1,2,3]), 1) + """Count the number of even numbers in a countdown from n to 1""" + self.assertEqual(even_number_count([1, 2, 3]), 1) def test_3(self): - """It should count the number of even numbers in a countdown from n to 1 """ - self.assertEqual(even_number_count([1,2,3,4]), 2) - + """Count the number of even numbers in a countdown from n to 1""" + self.assertEqual(even_number_count([1, 2, 3, 4]), 2) + def test_4(self): - """It should count the number of even numbers in a countdown from n to 1 """ - self.assertEqual(even_number_count([1,2,3,4,5]), 2) + """Count the number of even numbers in a countdown from n to 1""" + self.assertEqual(even_number_count([1, 2, 3, 4, 5]), 2) def test_5(self): - """It should count the number of even numbers in a countdown from n to 1 """ - self.assertEqual(even_number_count([1,2,3,4,5,6]), 3) + """Count the number of even numbers in a countdown from n to 1""" + self.assertEqual(even_number_count([1, 2, 3, 4, 5, 6]), 3) def test_6(self): - """It should count the number of even numbers in a countdown from n to 1 """ - self.assertEqual(even_number_count([1,2,3,4,5,6,7]), 3) \ No newline at end of file + """Count the number of even numbers in a countdown from n to 1""" + self.assertEqual(even_number_count([1, 2, 3, 4, 5, 6, 7]), 3) + + # Boundary case + + def test_big_numbers(self): + """it should evaluate 100 to [1,2,3,4,5,...]""" + self.assertEqual( + even_number_count( + [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + ] + ), + 99, + ) + + # Defensive cases + + def test_0_less_than_0(self): + """Raise an assertion error if the there is a string within a list""" + with self.assertRaises(AssertionError): + (even_number_count([1, 2, "-6", 4]),) + + def test_0_less_than_1(self): + """Raise an assertion error if the there is a list within a list""" + with self.assertRaises(AssertionError): + even_number_count([1, 2, [1, 2, 3], 4]) From a7aed16869ab47a9e44ab4cf1055d4618497b3c6 Mon Sep 17 00:00:00 2001 From: ayhm01 Date: Wed, 1 Jan 2025 21:09:31 +0200 Subject: [PATCH 054/151] Added unit tests for substitution cipher --- solutions/tests/test_substitution_cipher.py | 37 +++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 solutions/tests/test_substitution_cipher.py diff --git a/solutions/tests/test_substitution_cipher.py b/solutions/tests/test_substitution_cipher.py new file mode 100644 index 000000000..ab3198fb1 --- /dev/null +++ b/solutions/tests/test_substitution_cipher.py @@ -0,0 +1,37 @@ +import unittest + +from solutions.substitution_cipher import cipher + + +class TestCipher(unittest.TestCase): + """ + testing cipher function + """ + + def test_lowercase(self): + """ + testing lower case encryption + """ + self.assertEqual(cipher("abc"), "def") + + def test_mixed_cases(self): + """ + testing lower and upper case mixed letters + """ + self.assertEqual(cipher("AbCd"), "DeFg") + + def test_edge_cases(self): + """ + testing edge cases such as reaching the end of the alphabets + """ + self.assertEqual(cipher("xyz"), "abc") + + def test_invalid_chars(self): + """ + testing that ivalid chars remain unchanged when mixed with alphabets + """ + self.assertEqual(cipher("Hello@123!"), "Khoor@123!") + + +if __name__ == "__main__": + unittest.main() From 5bd9e005d52a6d32d1c572cee166150577d2b75a Mon Sep 17 00:00:00 2001 From: Mayar-Agab Date: Wed, 1 Jan 2025 22:48:41 +0200 Subject: [PATCH 055/151] added --- solutions/tests/test_arithmetic_sequence.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/solutions/tests/test_arithmetic_sequence.py b/solutions/tests/test_arithmetic_sequence.py index 026e2392c..9d5cd19d5 100644 --- a/solutions/tests/test_arithmetic_sequence.py +++ b/solutions/tests/test_arithmetic_sequence.py @@ -56,7 +56,7 @@ def test_2_not_an_integer(self): def test_a_big_number(self): "Should evaluate 100 to [0, 1, 5]" self.assertEqual( - arithmetic_sequence(100), + arithmetic_sequence(101), [ 0, 1, @@ -158,5 +158,6 @@ def test_a_big_number(self): 289, 292, 295, + 298 ], ) From b75c05a602bd53a5de0b47a3e33f8eb1671831da Mon Sep 17 00:00:00 2001 From: Mayar-Agab Date: Wed, 1 Jan 2025 22:55:00 +0200 Subject: [PATCH 056/151] extended example --- solutions/tests/test_arithmetic_sequence.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/solutions/tests/test_arithmetic_sequence.py b/solutions/tests/test_arithmetic_sequence.py index 9d5cd19d5..5fe1172a3 100644 --- a/solutions/tests/test_arithmetic_sequence.py +++ b/solutions/tests/test_arithmetic_sequence.py @@ -56,7 +56,7 @@ def test_2_not_an_integer(self): def test_a_big_number(self): "Should evaluate 100 to [0, 1, 5]" self.assertEqual( - arithmetic_sequence(101), + arithmetic_sequence(102), [ 0, 1, @@ -158,6 +158,7 @@ def test_a_big_number(self): 289, 292, 295, - 298 + 298, + 301, ], ) From 37474b28bbc81be4dc827e316cafd12a96491615 Mon Sep 17 00:00:00 2001 From: Safi222 Date: Thu, 2 Jan 2025 03:37:12 +0300 Subject: [PATCH 057/151] problem setup --- solutions/LowestCommonAncestor_in_BST.py | 44 +++++++++++++++++ .../tests/test_LowestCommonAncestor_in_BST.py | 48 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 solutions/LowestCommonAncestor_in_BST.py create mode 100644 solutions/tests/test_LowestCommonAncestor_in_BST.py diff --git a/solutions/LowestCommonAncestor_in_BST.py b/solutions/LowestCommonAncestor_in_BST.py new file mode 100644 index 000000000..6abf16368 --- /dev/null +++ b/solutions/LowestCommonAncestor_in_BST.py @@ -0,0 +1,44 @@ +class TreeNode: + """Define class for TreeNode""" + + def __init__(self, value=0, left=None, right=None): + self.value = value + self.left = left + self.right = right + + +def lowestCommonAncestor(root: "TreeNode", p: "TreeNode", q: "TreeNode") -> "TreeNode": + """ + Finds the Lowest Common Ancestor (LCA) of two nodes in a Binary Search Tree. + + The Lowest Common Ancestor between two nodes p and q is the lowest node in the tree T + such that both p and q are descendants of the node. The ancestor is allowed to be a + descendant of itself. + + Args: + root (TreeNode): The root of the Binary Search Tree. + p (TreeNode): The first node in the BST. + q (TreeNode): The second node in the BST to find LCA with. + + Returns: + TreeNode: The Lowest Common Ancestor of nodes p and q. + + Examples: + Given the Binary Search Tree Structure: + 5 + / \ + 3 8 + / \ / \ + 1 4 7 9 + \ + 2 + + Example 1: + Input: root = [5,3,8,1,4,7,9,null,2], p = 3, q = 8 + Output: 5 + + Example 2: + Input: root = [5,3,8,1,4,7,9,null,2], p = 3, q = 4 + Output: 3 + """ + start = root diff --git a/solutions/tests/test_LowestCommonAncestor_in_BST.py b/solutions/tests/test_LowestCommonAncestor_in_BST.py new file mode 100644 index 000000000..cb535758d --- /dev/null +++ b/solutions/tests/test_LowestCommonAncestor_in_BST.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Test module for Lowest Common Ancestor in Binary search tree function. + +""" + +import unittest + + +class TreeNode: + """Define class for TreeNode""" + + def __init__(self, value=0, left=None, right=None): + self.value = value + self.left = left + self.right = right + + +class TestLowestCommonAncestor(unittest.TestCase): + """Test the Lowest common Ancestor in Binary search tree function + Binary Search Tree structure: + + 5 + / \ + 3 8 + / \ / \ + 1 4 7 9 + \ + 2 + + """ + + +def setUp_BTS(self): + "create Binary search tree from the example" + self.root = TreeNode(5) + self.root.left = TreeNode(3) + self.root.right = TreeNode(8) + self.root.left.left = TreeNode(1) + self.root.left.right = TreeNode(4) + self.root.right.left = TreeNode(7) + self.root.right.right = TreeNode(9) + self.root.left.left.right = TreeNode(2) + + +def test_case_1(self): + "This test case 1" From 09d0525e2ca9427ec27a8132d96809d7a0525ec9 Mon Sep 17 00:00:00 2001 From: Safi222 Date: Thu, 2 Jan 2025 03:37:12 +0300 Subject: [PATCH 058/151] Lowest Common Ancestor problem Setup --- solutions/LowestCommonAncestor_in_BST.py | 44 +++++++++++++++++ .../tests/test_LowestCommonAncestor_in_BST.py | 48 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 solutions/LowestCommonAncestor_in_BST.py create mode 100644 solutions/tests/test_LowestCommonAncestor_in_BST.py diff --git a/solutions/LowestCommonAncestor_in_BST.py b/solutions/LowestCommonAncestor_in_BST.py new file mode 100644 index 000000000..6abf16368 --- /dev/null +++ b/solutions/LowestCommonAncestor_in_BST.py @@ -0,0 +1,44 @@ +class TreeNode: + """Define class for TreeNode""" + + def __init__(self, value=0, left=None, right=None): + self.value = value + self.left = left + self.right = right + + +def lowestCommonAncestor(root: "TreeNode", p: "TreeNode", q: "TreeNode") -> "TreeNode": + """ + Finds the Lowest Common Ancestor (LCA) of two nodes in a Binary Search Tree. + + The Lowest Common Ancestor between two nodes p and q is the lowest node in the tree T + such that both p and q are descendants of the node. The ancestor is allowed to be a + descendant of itself. + + Args: + root (TreeNode): The root of the Binary Search Tree. + p (TreeNode): The first node in the BST. + q (TreeNode): The second node in the BST to find LCA with. + + Returns: + TreeNode: The Lowest Common Ancestor of nodes p and q. + + Examples: + Given the Binary Search Tree Structure: + 5 + / \ + 3 8 + / \ / \ + 1 4 7 9 + \ + 2 + + Example 1: + Input: root = [5,3,8,1,4,7,9,null,2], p = 3, q = 8 + Output: 5 + + Example 2: + Input: root = [5,3,8,1,4,7,9,null,2], p = 3, q = 4 + Output: 3 + """ + start = root diff --git a/solutions/tests/test_LowestCommonAncestor_in_BST.py b/solutions/tests/test_LowestCommonAncestor_in_BST.py new file mode 100644 index 000000000..cb535758d --- /dev/null +++ b/solutions/tests/test_LowestCommonAncestor_in_BST.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Test module for Lowest Common Ancestor in Binary search tree function. + +""" + +import unittest + + +class TreeNode: + """Define class for TreeNode""" + + def __init__(self, value=0, left=None, right=None): + self.value = value + self.left = left + self.right = right + + +class TestLowestCommonAncestor(unittest.TestCase): + """Test the Lowest common Ancestor in Binary search tree function + Binary Search Tree structure: + + 5 + / \ + 3 8 + / \ / \ + 1 4 7 9 + \ + 2 + + """ + + +def setUp_BTS(self): + "create Binary search tree from the example" + self.root = TreeNode(5) + self.root.left = TreeNode(3) + self.root.right = TreeNode(8) + self.root.left.left = TreeNode(1) + self.root.left.right = TreeNode(4) + self.root.right.left = TreeNode(7) + self.root.right.right = TreeNode(9) + self.root.left.left.right = TreeNode(2) + + +def test_case_1(self): + "This test case 1" From b86f0661db0fb3cf12bff981a4d355bd4f6609c6 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Thu, 2 Jan 2025 08:19:59 +0400 Subject: [PATCH 059/151] modified code and added doctests --- solutions/fuel_gauge.py | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py index 551098ee9..641d65345 100644 --- a/solutions/fuel_gauge.py +++ b/solutions/fuel_gauge.py @@ -1,20 +1,36 @@ -def fuel_gauge(x, y): +def fuel_gauge(x: int, y: int) -> str: """ - This is a function that calculates the percentage of fuel in a tank. + Calculates the percentage of fuel in a tank and returns a status indicator. Parameters: - X= fuel in the tank (x value must be less than or equal to y) - Y= tank capacity (y value must be greater than 0)""" + x (int): Fuel in the tank (must be ≤ y). + y (int): Tank capacity (must be > 0). + + Returns: + str: + - "F" if percentage >= 90. + - "E" if percentage <= 10. + - "M" for all other cases. + - "Invalid input" for invalid parameters. + + Raises: + AssertionError: If y <= 0 or x > y. + + Examples: + >>> fuel_gauge(90, 100) + 'F' + >>> fuel_gauge(10, 100) + 'E' + >>> fuel_gauge(50, 100) + 'M' + """ if y == 0 or x > y: - """This is a condition that checks if the tank size is zero or if the fuel is more than the tank capacity.""" return "Invalid input" percentage = (x / y) * 100 - """This is a formula that calculates the percentage of fuel in the tank.""" if percentage >= 90: return "F" - elif percentage > 10: - return "M" elif percentage <= 10: return "E" - return int(percentage) + else: + return "M" From 772978924a05b11667e9b2e2173fbbbbcc7fe3e5 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Thu, 2 Jan 2025 08:31:26 +0400 Subject: [PATCH 060/151] modified code and added doctests --- solutions/fuel_gauge.py | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py index 551098ee9..641d65345 100644 --- a/solutions/fuel_gauge.py +++ b/solutions/fuel_gauge.py @@ -1,20 +1,36 @@ -def fuel_gauge(x, y): +def fuel_gauge(x: int, y: int) -> str: """ - This is a function that calculates the percentage of fuel in a tank. + Calculates the percentage of fuel in a tank and returns a status indicator. Parameters: - X= fuel in the tank (x value must be less than or equal to y) - Y= tank capacity (y value must be greater than 0)""" + x (int): Fuel in the tank (must be ≤ y). + y (int): Tank capacity (must be > 0). + + Returns: + str: + - "F" if percentage >= 90. + - "E" if percentage <= 10. + - "M" for all other cases. + - "Invalid input" for invalid parameters. + + Raises: + AssertionError: If y <= 0 or x > y. + + Examples: + >>> fuel_gauge(90, 100) + 'F' + >>> fuel_gauge(10, 100) + 'E' + >>> fuel_gauge(50, 100) + 'M' + """ if y == 0 or x > y: - """This is a condition that checks if the tank size is zero or if the fuel is more than the tank capacity.""" return "Invalid input" percentage = (x / y) * 100 - """This is a formula that calculates the percentage of fuel in the tank.""" if percentage >= 90: return "F" - elif percentage > 10: - return "M" elif percentage <= 10: return "E" - return int(percentage) + else: + return "M" From 88712dd74cf1a3b02dc95b2e2010c4bf74d93259 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Thu, 2 Jan 2025 08:46:26 +0400 Subject: [PATCH 061/151] modified the code and added doctests --- solutions/fuel_gauge.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py index 641d65345..eb00a1f0d 100644 --- a/solutions/fuel_gauge.py +++ b/solutions/fuel_gauge.py @@ -4,7 +4,7 @@ def fuel_gauge(x: int, y: int) -> str: Parameters: x (int): Fuel in the tank (must be ≤ y). - y (int): Tank capacity (must be > 0). + y (int): Tank capacity (must be > 0, the tank can't be 0 or a negative value). Returns: str: From 2fb77a08dcd2c7832589f211e15f35cfa49c28d5 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Thu, 2 Jan 2025 09:11:04 +0400 Subject: [PATCH 062/151] modified the code --- solutions/fuel_gauge.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py index eb00a1f0d..553998c17 100644 --- a/solutions/fuel_gauge.py +++ b/solutions/fuel_gauge.py @@ -4,14 +4,14 @@ def fuel_gauge(x: int, y: int) -> str: Parameters: x (int): Fuel in the tank (must be ≤ y). - y (int): Tank capacity (must be > 0, the tank can't be 0 or a negative value). + y (int): Tank capacity (must be > 0, the tank can't be 0 or a negative number). Returns: str: - "F" if percentage >= 90. - "E" if percentage <= 10. - "M" for all other cases. - - "Invalid input" for invalid parameters. + - "Invalid input" for invalid inputs. Raises: AssertionError: If y <= 0 or x > y. From 60aafa60c5f2d32f8b82579c2e3dbd9cc1022c2e Mon Sep 17 00:00:00 2001 From: Goutbi Date: Thu, 2 Jan 2025 09:16:28 +0400 Subject: [PATCH 063/151] resolving python formatting -1 --- solutions/fuel_gauge.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py index 553998c17..a4dcac5da 100644 --- a/solutions/fuel_gauge.py +++ b/solutions/fuel_gauge.py @@ -4,7 +4,7 @@ def fuel_gauge(x: int, y: int) -> str: Parameters: x (int): Fuel in the tank (must be ≤ y). - y (int): Tank capacity (must be > 0, the tank can't be 0 or a negative number). + y (int): Tank capacity (must be > 0). Returns: str: From 6f5f69e7bfb2242a50bd30a8a1c3016ad6d94b5f Mon Sep 17 00:00:00 2001 From: Goutbi Date: Thu, 2 Jan 2025 09:26:35 +0400 Subject: [PATCH 064/151] fixing pyformatting -2 --- solutions/fuel_gauge.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py index a4dcac5da..fbc35ca08 100644 --- a/solutions/fuel_gauge.py +++ b/solutions/fuel_gauge.py @@ -1,3 +1,6 @@ +"""module calculates the percentage of fuel in a tank and returns a status indicator.""" + + def fuel_gauge(x: int, y: int) -> str: """ Calculates the percentage of fuel in a tank and returns a status indicator. @@ -7,7 +10,7 @@ def fuel_gauge(x: int, y: int) -> str: y (int): Tank capacity (must be > 0). Returns: - str: + str: - "F" if percentage >= 90. - "E" if percentage <= 10. - "M" for all other cases. From f27bfb783b02ec64fda22da821d0eb1d11ed3e79 Mon Sep 17 00:00:00 2001 From: RAFAA ALI Date: Thu, 2 Jan 2025 23:13:00 +0400 Subject: [PATCH 065/151] tests have been added --- solutions/FooBar_code.py | 51 ++++++++++++++++++++++++++ solutions/tests/test_FooBar_code.py | 55 ++++++++++++++++++++++++++++- 2 files changed, 105 insertions(+), 1 deletion(-) diff --git a/solutions/FooBar_code.py b/solutions/FooBar_code.py index 6d5c7595a..ee05eb825 100644 --- a/solutions/FooBar_code.py +++ b/solutions/FooBar_code.py @@ -1,4 +1,55 @@ +""" +Creates a sequence where numbers divisible by 4 return 'Foo', +numbers divisible by 6 return 'Bar', numbers divisible by both +return 'FooBar', and other numbers remain unchanged. + +Author: Rafaa Ali +Created date: 1.1.2025 +""" + + def FooBar_code(n: int): + """This function, `FooBar_code`, creates a sequence that replaces numbers + based on their divisibility by 4 and 6. + + Parameters: + n (int):the last number in the list + + Returns: + List containing the sequence with 'Foo', 'Bar', 'FooBar' or numbers + + assertion: + n must be integer otherwise error + + + example: + Edge cases: + >>> FooBar_code(1) + [1] + >>> FooBar_code(0) + [] + >>> FooBar_code(-1) + [] + + Standard cases: + >>> FooBar_code(8) + [1, 2, 3, 'Foo', 5, 'Bar', 7, 'Foo'] + >>> FooBar_code(12) + [1, 2, 3, 'Foo', 5, 'Bar', 7, 'Foo', 9, 10, 11, 'FooBar'] + >>> FooBar_code(16) + [1, 2, 3, 'Foo', 5, 'Bar', 7, 'Foo', 9, 10, 11, 'FooBar', + 13, 14, 15, 'Foo'] + + Defensive cases: + >>> FooBar_code("rafaa") + AssertionError: N must be integer + >>> FooBar_code(5.5) + AssertionError: N must be integer + >>> FooBar_code([1, 2, 3]) + AssertionError: N must be integer + + + """ assert isinstance(n, int), "N must be integer" result = [] for i in range(1, n + 1): diff --git a/solutions/tests/test_FooBar_code.py b/solutions/tests/test_FooBar_code.py index 21d045247..3b1f67331 100644 --- a/solutions/tests/test_FooBar_code.py +++ b/solutions/tests/test_FooBar_code.py @@ -4,7 +4,60 @@ class TestFooBar(unittest.TestCase): - def test_int(self): + # Edge cases: + def test_int1(self): + self.assertEqual(FooBar_code(1), [1]) + + def test_int0(self): + self.assertEqual(FooBar_code(0), []) + + def test_negative_int(self): + self.assertEqual(FooBar_code(-1), []) + + # Standard cases: + def test_int8(self): + self.assertEqual(FooBar_code(8), [1, 2, 3, "foo", 5, "Bar", 7, "foo"]) + + def test_int12(self): self.assertEqual( FooBar_code(12), [1, 2, 3, "foo", 5, "Bar", 7, "foo", 9, 10, 11, "FooBar"] ) + + def test_is_int(self): + self.assertEqual( + FooBar_code(16), + [ + 1, + 2, + 3, + "foo", + 5, + "Bar", + 7, + "foo", + 9, + 10, + 11, + "FooBar", + 13, + 14, + 15, + "foo", + ], + ) + + # defensive cases + def test_string_input(self): + """It should raise AssertionError for string input""" + with self.assertRaises(AssertionError): + FooBar_code("rafaa") + + def test_is_float_input(self): + """It should raise AssertionError for float input""" + with self.assertRaises(AssertionError): + FooBar_code(5.5) + + def test_is_list_input(self): + """It should raise AssertionError for list input""" + with self.assertRaises(AssertionError): + FooBar_code([1, 2, 3]) From e9a079eda98a6173387c72f67bf3575990b6d64e Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Thu, 2 Jan 2025 23:24:10 +0400 Subject: [PATCH 066/151] README.md: adding the edits of the readme file --- README.md | 75 ++++++++++++++++++++++++++++++++++ solutions/even_number_count.py | 47 +++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 solutions/even_number_count.py diff --git a/README.md b/README.md index e69de29bb..89fef71ca 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,75 @@ +# Collabor8 - MIT Emerging Talent ET6 Group 27 + +We are **Collabor8**, a team formed as part of the **MIT Emerging Talent program**. Our group consists of: + +- Omnia Mustafa *(Group Leader)* +- Ahmed Goutbi *(Vice Leader)* +- Ayham Hasan +- Mohamad Tilal +- Mayar Agab +- Reem Osama +- Safa Ishag +- Safia Gibril Nouman +- Saja Abu Safia +- Rafaa Ali + +We are collaborating on a GitHub project to enhance our understanding and application of version control while improving our programming skills. + + +## Project Overview +This project focuses on solving a selected set of problems while learning how to effectively use GitHub for version control. The selection process for these problems mimicked the **Secret Santa** game: + +1. We discussed each member's strengths and weaknesses, level of experience, and knowledge. +2. Based on this discussion, a list of problems was created, ensuring that each participant received two problems chosen by another member. + +### Learning Goals +- Gain hands-on experience with GitHub workflows. +- Collaborate effectively within a team. +- Improve programming skills through problem-solving and peer reviews. +- Provide constructive feedback on each other's code. + +More on Learning Goals in `collaberations/learning_goals.md` + + +## Workflow +Here is a step-by-step guide to our workflow: + +1. **Branch Creation**: Create a new branch named after your problem file. +2. **File Addition**: Add your problem file(s) to the branch. +3. **Issue Creation**: Create an issue for the problem and a corresponding card on the project board. +4. **Pull Request**: Once the problem is solved, add the solutions with corresponding test file as a commit, and create a pull request (PR) to merge your changes into the main branch. +5. **Card Update**: Update the card on the project board and mark it as "Ready for Review." +6. **Peer Review**: Another member will review your code and provide feedback. +7. **Merge**: After addressing any feedback, your PR can be merged into the main branch. + + +## Collaboration Tools +- **GitHub Project Board**: Tracks the progress of issues and pull requests. +- **Slack**: Main Communication tool +- **Google Meet**: Meetings three times a week, or according to requirements. +- **Collaboration Directory**: Contains additional details about: + - Collaboration process. + - Learning objectives. + - Meeting notes. + + +## Meetings and Sessions +We conducted several meetings and one dedicated session on GitHub usage. During these, we discussed: +- General GitHub commands. +- Best practices for our workflow. +- Troubleshooting common issues. + +Meetings times and agenda are discussed a few days before the date to schedule best time that suits the majority of the team. Voting is done through **Polly**, a third party service of Slack. + +For more information refer to `collaberations/communication.md` + + + +## Contact +For any questions or further information, please refer to the files in the collaboration directory or contact any group member. + +Happy collaborating! + +--- + +**MIT Emerging Talent ET6 Group 27 - Collabor8** diff --git a/solutions/even_number_count.py b/solutions/even_number_count.py new file mode 100644 index 000000000..63ea6c592 --- /dev/null +++ b/solutions/even_number_count.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A function that counts the number of even numbers in a countdown from n to 1 + +Module contents: + - even_number_count: generates a number for the amount of even numbers in the list. + +Created on Monday/ 30/ December/ 2024 +@author: Mayar Ali. +""" + +def even_number_count(number: list) -> int: + """Returns the number of even numbers on the list. + + Parameters: + int: list, the input list to process + + return - > int: indicating the number of even number in the list + + Raises: + AssertionError: + + Examples: + >>> even_number_count ([1]) + 0 + >>> even_number_count ([2,1]) + 1 + >>> even_number_count ([3,2,1]) + 1 + """ + assert isinstance(number,list) + for num in number: + assert isinstance(num,int) + + count = 0 + + for num in number: + if num % 2 ==0: + count +=1 + return count + +if __name__ == "__main__": + + print(even_number_count([1,2,3,4,5])) + + From 6775cf15bba8ea46fa7b5aa975775859d26812ce Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Thu, 2 Jan 2025 23:30:59 +0400 Subject: [PATCH 067/151] Adding the linting fixes --- README.md | 57 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 89fef71ca..39735afd6 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # Collabor8 - MIT Emerging Talent ET6 Group 27 -We are **Collabor8**, a team formed as part of the **MIT Emerging Talent program**. Our group consists of: +We are **Collabor8**, a team formed as part of the + **MIT Emerging Talent program**. Our group consists of: -- Omnia Mustafa *(Group Leader)* +- Omnia Mustafa *(Group Leader)* - Ahmed Goutbi *(Vice Leader)* - Ayham Hasan - Mohamad Tilal @@ -13,16 +14,22 @@ We are **Collabor8**, a team formed as part of the **MIT Emerging Talent program - Saja Abu Safia - Rafaa Ali -We are collaborating on a GitHub project to enhance our understanding and application of version control while improving our programming skills. - +We are collaborating on a GitHub project to enhance our understanding and +application of version control while improving our programming skills. ## Project Overview -This project focuses on solving a selected set of problems while learning how to effectively use GitHub for version control. The selection process for these problems mimicked the **Secret Santa** game: -1. We discussed each member's strengths and weaknesses, level of experience, and knowledge. -2. Based on this discussion, a list of problems was created, ensuring that each participant received two problems chosen by another member. +This project focuses on solving a selected set of problems while learning how +to effectively use GitHub for version control. The selection process for these +problems mimicked the **Secret Santa** game: + +1. We discussed each member's strengths and weaknesses, level of experience, and +knowledge. +2. Based on this discussion, a list of problems was created, ensuring that each +participant received two problems chosen by another member. ### Learning Goals + - Gain hands-on experience with GitHub workflows. - Collaborate effectively within a team. - Improve programming skills through problem-solving and peer reviews. @@ -30,20 +37,25 @@ This project focuses on solving a selected set of problems while learning how to More on Learning Goals in `collaberations/learning_goals.md` - ## Workflow + Here is a step-by-step guide to our workflow: 1. **Branch Creation**: Create a new branch named after your problem file. 2. **File Addition**: Add your problem file(s) to the branch. -3. **Issue Creation**: Create an issue for the problem and a corresponding card on the project board. -4. **Pull Request**: Once the problem is solved, add the solutions with corresponding test file as a commit, and create a pull request (PR) to merge your changes into the main branch. -5. **Card Update**: Update the card on the project board and mark it as "Ready for Review." +3. **Issue Creation**: Create an issue for the problem and a corresponding card +on the project board. +4. **Pull Request**: Once the problem is solved, add the solutions with +corresponding test file as a commit, and create a pull request (PR) to merge +your changes into the main branch. +5. **Card Update**: Update the card on the project board and mark it as "Ready +for Review." 6. **Peer Review**: Another member will review your code and provide feedback. -7. **Merge**: After addressing any feedback, your PR can be merged into the main branch. - +7. **Merge**: After addressing any feedback, your PR can be merged into the main +branch. ## Collaboration Tools + - **GitHub Project Board**: Tracks the progress of issues and pull requests. - **Slack**: Main Communication tool - **Google Meet**: Meetings three times a week, or according to requirements. @@ -52,24 +64,29 @@ Here is a step-by-step guide to our workflow: - Learning objectives. - Meeting notes. - ## Meetings and Sessions -We conducted several meetings and one dedicated session on GitHub usage. During these, we discussed: + +We conducted several meetings and one dedicated session on GitHub usage. During +these, we discussed: + - General GitHub commands. - Best practices for our workflow. - Troubleshooting common issues. -Meetings times and agenda are discussed a few days before the date to schedule best time that suits the majority of the team. Voting is done through **Polly**, a third party service of Slack. +Meetings times and agenda are discussed a few days before the date to schedule +best time that suits the majority of the team. Voting is done through **Polly**, +a third party service of Slack. For more information refer to `collaberations/communication.md` - - ## Contact -For any questions or further information, please refer to the files in the collaboration directory or contact any group member. + +For any questions or further information, please refer to the files in the +collaboration directory or contact any group member. Happy collaborating! --- - + **MIT Emerging Talent ET6 Group 27 - Collabor8** + From bb6b72aea6d3ab61937fe33613284dafa42cd7f8 Mon Sep 17 00:00:00 2001 From: RAFAA ALI Date: Thu, 2 Jan 2025 23:38:35 +0400 Subject: [PATCH 068/151] docstring has been added --- solutions/FooBar_code.py | 11 +++++++++++ solutions/tests/test_FooBar_code.py | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/solutions/FooBar_code.py b/solutions/FooBar_code.py index ee05eb825..d73611426 100644 --- a/solutions/FooBar_code.py +++ b/solutions/FooBar_code.py @@ -50,15 +50,26 @@ def FooBar_code(n: int): """ + # assert an error when n is not integer assert isinstance(n, int), "N must be integer" + # prepare empty list for the result result = [] + # loop for checking the sequence for i in range(1, n + 1): + # checking if the number is devisable by 4 and 6 if i % 4 == 0 and i % 6 == 0: + # add FooBar to the list if it devisable by both 4,6 result.append("FooBar") + # checking if the number is devisable by 4 elif i % 4 == 0: + # add Foo to the list if it devisable by 4 result.append("foo") + # checking if the number is devisable by 6 elif i % 6 == 0: + # add Bar to the list if it devisable by 6 result.append("Bar") + # otherwise add the number to the list else: result.append(i) + # return the result's list return result diff --git a/solutions/tests/test_FooBar_code.py b/solutions/tests/test_FooBar_code.py index 3b1f67331..412a520b7 100644 --- a/solutions/tests/test_FooBar_code.py +++ b/solutions/tests/test_FooBar_code.py @@ -6,24 +6,30 @@ class TestFooBar(unittest.TestCase): # Edge cases: def test_int1(self): + """check if the input is 1""" self.assertEqual(FooBar_code(1), [1]) def test_int0(self): + """check if the input is 0""" self.assertEqual(FooBar_code(0), []) def test_negative_int(self): + """check if the input is negative""" self.assertEqual(FooBar_code(-1), []) # Standard cases: def test_int8(self): + """check if the input is 8""" self.assertEqual(FooBar_code(8), [1, 2, 3, "foo", 5, "Bar", 7, "foo"]) def test_int12(self): + """check if the input is 12""" self.assertEqual( FooBar_code(12), [1, 2, 3, "foo", 5, "Bar", 7, "foo", 9, 10, 11, "FooBar"] ) def test_is_int(self): + """check if the input is large number""" self.assertEqual( FooBar_code(16), [ From e0d51ae65299476372f4f720480d05608eadfe94 Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Fri, 3 Jan 2025 00:05:28 +0400 Subject: [PATCH 069/151] Fixing linting errors in the python file that got to be involved within the branch of READNE --- solutions/even_number_count.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/solutions/even_number_count.py b/solutions/even_number_count.py index 63ea6c592..421b1b4f6 100644 --- a/solutions/even_number_count.py +++ b/solutions/even_number_count.py @@ -14,13 +14,13 @@ def even_number_count(number: list) -> int: """Returns the number of even numbers on the list. Parameters: - int: list, the input list to process + int: list, the input list to process return - > int: indicating the number of even number in the list Raises: - AssertionError: - + AssertionError: + Examples: >>> even_number_count ([1]) 0 @@ -32,7 +32,6 @@ def even_number_count(number: list) -> int: assert isinstance(number,list) for num in number: assert isinstance(num,int) - count = 0 for num in number: @@ -43,5 +42,3 @@ def even_number_count(number: list) -> int: if __name__ == "__main__": print(even_number_count([1,2,3,4,5])) - - From a5cbc04baaef01c96d9511619c828b7dabf4aad7 Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Fri, 3 Jan 2025 01:47:50 +0400 Subject: [PATCH 070/151] Solving is_anagram problem and adding the corresponding test files --- solutions/anagrams.py | 34 -------------- solutions/is_anagram.py | 55 ++++++++++++++++++++++ solutions/tests/test_anagrams.py | 26 ----------- solutions/tests/test_is_anagram.py | 75 ++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+), 60 deletions(-) delete mode 100644 solutions/anagrams.py create mode 100644 solutions/is_anagram.py delete mode 100644 solutions/tests/test_anagrams.py create mode 100644 solutions/tests/test_is_anagram.py diff --git a/solutions/anagrams.py b/solutions/anagrams.py deleted file mode 100644 index 0cd75a3f3..000000000 --- a/solutions/anagrams.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Write a function that takes two strings as input and checks if they -are anagrams of each other. Anagrams are words or phrases made by -rearranging the letters of another, using all original letters -exactly once - -True if the two strings are anagrams, False otherwise - -""" - - -def is_anagrams(word1: str, word2: str) -> bool: - """ - Returns true or false if the two strings given are anagrams - of each other. - - Parameters: - word1: The first string - words2: The second string - - Returns -> bool: Either true or false of either the strings - are anagrams of each other or not. - - Raises: - AssertionError: if the parameters are not strings - - Examples: - >>> is_anagrams("anagram", "nagaram") - True - >>> is_anagrams("rat", "car") - False - """ diff --git a/solutions/is_anagram.py b/solutions/is_anagram.py new file mode 100644 index 000000000..a51680229 --- /dev/null +++ b/solutions/is_anagram.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Write a function that takes two strings as input and checks if they +are anagrams of each other. Anagrams are words or phrases made by +rearranging the letters of another, using all original letters +exactly once + +True if the two strings are anagrams, False otherwise + +""" + + +from collections import Counter + + +def is_anagram(first_word: str, second_word: str) -> bool: + """ + Returns true or false if the two strings given are anagrams + of each other. + + Anagram is word or a phrade formed by rearranging the letters of another + word or phrase, using all the original letters exactly once + + "listen" -> "silent" + + Parameters: + first_word: The first string + second_word: The second string + + Returns -> bool: Either true or false of either the strings + are anagrams of each other or not. + + Raises: + AssertionError: if the parameters are not strings + + Examples: + >>> is_anagram("listen", "silent") + True + >>> is_anagram("raac", "car") + False + >>> is_anagram("evil", "vile") + True + """ + assert isinstance(first_word, str), "First word must be a string" + assert isinstance(second_word, str), "Second word must be a string" + + if len(first_word) != len(second_word): + return False + + # This is a time complexity of O(nlogn) answer + # return sorted(first_word) == sorted(second_word) + + # This is a time complexity of O(n) answer + return Counter(first_word) == Counter(second_word) diff --git a/solutions/tests/test_anagrams.py b/solutions/tests/test_anagrams.py deleted file mode 100644 index 71346393d..000000000 --- a/solutions/tests/test_anagrams.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Test module for find_longest function. -Contains correct tests to help identify bugs in the implementation. - -Test categories: - - Standard cases: typical string lists - - Edge cases: empty strings, equal lengths - - Defensive tests: invalid inputs - -Created on 2024-12-06 -Author: Claude AI -""" - - -import unittest - -from ..anagrams import is_anagrams - - -class TestIsAnagram(unittest.TestCase): - """Test suite for the is_anagram function""" - # Standard test cases - def test_base(self): - pass diff --git a/solutions/tests/test_is_anagram.py b/solutions/tests/test_is_anagram.py new file mode 100644 index 000000000..e5800fa42 --- /dev/null +++ b/solutions/tests/test_is_anagram.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Test module for is_anagram function. + +Test categories: + - Standard cases: typical string lists + - Edge cases: empty strings, equal lengths + - Defensive tests: invalid inputs + +Created on 2024-01-02 +Author: Reem Osama +""" + + +import unittest + +from ..is_anagram import is_anagram + + +class TestIsAnagram(unittest.TestCase): + """Test suite for the is_anagram function""" + # Standard Cases: + def test_base_one(self): + """A basic test for valid cases""" + self.assertEqual(is_anagram("listen", "silent"), True) + + def test_differnt_length(self): + """A test for string with unequal lengths""" + self.assertEqual(is_anagram("apple", "apples"), False) + + # Edge Cases: + def test_case_sensitivity(self): + """A test for case sensetivity strings""" + self.assertEqual(is_anagram("Listen", "silent"), False) + + def test_white_space(self): + """A test for whitespace handling""" + self.assertEqual(is_anagram("dormitory", "dirty room"), False) + + def test_space_in_middle(self): + """A test for handling spaces in the middle of two strings""" + self.assertEqual(is_anagram("the eyes", "they see"), True) + + def test_special_characters(self): + """A test with inputs with punctutation or non-alphabetic chars""" + self.assertEqual(is_anagram("a+b=c", "c+b=a"), True) + + def test_empty_strings(self): + """A test with empty strings""" + self.assertEqual(is_anagram("", ""), True) + + def test_single_characters(self): + """A test with single character strings""" + self.assertEqual(is_anagram("a", "b"), False) + + def test_numerical_strings(self): + """A test with numerical strings""" + self.assertEqual(is_anagram("123", "321"), True) + + def test_large_inputs(self): + """A test with large strings""" + large_str1 = "a" * 10000 + "b" * 10000 + large_str2 = "b" * 10000 + "a" * 10000 + self.assertEqual(is_anagram(large_str1, large_str2), True) + + # Defensive tests: + def test_invalid_input(self): + """A test with invalid input""" + with self.assertRaises(AssertionError): + is_anagram(123, "abc") + + +if __name__ == "__main__": + unittest.main() From 985bf6f6e4965fbbb75c6e77cc85ad85fba161d6 Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Fri, 3 Jan 2025 01:55:32 +0400 Subject: [PATCH 071/151] reiterate to fix ruff linter errors --- solutions/.vscode/settings.json | 6 ++++++ solutions/is_anagram.py | 7 +++---- solutions/tests/test_is_anagram.py | 8 ++++---- 3 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 solutions/.vscode/settings.json diff --git a/solutions/.vscode/settings.json b/solutions/.vscode/settings.json new file mode 100644 index 000000000..3f2b53ad3 --- /dev/null +++ b/solutions/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "cSpell.words": [ + "Osama", + "Reem" + ] +} \ No newline at end of file diff --git a/solutions/is_anagram.py b/solutions/is_anagram.py index a51680229..2a63f3b34 100644 --- a/solutions/is_anagram.py +++ b/solutions/is_anagram.py @@ -10,7 +10,6 @@ """ - from collections import Counter @@ -19,7 +18,7 @@ def is_anagram(first_word: str, second_word: str) -> bool: Returns true or false if the two strings given are anagrams of each other. - Anagram is word or a phrade formed by rearranging the letters of another + Anagram is word or a phrase formed by rearranging the letters of another word or phrase, using all the original letters exactly once "listen" -> "silent" @@ -37,7 +36,7 @@ def is_anagram(first_word: str, second_word: str) -> bool: Examples: >>> is_anagram("listen", "silent") True - >>> is_anagram("raac", "car") + >>> is_anagram("rat", "car") False >>> is_anagram("evil", "vile") True @@ -48,7 +47,7 @@ def is_anagram(first_word: str, second_word: str) -> bool: if len(first_word) != len(second_word): return False - # This is a time complexity of O(nlogn) answer + # This is a time complexity of O(n log n) answer # return sorted(first_word) == sorted(second_word) # This is a time complexity of O(n) answer diff --git a/solutions/tests/test_is_anagram.py b/solutions/tests/test_is_anagram.py index e5800fa42..968529378 100644 --- a/solutions/tests/test_is_anagram.py +++ b/solutions/tests/test_is_anagram.py @@ -12,7 +12,6 @@ Author: Reem Osama """ - import unittest from ..is_anagram import is_anagram @@ -20,18 +19,19 @@ class TestIsAnagram(unittest.TestCase): """Test suite for the is_anagram function""" + # Standard Cases: def test_base_one(self): """A basic test for valid cases""" self.assertEqual(is_anagram("listen", "silent"), True) - def test_differnt_length(self): + def test_different_length(self): """A test for string with unequal lengths""" self.assertEqual(is_anagram("apple", "apples"), False) # Edge Cases: def test_case_sensitivity(self): - """A test for case sensetivity strings""" + """A test for case sensitivity strings""" self.assertEqual(is_anagram("Listen", "silent"), False) def test_white_space(self): @@ -43,7 +43,7 @@ def test_space_in_middle(self): self.assertEqual(is_anagram("the eyes", "they see"), True) def test_special_characters(self): - """A test with inputs with punctutation or non-alphabetic chars""" + """A test with inputs with punctuation or non-alphabetic chars""" self.assertEqual(is_anagram("a+b=c", "c+b=a"), True) def test_empty_strings(self): From 451c6bfef1320d5186e0dd1d1dc0d7486f7bb9ba Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Fri, 3 Jan 2025 01:58:38 +0400 Subject: [PATCH 072/151] reiterate to fix ls_linting by removing cSpell additions --- solutions/.vscode/settings.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/solutions/.vscode/settings.json b/solutions/.vscode/settings.json index 3f2b53ad3..e69de29bb 100644 --- a/solutions/.vscode/settings.json +++ b/solutions/.vscode/settings.json @@ -1,6 +0,0 @@ -{ - "cSpell.words": [ - "Osama", - "Reem" - ] -} \ No newline at end of file From 332e5b42436fd10b88ace7c4d48d602558df72e0 Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Fri, 3 Jan 2025 02:02:33 +0400 Subject: [PATCH 073/151] fizing ls_linting error by removing the .vscode file from the solutions dir --- solutions/.vscode/settings.json | 0 solutions/__init__.py | 1 - 2 files changed, 1 deletion(-) delete mode 100644 solutions/.vscode/settings.json diff --git a/solutions/.vscode/settings.json b/solutions/.vscode/settings.json deleted file mode 100644 index e69de29bb..000000000 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 @@ - From b64994bbacb09b2425084e39063e6986862acb82 Mon Sep 17 00:00:00 2001 From: Safi222 Date: Fri, 3 Jan 2025 01:31:46 +0300 Subject: [PATCH 074/151] adding 7 test cases and the function implementation --- solutions/LowestCommonAncestor_in_BST.py | 53 +++++++---- .../tests/test_LowestCommonAncestor_in_BST.py | 91 ++++++++++++++----- 2 files changed, 105 insertions(+), 39 deletions(-) diff --git a/solutions/LowestCommonAncestor_in_BST.py b/solutions/LowestCommonAncestor_in_BST.py index 6abf16368..3a5efe452 100644 --- a/solutions/LowestCommonAncestor_in_BST.py +++ b/solutions/LowestCommonAncestor_in_BST.py @@ -8,30 +8,43 @@ def __init__(self, value=0, left=None, right=None): def lowestCommonAncestor(root: "TreeNode", p: "TreeNode", q: "TreeNode") -> "TreeNode": - """ + r""" Finds the Lowest Common Ancestor (LCA) of two nodes in a Binary Search Tree. - The Lowest Common Ancestor between two nodes p and q is the lowest node in the tree T - such that both p and q are descendants of the node. The ancestor is allowed to be a - descendant of itself. + In a Binary Search Tree, the Lowest Common Ancestor between two nodes p and q is the lowest node + such that both p and q are descendants of this node (a node can be a descendant of itself). Args: - root (TreeNode): The root of the Binary Search Tree. - p (TreeNode): The first node in the BST. - q (TreeNode): The second node in the BST to find LCA with. + root (TreeNode): The root node of the Binary Search Tree. + p (TreeNode): The first node in the tree. + q (TreeNode): The second node in the tree. Returns: TreeNode: The Lowest Common Ancestor of nodes p and q. + Notes: + - If both p and q are smaller than the current node, the LCA is in the left subtree. + - If both p and q are larger than the current node, the LCA is in the right subtree. + - Otherwise, the current node is the LCA. + Examples: - Given the Binary Search Tree Structure: - 5 - / \ - 3 8 - / \ / \ - 1 4 7 9 - \ - 2 + Example 1: + Input: root = [5,3,8,1,4,7,9,null,2], p = TreeNode(3), q = TreeNode(8) + Output: TreeNode(5) + + Example 2: + Input: root = [5,3,8,1,4,7,9,null,2], p = TreeNode(3), q = TreeNode(4) + Output: TreeNode(3) + + Example: + Tree Structure: + 5 + / \\ + 3 8 + / \ / \\ + 1 4 7 9 + \\ + 2 Example 1: Input: root = [5,3,8,1,4,7,9,null,2], p = 3, q = 8 @@ -41,4 +54,12 @@ def lowestCommonAncestor(root: "TreeNode", p: "TreeNode", q: "TreeNode") -> "Tre Input: root = [5,3,8,1,4,7,9,null,2], p = 3, q = 4 Output: 3 """ - start = root + candidate = root + # this tree satisfy BTS properties + while candidate: + if p.value > candidate.value and q.value > candidate.value: + candidate = candidate.right + elif p.value < candidate.value and q.value < candidate.value: + candidate = candidate.left + else: + return candidate diff --git a/solutions/tests/test_LowestCommonAncestor_in_BST.py b/solutions/tests/test_LowestCommonAncestor_in_BST.py index cb535758d..639af3e24 100644 --- a/solutions/tests/test_LowestCommonAncestor_in_BST.py +++ b/solutions/tests/test_LowestCommonAncestor_in_BST.py @@ -1,12 +1,13 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ -Test module for Lowest Common Ancestor in Binary search tree function. - +Test module for Lowest Common Ancestor in Binary Search Tree function. """ import unittest +from solutions.LowestCommonAncestor_in_BST import lowestCommonAncestor + class TreeNode: """Define class for TreeNode""" @@ -18,31 +19,75 @@ def __init__(self, value=0, left=None, right=None): class TestLowestCommonAncestor(unittest.TestCase): - """Test the Lowest common Ancestor in Binary search tree function + """Test the Lowest Common Ancestor in Binary Search Tree function. + Binary Search Tree structure: - - 5 - / \ - 3 8 - / \ / \ - 1 4 7 9 - \ - 2 + 5 + / \\ + 3 8 + / \ / \\ + 1 4 7 9 + \\ + 2 """ + def setUp(self): + """Construct Binary Search Tree from the example.""" + self.root = TreeNode(5) + self.root.left = TreeNode(3) + self.root.right = TreeNode(8) + self.root.left.left = TreeNode(1) + self.root.left.right = TreeNode(4) + self.root.right.left = TreeNode(7) + self.root.right.right = TreeNode(9) + self.root.left.left.right = TreeNode(2) + + def test_level_1(self): + """Test LCA of node 3 and node 8 on the same level""" + p = self.root.left + q = self.root.right + candidate = lowestCommonAncestor(self.root, p, q) + self.assertEqual(candidate.value, 5) + + def test_different_levels_case_1(self): + """Test LCA for node 2 and node 9 on different levels""" + p = self.root.left.left.right # Node 2 + q = self.root.right.right # Node 9 + candidate = lowestCommonAncestor(self.root, p, q) + self.assertEqual(candidate.value, 5) + + def test_different_levels_case_2(self): + """Test LCA for node 1 and node 2 on different levels""" + p = self.root.left.left.right + q = self.root.left.left + candidate = lowestCommonAncestor(self.root, p, q) + self.assertEqual(candidate.value, 1) + + def test_different_levels_case_3(self): + """Test LCA for node 3 and node 7 on different levels""" + p = self.root.left.left + q = self.root.right.left + candidate = lowestCommonAncestor(self.root, p, q) + self.assertEqual(candidate.value, 5) -def setUp_BTS(self): - "create Binary search tree from the example" - self.root = TreeNode(5) - self.root.left = TreeNode(3) - self.root.right = TreeNode(8) - self.root.left.left = TreeNode(1) - self.root.left.right = TreeNode(4) - self.root.right.left = TreeNode(7) - self.root.right.right = TreeNode(9) - self.root.left.left.right = TreeNode(2) + def test_different_levels_case_4(self): + """Test LCA for node 7 and node 9 on different levels""" + p = self.root.right.left + q = self.root.right.right + candidate = lowestCommonAncestor(self.root, p, q) + self.assertEqual(candidate.value, 8) + def test_different_levels_root_2(self): + """Test LCA for root 5 and node 7 on different levels""" + p = self.root + q = self.root.right.left + candidate = lowestCommonAncestor(self.root, p, q) + self.assertEqual(candidate.value, 5) -def test_case_1(self): - "This test case 1" + def test_ancestor_is_the_node_itself(self): + """Test LCA where the ancestor is one of the nodes itself (3, 4)""" + p = self.root.left + q = self.root.left.right + candidate = lowestCommonAncestor(self.root, p, q) + self.assertEqual(candidate.value, 3) From fc913ec170d7ff1a6baa7a4fc7479e3104ddea69 Mon Sep 17 00:00:00 2001 From: Safi222 Date: Fri, 3 Jan 2025 02:08:03 +0300 Subject: [PATCH 075/151] setup for Roman to integer problem with test base case --- solutions/Roman_to_integer.py | 26 ++++++++++++++++++++++++ solutions/tests/test_Roman_to_integer.py | 18 ++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 solutions/Roman_to_integer.py create mode 100644 solutions/tests/test_Roman_to_integer.py diff --git a/solutions/Roman_to_integer.py b/solutions/Roman_to_integer.py new file mode 100644 index 000000000..54e29d3a5 --- /dev/null +++ b/solutions/Roman_to_integer.py @@ -0,0 +1,26 @@ +def romanToInteger(self, s: str) -> int: + """ + Convert a Roman numeral string to an integer. + You can assume the number will be between 1 and 3999. + + Args: + str (str): The Roman numeral string to convert. + + Returns: + int: The integer representation of the Roman numeral. + + Exceptions: + If `str` is not a string or is None, return 0. + + Roman numeral system: + Roman numerals are made up of the following characters: + I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000. + Numbers are written from largest to smallest from left to right, + except when a smaller numeral appears before a larger numeral, + indicating subtraction (e.g: IV = 4). + + Examples: + romanToInteger("X") => 10 + romanToInteger("VII") => 7 + romanToInteger("LXXXVII") => 87 + """ diff --git a/solutions/tests/test_Roman_to_integer.py b/solutions/tests/test_Roman_to_integer.py new file mode 100644 index 000000000..f9ae98484 --- /dev/null +++ b/solutions/tests/test_Roman_to_integer.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Test module for Roman to integer function. +""" + +import unittest + + +class TestRomanToInteger(unittest.TestCase): + """ + Unit test class to verify the correctness of the romanToInteger function. + """ + + +def test_case_0(self): + """Test conversion of single Roman number to 10""" + self.assertEqual(self.romanToInteger("X"), 10) From 3e7f9dd23ff253e9a498b4d0c674ff4e9816f04a Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:09:06 +0400 Subject: [PATCH 076/151] Fixing ruff linting on existing py files --- solutions/even_number_count.py | 13 +++++++------ solutions/fuel_gauge.py | 5 ++++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/solutions/even_number_count.py b/solutions/even_number_count.py index 421b1b4f6..316ff13ff 100644 --- a/solutions/even_number_count.py +++ b/solutions/even_number_count.py @@ -10,6 +10,7 @@ @author: Mayar Ali. """ + def even_number_count(number: list) -> int: """Returns the number of even numbers on the list. @@ -29,16 +30,16 @@ def even_number_count(number: list) -> int: >>> even_number_count ([3,2,1]) 1 """ - assert isinstance(number,list) + assert isinstance(number, list) for num in number: - assert isinstance(num,int) + assert isinstance(num, int) count = 0 for num in number: - if num % 2 ==0: - count +=1 + if num % 2 == 0: + count += 1 return count -if __name__ == "__main__": - print(even_number_count([1,2,3,4,5])) +if __name__ == "__main__": + print(even_number_count([1, 2, 3, 4, 5])) diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py index 641d65345..71091e5b4 100644 --- a/solutions/fuel_gauge.py +++ b/solutions/fuel_gauge.py @@ -1,3 +1,6 @@ +"""module calculates the percentage of fuel in a tank and returns a status indicator.""" + + def fuel_gauge(x: int, y: int) -> str: """ Calculates the percentage of fuel in a tank and returns a status indicator. @@ -7,7 +10,7 @@ def fuel_gauge(x: int, y: int) -> str: y (int): Tank capacity (must be > 0). Returns: - str: + str: - "F" if percentage >= 90. - "E" if percentage <= 10. - "M" for all other cases. From d331cb6f59d916abcef266df530d5892050dfd9b Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:44:59 +0400 Subject: [PATCH 077/151] fixing ruff linter of fuel_gauge.py file --- solutions/fuel_gauge.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py index 641d65345..71091e5b4 100644 --- a/solutions/fuel_gauge.py +++ b/solutions/fuel_gauge.py @@ -1,3 +1,6 @@ +"""module calculates the percentage of fuel in a tank and returns a status indicator.""" + + def fuel_gauge(x: int, y: int) -> str: """ Calculates the percentage of fuel in a tank and returns a status indicator. @@ -7,7 +10,7 @@ def fuel_gauge(x: int, y: int) -> str: y (int): Tank capacity (must be > 0). Returns: - str: + str: - "F" if percentage >= 90. - "E" if percentage <= 10. - "M" for all other cases. From 18987846d48082d6873baecdb4400c8ee2a87041 Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Fri, 3 Jan 2025 18:19:34 +0200 Subject: [PATCH 078/151] initial commit --- solutions/copy_from_file_to_file.py | 48 ++++++++++++++ solutions/empty.txt | 0 solutions/source.txt | 1 + .../tests/test_copy_from_file_to_file.py | 64 +++++++++++++++++++ 4 files changed, 113 insertions(+) create mode 100644 solutions/copy_from_file_to_file.py create mode 100644 solutions/empty.txt create mode 100644 solutions/source.txt create mode 100644 solutions/tests/test_copy_from_file_to_file.py diff --git a/solutions/copy_from_file_to_file.py b/solutions/copy_from_file_to_file.py new file mode 100644 index 000000000..4ee07a3cf --- /dev/null +++ b/solutions/copy_from_file_to_file.py @@ -0,0 +1,48 @@ +import os + +""" + This Module can copy content from one file to another + + Module contents: + - .txt file: the file to read the content from + - .txt file: the file to write the content to + +created on 1 Jan 2025 "Happy new year" +@author: saja abusafia + +""" + + +def copy_file_to_file(source_file, destination_file): + """ + The function copies the content from one file to another file + + + Parameters: + source_file (str): the file to read the conent from + destination_file(str): the file to add the content to + + Returns: + none-The function performs the copying operation but does not return + anything + + >>> copy_file_to_file("solutions/source.txt","solutions/destination.txt") + + + + """ + assert os.path.exists( + source_file + ), f"Error: Source file '{source_file}' doesn't exist." + assert source_file.endswith( + ".txt" + ), f"Error: Source file '{source_file}' is not a .txt file." + assert destination_file.endswith( + ".txt" + ), f"Error: Destination file '{destination_file}' is not a .txt file." + + with open(source_file, "r") as file_from: + file_content = file_from.read() + + with open(destination_file, "w") as file_to: + file_to.write(file_content) diff --git a/solutions/empty.txt b/solutions/empty.txt new file mode 100644 index 000000000..e69de29bb diff --git a/solutions/source.txt b/solutions/source.txt new file mode 100644 index 000000000..8d5189012 --- /dev/null +++ b/solutions/source.txt @@ -0,0 +1 @@ +This content is written inside the Source file .txt diff --git a/solutions/tests/test_copy_from_file_to_file.py b/solutions/tests/test_copy_from_file_to_file.py new file mode 100644 index 000000000..0fea78e35 --- /dev/null +++ b/solutions/tests/test_copy_from_file_to_file.py @@ -0,0 +1,64 @@ +import unittest + +from ..copy_from_file_to_file import copy_file_to_file + +""" + copy the content from one file to another file + Parameters: + source_file (str): the file to read the conent from + Destination_file(str): the file to add the content to + + Returns -> + None-The method performs the copying operation but does not return anything + Raises: AssertionError +""" + + +class TestCopyFromFileToFile(unittest.TestCase): + def test_des_not_exist(self): + """This method test if Destination doesn't exist""" + source_file = "solutions/source.txt" + destination_file = "solutions/destination.txt" + copy_file_to_file(source_file, destination_file) + with ( + open("solutions/source.txt", "r") as source, + open("solutions/destination.txt", "r") as destination, + ): + self.assertEqual(source.read(), destination.read()) + + def test_copy_to_file(self): + """This method test when the file we copy already exist""" + source_file = "solutions/source.txt" + destination_file = "solutions/destination.txt" + copy_file_to_file(source_file, destination_file) + + with ( + open("solutions/source.txt", "r") as source, + open("solutions/destination.txt", "r") as destination, + ): + self.assertEqual(source.read(), destination.read()) + + def test_not_a_txt_file(self): + """It should raise an assertion error if file is not .txt""" + with self.assertRaises(AssertionError): + copy_file_to_file("solutions/Source.", "solutions/destination.txt") + + def test_source_file_empty(self): + """The method test when the source file is empty""" + source_file = "solutions/empty.txt" + destination_file = "solutions/destination.txt" + copy_file_to_file(source_file, destination_file) + + with ( + open("solutions/empty.txt", "r") as source, + open("solutions/destination.txt", "r") as destination, + ): + self.assertEqual(source.read(), destination.read()) + + def test_src_not_exist(self): + """This method test if Source doesn't exist""" + source_file = "solutions/not_exist.txt" + destination_file = "solutions/destination.txt" + + with self.assertRaises(AssertionError): + copy_file_to_file(source_file, destination_file) From 71ef95656a46612cbba95d695daa936c7df289d6 Mon Sep 17 00:00:00 2001 From: Safi222 Date: Sat, 4 Jan 2025 01:52:30 +0300 Subject: [PATCH 079/151] adding more tests and implementing Roman to integer function --- solutions/Roman_to_integer.py | 67 +++++++++++++++--------- solutions/tests/test_Roman_to_integer.py | 40 ++++++++++++-- 2 files changed, 77 insertions(+), 30 deletions(-) diff --git a/solutions/Roman_to_integer.py b/solutions/Roman_to_integer.py index 54e29d3a5..44e15c9a6 100644 --- a/solutions/Roman_to_integer.py +++ b/solutions/Roman_to_integer.py @@ -1,26 +1,41 @@ -def romanToInteger(self, s: str) -> int: - """ - Convert a Roman numeral string to an integer. - You can assume the number will be between 1 and 3999. - - Args: - str (str): The Roman numeral string to convert. - - Returns: - int: The integer representation of the Roman numeral. - - Exceptions: - If `str` is not a string or is None, return 0. - - Roman numeral system: - Roman numerals are made up of the following characters: - I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000. - Numbers are written from largest to smallest from left to right, - except when a smaller numeral appears before a larger numeral, - indicating subtraction (e.g: IV = 4). - - Examples: - romanToInteger("X") => 10 - romanToInteger("VII") => 7 - romanToInteger("LXXXVII") => 87 - """ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Module for converting Roman numerals to integers. + +Provides the RomanConverter class with a method to convert valid Roman numeral strings +into their integer representation. +""" + + +class RomanConverter: + """This class identify Roman Converter.""" + + def roman_to_integer(self, roman_str: str) -> int: + """ + Convert a Roman numeral string to an integer. + + Args: + roman_str (str): The Roman numeral string to convert. + + Returns: + int: The integer representation of the Roman numeral. + + Exceptions: + If `roman_str` is not a string or is None, return 0. + + + """ + if not isinstance(roman_str, str) or roman_str is None: + return 0 + + roman = {"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000} + result = 0 + + for idx, char in enumerate(roman_str): + if idx + 1 < len(roman_str) and roman[char] < roman[roman_str[idx + 1]]: + result -= roman[char] + else: + result += roman[char] + + return result diff --git a/solutions/tests/test_Roman_to_integer.py b/solutions/tests/test_Roman_to_integer.py index f9ae98484..ac92fd4de 100644 --- a/solutions/tests/test_Roman_to_integer.py +++ b/solutions/tests/test_Roman_to_integer.py @@ -5,14 +5,46 @@ """ import unittest +from solutions.roman_to_integer import RomanConverter class TestRomanToInteger(unittest.TestCase): """ - Unit test class to verify the correctness of the romanToInteger function. + Unittest class to test the roman_to_integer function. """ + def test_case_0(self): + """Test conversion of single Roman (X) to numeral 10""" + self.assertEqual(RomanConverter().roman_to_integer("X"), 10) -def test_case_0(self): - """Test conversion of single Roman number to 10""" - self.assertEqual(self.romanToInteger("X"), 10) + def test_case_1(self): + """Test conversion of Roman numeral to 1000 (M)""" + self.assertEqual(RomanConverter().roman_to_integer("M"), 1000) + + def test_case_2(self): + """Test conversion of Roman (XC) to numeral 90""" + self.assertEqual(RomanConverter().roman_to_integer("XC"), 90) + + def test_case_3(self): + """Test conversion of Roman (IX) numeral to 9""" + self.assertEqual(RomanConverter().roman_to_integer("IX"), 9) + + def test_case_4(self): + """Test conversion of Roman (LXXXVII) numeral to 87""" + self.assertEqual(RomanConverter().roman_to_integer("LXXXVII"), 87) + + def test_case_5(self): + """Test conversion of Roman numeral to 3999 (MMMCMXCIX)""" + self.assertEqual(RomanConverter().roman_to_integer("MMMCMXCIX"), 3999) + + def test_case_6(self): + """Test non-string input, expect 0""" + self.assertEqual(RomanConverter().roman_to_integer(123), 0) + + def test_case_7(self): + """Test non-string input (None), expect 0""" + self.assertEqual(RomanConverter().roman_to_integer(None), 0) + + def test_case_8(self): + """Test empty string input, expect 0""" + self.assertEqual(RomanConverter().roman_to_integer(""), 0) From fd2a816734f88cdd6b9db75ffdd84d5c08194c84 Mon Sep 17 00:00:00 2001 From: Safi222 Date: Sat, 4 Jan 2025 02:00:02 +0300 Subject: [PATCH 080/151] fixing issues --- solutions/tests/test_Roman_to_integer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/solutions/tests/test_Roman_to_integer.py b/solutions/tests/test_Roman_to_integer.py index ac92fd4de..16f400443 100644 --- a/solutions/tests/test_Roman_to_integer.py +++ b/solutions/tests/test_Roman_to_integer.py @@ -5,7 +5,8 @@ """ import unittest -from solutions.roman_to_integer import RomanConverter + +from solutions.Roman_to_integer import RomanConverter class TestRomanToInteger(unittest.TestCase): From 4b335178042e902388eb626bfc77d32f7ed60fdb Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Sat, 4 Jan 2025 03:14:32 +0400 Subject: [PATCH 081/151] Writing the base code for the robot problem --- .vscode/settings.json | 4 ++-- solutions/robot.py | 51 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index bbda5188d..252022b48 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -119,8 +119,8 @@ "editor.defaultFormatter": "charliermarsh.ruff", "editor.formatOnSave": true, "editor.codeActionsOnSave": { - "source.fixAll.ruff": true, - "source.organizeImports.ruff": true + "source.fixAll.ruff": "explicit", + "source.organizeImports.ruff": "explicit" } } } diff --git a/solutions/robot.py b/solutions/robot.py index b6c033e2e..c3862c7ab 100644 --- a/solutions/robot.py +++ b/solutions/robot.py @@ -14,22 +14,65 @@ be less than or equal to 2 * 109. """ -def robot(m_: int, n_: int) -> int: + +def robot_move(cell, rows, cols, memo) -> int: + """ + This is a helper function that determines the number of unique paths by + using dynamic programming and memoization + + Parameters: + cell: a tuple made of two elements refers to the current location + inside the grid + rows: The number of rows in the grid. + cols: The number of columns in the grid. + memo: a dictionary to save answers for memoization + + Returns -> The number of unique paths from the top-left corner + to the bottom-right corner. + """ + if memo.get(cell): + return memo.get(cell) + if cell[1] >= cols - 1 or cell[0] >= rows - 1: + return 1 + memo[cell] = robot_move((cell[0] + 1, cell[1]), rows, cols, memo) + \ + robot_move((cell[0], cell[1] + 1), rows, cols, memo) + return memo[cell] + + +def robot(rows: int, cols: int) -> int: """ Returns the number of possible unique routes to reach the most bottom-right corner Parameters: - m: The number of rows in the grid. - n: The number of columns in the grid. + rows: The number of rows in the grid. + cols: The number of columns in the grid. Returns -> The number of unique paths from the top-left corner to the bottom-right corner. Raises: - AssertionError: if m and n are not integers or less than 1 + AssertionError: if rows and cols are not integers or less than 1 Examples: >>> robot(3, 7) 28 + >>> robot(4, 3) + 10 + >>> robot(23, 12) + 193536720 """ + # assert the values of rows and clos and make sure they are ints and + # greater than 1 + assert isinstance(rows, int) and rows > 1, "Rows variables has to \ + be an integer greater than 1" + assert isinstance(cols, int) and cols > 1, "Cols variable has to be \ + greater than 1" + + # use the helper function robot_move to determine the number of paths + memo = {} + return robot_move((0, 0), rows, cols, memo) # (0, 0) is the initial spot + + +if __name__ == "__main__": + print(robot(23, 12)) From 8818d31873958f5a7550a3656cd2c0ae083ca288 Mon Sep 17 00:00:00 2001 From: Safi222 Date: Sat, 4 Jan 2025 02:40:06 +0300 Subject: [PATCH 082/151] fixing issues --- solutions/LowestCommonAncestor_in_BST.py | 65 ------- solutions/arithmetic_sequence.py | 53 ------ solutions/fuel_gauge.py | 20 --- .../tests/test_LowestCommonAncestor_in_BST.py | 93 ---------- solutions/tests/test_arithmetic_sequence.py | 162 ------------------ solutions/tests/test_fuel_gauge.py | 30 ---- 6 files changed, 423 deletions(-) delete mode 100644 solutions/LowestCommonAncestor_in_BST.py delete mode 100644 solutions/arithmetic_sequence.py delete mode 100644 solutions/fuel_gauge.py delete mode 100644 solutions/tests/test_LowestCommonAncestor_in_BST.py delete mode 100644 solutions/tests/test_arithmetic_sequence.py delete mode 100644 solutions/tests/test_fuel_gauge.py diff --git a/solutions/LowestCommonAncestor_in_BST.py b/solutions/LowestCommonAncestor_in_BST.py deleted file mode 100644 index 3a5efe452..000000000 --- a/solutions/LowestCommonAncestor_in_BST.py +++ /dev/null @@ -1,65 +0,0 @@ -class TreeNode: - """Define class for TreeNode""" - - def __init__(self, value=0, left=None, right=None): - self.value = value - self.left = left - self.right = right - - -def lowestCommonAncestor(root: "TreeNode", p: "TreeNode", q: "TreeNode") -> "TreeNode": - r""" - Finds the Lowest Common Ancestor (LCA) of two nodes in a Binary Search Tree. - - In a Binary Search Tree, the Lowest Common Ancestor between two nodes p and q is the lowest node - such that both p and q are descendants of this node (a node can be a descendant of itself). - - Args: - root (TreeNode): The root node of the Binary Search Tree. - p (TreeNode): The first node in the tree. - q (TreeNode): The second node in the tree. - - Returns: - TreeNode: The Lowest Common Ancestor of nodes p and q. - - Notes: - - If both p and q are smaller than the current node, the LCA is in the left subtree. - - If both p and q are larger than the current node, the LCA is in the right subtree. - - Otherwise, the current node is the LCA. - - Examples: - Example 1: - Input: root = [5,3,8,1,4,7,9,null,2], p = TreeNode(3), q = TreeNode(8) - Output: TreeNode(5) - - Example 2: - Input: root = [5,3,8,1,4,7,9,null,2], p = TreeNode(3), q = TreeNode(4) - Output: TreeNode(3) - - Example: - Tree Structure: - 5 - / \\ - 3 8 - / \ / \\ - 1 4 7 9 - \\ - 2 - - Example 1: - Input: root = [5,3,8,1,4,7,9,null,2], p = 3, q = 8 - Output: 5 - - Example 2: - Input: root = [5,3,8,1,4,7,9,null,2], p = 3, q = 4 - Output: 3 - """ - candidate = root - # this tree satisfy BTS properties - while candidate: - if p.value > candidate.value and q.value > candidate.value: - candidate = candidate.right - elif p.value < candidate.value and q.value < candidate.value: - candidate = candidate.left - else: - return candidate diff --git a/solutions/arithmetic_sequence.py b/solutions/arithmetic_sequence.py deleted file mode 100644 index fbab5c1fc..000000000 --- a/solutions/arithmetic_sequence.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -A module for generating a sequence for arithmetic numbers - -Module contents: - - arithmetic_sequence:generating a sequence of n arithmetic numbers. - -Created on Sunday/22/December/2024 -@author:Mayar Ali -""" - -# ---before documenting and testing--- - - -def arithmetic_sequence(sequence_length: int) -> list: - """ - list in which the difference between consecutive terms is constant. - Parameters: - sequence_length:int, greater than zero - - Returns -list[int] with the first n number of the arithmetic sequence - - Raises: - AssertionError : if the argument is not an integer - AssertionError : if the argument is less or equal to zero - - Examples: - >>>arithmetic_sequence(0) - [1] - >>>arithmetic_sequence(5) - [0 ,1 ,5 ,9 ,13] - >>>arithmetic_sequence(11) - [0 ,1 ,5 ,9 ,13 ,17 ,21 ,25 ,29 ,33 ,37 ] - """ - assert isinstance(sequence_length, int) - assert sequence_length >= 0 - - if sequence_length == 0: - return [] - if sequence_length == 1: - return [1] - if sequence_length == 2: - return [0, 1] - sequence = [0, 1] - while len(sequence) < sequence_length: - sequence.append(sequence[-1] + 3) - - return sequence - - -if __name__ == "__main__": - print(arithmetic_sequence(20)) diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py deleted file mode 100644 index 551098ee9..000000000 --- a/solutions/fuel_gauge.py +++ /dev/null @@ -1,20 +0,0 @@ -def fuel_gauge(x, y): - """ - This is a function that calculates the percentage of fuel in a tank. - - Parameters: - X= fuel in the tank (x value must be less than or equal to y) - Y= tank capacity (y value must be greater than 0)""" - if y == 0 or x > y: - """This is a condition that checks if the tank size is zero or if the fuel is more than the tank capacity.""" - return "Invalid input" - - percentage = (x / y) * 100 - """This is a formula that calculates the percentage of fuel in the tank.""" - if percentage >= 90: - return "F" - elif percentage > 10: - return "M" - elif percentage <= 10: - return "E" - return int(percentage) diff --git a/solutions/tests/test_LowestCommonAncestor_in_BST.py b/solutions/tests/test_LowestCommonAncestor_in_BST.py deleted file mode 100644 index 639af3e24..000000000 --- a/solutions/tests/test_LowestCommonAncestor_in_BST.py +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Test module for Lowest Common Ancestor in Binary Search Tree function. -""" - -import unittest - -from solutions.LowestCommonAncestor_in_BST import lowestCommonAncestor - - -class TreeNode: - """Define class for TreeNode""" - - def __init__(self, value=0, left=None, right=None): - self.value = value - self.left = left - self.right = right - - -class TestLowestCommonAncestor(unittest.TestCase): - """Test the Lowest Common Ancestor in Binary Search Tree function. - - Binary Search Tree structure: - - 5 - / \\ - 3 8 - / \ / \\ - 1 4 7 9 - \\ - 2 - """ - - def setUp(self): - """Construct Binary Search Tree from the example.""" - self.root = TreeNode(5) - self.root.left = TreeNode(3) - self.root.right = TreeNode(8) - self.root.left.left = TreeNode(1) - self.root.left.right = TreeNode(4) - self.root.right.left = TreeNode(7) - self.root.right.right = TreeNode(9) - self.root.left.left.right = TreeNode(2) - - def test_level_1(self): - """Test LCA of node 3 and node 8 on the same level""" - p = self.root.left - q = self.root.right - candidate = lowestCommonAncestor(self.root, p, q) - self.assertEqual(candidate.value, 5) - - def test_different_levels_case_1(self): - """Test LCA for node 2 and node 9 on different levels""" - p = self.root.left.left.right # Node 2 - q = self.root.right.right # Node 9 - candidate = lowestCommonAncestor(self.root, p, q) - self.assertEqual(candidate.value, 5) - - def test_different_levels_case_2(self): - """Test LCA for node 1 and node 2 on different levels""" - p = self.root.left.left.right - q = self.root.left.left - candidate = lowestCommonAncestor(self.root, p, q) - self.assertEqual(candidate.value, 1) - - def test_different_levels_case_3(self): - """Test LCA for node 3 and node 7 on different levels""" - p = self.root.left.left - q = self.root.right.left - candidate = lowestCommonAncestor(self.root, p, q) - self.assertEqual(candidate.value, 5) - - def test_different_levels_case_4(self): - """Test LCA for node 7 and node 9 on different levels""" - p = self.root.right.left - q = self.root.right.right - candidate = lowestCommonAncestor(self.root, p, q) - self.assertEqual(candidate.value, 8) - - def test_different_levels_root_2(self): - """Test LCA for root 5 and node 7 on different levels""" - p = self.root - q = self.root.right.left - candidate = lowestCommonAncestor(self.root, p, q) - self.assertEqual(candidate.value, 5) - - def test_ancestor_is_the_node_itself(self): - """Test LCA where the ancestor is one of the nodes itself (3, 4)""" - p = self.root.left - q = self.root.left.right - candidate = lowestCommonAncestor(self.root, p, q) - self.assertEqual(candidate.value, 3) diff --git a/solutions/tests/test_arithmetic_sequence.py b/solutions/tests/test_arithmetic_sequence.py deleted file mode 100644 index 026e2392c..000000000 --- a/solutions/tests/test_arithmetic_sequence.py +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Created on Monday/30/December/2024 -@author:Mayar Ali -""" - -import unittest - -# ---imports & test class before documenting and testing--- -# from ..arithmetic_sequence import arithmetic_sequence -# class TestArithmeticSequence(unittest.TestCase): -# ---imports & test class after documenting and testing--- - -from ..arithmetic_sequence import arithmetic_sequence - - -class TestArithmeticSequence(unittest.TestCase): - """Test the arithmetic_sequence function""" - - def test_0(self): - "It should evaluate 0 to []" - self.assertEqual(arithmetic_sequence(0), []) - - def test_1(self): - "Should evaluate 1 to [0]" - self.assertEqual(arithmetic_sequence(1), [1]) - - def test_2(self): - "Should evaluate 2 to [0,1]" - self.assertEqual(arithmetic_sequence(2), [0, 1]) - - def test_3(self): - "Should evaluate 3 to [0, 1, 5]" - self.assertEqual(arithmetic_sequence(3), [0, 1, 4]) - - # defensive cases - - def test_0_less_than_0(self): - """It should raise an assertion error if the argument is less than 0""" - with self.assertRaises(AssertionError): - arithmetic_sequence(-1) - - def test_1_not_an_integer(self): - """Should raise an assertion error if the argument is a float""" - with self.assertRaises(AssertionError): - arithmetic_sequence(1.0) - - def test_2_not_an_integer(self): - """Should raise an assertion error if the argument is not an integer""" - with self.assertRaises(AssertionError): - arithmetic_sequence(["1", 2, 3]) - - # Edge case - - def test_a_big_number(self): - "Should evaluate 100 to [0, 1, 5]" - self.assertEqual( - arithmetic_sequence(100), - [ - 0, - 1, - 4, - 7, - 10, - 13, - 16, - 19, - 22, - 25, - 28, - 31, - 34, - 37, - 40, - 43, - 46, - 49, - 52, - 55, - 58, - 61, - 64, - 67, - 70, - 73, - 76, - 79, - 82, - 85, - 88, - 91, - 94, - 97, - 100, - 103, - 106, - 109, - 112, - 115, - 118, - 121, - 124, - 127, - 130, - 133, - 136, - 139, - 142, - 145, - 148, - 151, - 154, - 157, - 160, - 163, - 166, - 169, - 172, - 175, - 178, - 181, - 184, - 187, - 190, - 193, - 196, - 199, - 202, - 205, - 208, - 211, - 214, - 217, - 220, - 223, - 226, - 229, - 232, - 235, - 238, - 241, - 244, - 247, - 250, - 253, - 256, - 259, - 262, - 265, - 268, - 271, - 274, - 277, - 280, - 283, - 286, - 289, - 292, - 295, - ], - ) diff --git a/solutions/tests/test_fuel_gauge.py b/solutions/tests/test_fuel_gauge.py deleted file mode 100644 index d1d8aed8a..000000000 --- a/solutions/tests/test_fuel_gauge.py +++ /dev/null @@ -1,30 +0,0 @@ -import unittest - -from ..fuel_gauge import fuel_gauge - - -class TestFuelGauge(unittest.TestCase): - """Test cases for the fuel_gauge function.""" - - def test_full(self): - """Test cases where the percentage is 90% or more it should result in F.""" - self.assertEqual(fuel_gauge(90, 100), "F") - self.assertEqual(fuel_gauge(100, 100), "F") - self.assertEqual(fuel_gauge(97, 100), "F") - - def test_empty(self): - """Test cases where the percentage is 10% or less it should result E.""" - self.assertEqual(fuel_gauge(10, 100), "E") - self.assertEqual(fuel_gauge(0, 100), "E") - self.assertEqual(fuel_gauge(2, 100), "E") - - def test_percentage(self): - """Test cases where the result is between 90 and 10 it should be M.""" - self.assertEqual(fuel_gauge(71, 100), "M") - self.assertEqual(fuel_gauge(23, 100), "M") - self.assertEqual(fuel_gauge(10, 50), "M") - - def test_invalid_input(self): - """Test cases for invalid inputs.""" - self.assertEqual(fuel_gauge(6, 0), "Invalid input") - self.assertEqual(fuel_gauge(7, -1), "Invalid input") From 358fac19a00852bb5f3d39ab4a43403c7d87cfe7 Mon Sep 17 00:00:00 2001 From: Safi222 Date: Sat, 4 Jan 2025 03:05:29 +0300 Subject: [PATCH 083/151] fixing more issues --- solutions/arithmetic_sequence.py | 53 ------- solutions/fuel_gauge.py | 20 --- solutions/tests/test_arithmetic_sequence.py | 162 -------------------- solutions/tests/test_fuel_gauge.py | 30 ---- 4 files changed, 265 deletions(-) delete mode 100644 solutions/arithmetic_sequence.py delete mode 100644 solutions/fuel_gauge.py delete mode 100644 solutions/tests/test_arithmetic_sequence.py delete mode 100644 solutions/tests/test_fuel_gauge.py diff --git a/solutions/arithmetic_sequence.py b/solutions/arithmetic_sequence.py deleted file mode 100644 index fbab5c1fc..000000000 --- a/solutions/arithmetic_sequence.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -A module for generating a sequence for arithmetic numbers - -Module contents: - - arithmetic_sequence:generating a sequence of n arithmetic numbers. - -Created on Sunday/22/December/2024 -@author:Mayar Ali -""" - -# ---before documenting and testing--- - - -def arithmetic_sequence(sequence_length: int) -> list: - """ - list in which the difference between consecutive terms is constant. - Parameters: - sequence_length:int, greater than zero - - Returns -list[int] with the first n number of the arithmetic sequence - - Raises: - AssertionError : if the argument is not an integer - AssertionError : if the argument is less or equal to zero - - Examples: - >>>arithmetic_sequence(0) - [1] - >>>arithmetic_sequence(5) - [0 ,1 ,5 ,9 ,13] - >>>arithmetic_sequence(11) - [0 ,1 ,5 ,9 ,13 ,17 ,21 ,25 ,29 ,33 ,37 ] - """ - assert isinstance(sequence_length, int) - assert sequence_length >= 0 - - if sequence_length == 0: - return [] - if sequence_length == 1: - return [1] - if sequence_length == 2: - return [0, 1] - sequence = [0, 1] - while len(sequence) < sequence_length: - sequence.append(sequence[-1] + 3) - - return sequence - - -if __name__ == "__main__": - print(arithmetic_sequence(20)) diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py deleted file mode 100644 index 551098ee9..000000000 --- a/solutions/fuel_gauge.py +++ /dev/null @@ -1,20 +0,0 @@ -def fuel_gauge(x, y): - """ - This is a function that calculates the percentage of fuel in a tank. - - Parameters: - X= fuel in the tank (x value must be less than or equal to y) - Y= tank capacity (y value must be greater than 0)""" - if y == 0 or x > y: - """This is a condition that checks if the tank size is zero or if the fuel is more than the tank capacity.""" - return "Invalid input" - - percentage = (x / y) * 100 - """This is a formula that calculates the percentage of fuel in the tank.""" - if percentage >= 90: - return "F" - elif percentage > 10: - return "M" - elif percentage <= 10: - return "E" - return int(percentage) diff --git a/solutions/tests/test_arithmetic_sequence.py b/solutions/tests/test_arithmetic_sequence.py deleted file mode 100644 index 026e2392c..000000000 --- a/solutions/tests/test_arithmetic_sequence.py +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Created on Monday/30/December/2024 -@author:Mayar Ali -""" - -import unittest - -# ---imports & test class before documenting and testing--- -# from ..arithmetic_sequence import arithmetic_sequence -# class TestArithmeticSequence(unittest.TestCase): -# ---imports & test class after documenting and testing--- - -from ..arithmetic_sequence import arithmetic_sequence - - -class TestArithmeticSequence(unittest.TestCase): - """Test the arithmetic_sequence function""" - - def test_0(self): - "It should evaluate 0 to []" - self.assertEqual(arithmetic_sequence(0), []) - - def test_1(self): - "Should evaluate 1 to [0]" - self.assertEqual(arithmetic_sequence(1), [1]) - - def test_2(self): - "Should evaluate 2 to [0,1]" - self.assertEqual(arithmetic_sequence(2), [0, 1]) - - def test_3(self): - "Should evaluate 3 to [0, 1, 5]" - self.assertEqual(arithmetic_sequence(3), [0, 1, 4]) - - # defensive cases - - def test_0_less_than_0(self): - """It should raise an assertion error if the argument is less than 0""" - with self.assertRaises(AssertionError): - arithmetic_sequence(-1) - - def test_1_not_an_integer(self): - """Should raise an assertion error if the argument is a float""" - with self.assertRaises(AssertionError): - arithmetic_sequence(1.0) - - def test_2_not_an_integer(self): - """Should raise an assertion error if the argument is not an integer""" - with self.assertRaises(AssertionError): - arithmetic_sequence(["1", 2, 3]) - - # Edge case - - def test_a_big_number(self): - "Should evaluate 100 to [0, 1, 5]" - self.assertEqual( - arithmetic_sequence(100), - [ - 0, - 1, - 4, - 7, - 10, - 13, - 16, - 19, - 22, - 25, - 28, - 31, - 34, - 37, - 40, - 43, - 46, - 49, - 52, - 55, - 58, - 61, - 64, - 67, - 70, - 73, - 76, - 79, - 82, - 85, - 88, - 91, - 94, - 97, - 100, - 103, - 106, - 109, - 112, - 115, - 118, - 121, - 124, - 127, - 130, - 133, - 136, - 139, - 142, - 145, - 148, - 151, - 154, - 157, - 160, - 163, - 166, - 169, - 172, - 175, - 178, - 181, - 184, - 187, - 190, - 193, - 196, - 199, - 202, - 205, - 208, - 211, - 214, - 217, - 220, - 223, - 226, - 229, - 232, - 235, - 238, - 241, - 244, - 247, - 250, - 253, - 256, - 259, - 262, - 265, - 268, - 271, - 274, - 277, - 280, - 283, - 286, - 289, - 292, - 295, - ], - ) diff --git a/solutions/tests/test_fuel_gauge.py b/solutions/tests/test_fuel_gauge.py deleted file mode 100644 index d1d8aed8a..000000000 --- a/solutions/tests/test_fuel_gauge.py +++ /dev/null @@ -1,30 +0,0 @@ -import unittest - -from ..fuel_gauge import fuel_gauge - - -class TestFuelGauge(unittest.TestCase): - """Test cases for the fuel_gauge function.""" - - def test_full(self): - """Test cases where the percentage is 90% or more it should result in F.""" - self.assertEqual(fuel_gauge(90, 100), "F") - self.assertEqual(fuel_gauge(100, 100), "F") - self.assertEqual(fuel_gauge(97, 100), "F") - - def test_empty(self): - """Test cases where the percentage is 10% or less it should result E.""" - self.assertEqual(fuel_gauge(10, 100), "E") - self.assertEqual(fuel_gauge(0, 100), "E") - self.assertEqual(fuel_gauge(2, 100), "E") - - def test_percentage(self): - """Test cases where the result is between 90 and 10 it should be M.""" - self.assertEqual(fuel_gauge(71, 100), "M") - self.assertEqual(fuel_gauge(23, 100), "M") - self.assertEqual(fuel_gauge(10, 50), "M") - - def test_invalid_input(self): - """Test cases for invalid inputs.""" - self.assertEqual(fuel_gauge(6, 0), "Invalid input") - self.assertEqual(fuel_gauge(7, -1), "Invalid input") From ebc09b73b7e21491be8882d78ef1d51beae74614 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Sat, 4 Jan 2025 12:27:10 +0400 Subject: [PATCH 084/151] Adding the armstrong checker --- solutions/armstrong_checker.py | 35 +++++++++++++++++++++++ solutions/armstrong_number.py | 0 solutions/tests/test_armstrong_checker.py | 24 ++++++++++++++++ solutions/tests/test_armstrong_number.py | 0 4 files changed, 59 insertions(+) create mode 100644 solutions/armstrong_checker.py delete mode 100644 solutions/armstrong_number.py create mode 100644 solutions/tests/test_armstrong_checker.py delete mode 100644 solutions/tests/test_armstrong_number.py diff --git a/solutions/armstrong_checker.py b/solutions/armstrong_checker.py new file mode 100644 index 000000000..794f203de --- /dev/null +++ b/solutions/armstrong_checker.py @@ -0,0 +1,35 @@ +"""Module checks if a number is an Armstrong number.""" + + +def armstrong_checker(number: int) -> str: + """ + Checks if a given positive integer is an Armstrong number. + + Parameters: + number (int): The number to check (must be > 0). + + Returns: + str: + - "True" if the number is an Armstrong number. + - "False" if the number is not an Armstrong number. + - "Invalid input" for invalid inputs. + + Raises: + AssertionError: If the input is not a positive integer. + + Examples: + >>> armstrong_checker(153) + 'True' + >>> armstrong_checker(123) + 'False' + >>> armstrong_checker(-153) + 'Invalid input' + """ + if not isinstance(number, int) or number < 0: + return "Invalid input" + + digits = [int(d) for d in str(number)] + n = len(digits) + armstrong_sum = sum(d**n for d in digits) + + return "True" if armstrong_sum == number else "False" diff --git a/solutions/armstrong_number.py b/solutions/armstrong_number.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/solutions/tests/test_armstrong_checker.py b/solutions/tests/test_armstrong_checker.py new file mode 100644 index 000000000..54aec7a8a --- /dev/null +++ b/solutions/tests/test_armstrong_checker.py @@ -0,0 +1,24 @@ +import unittest + +from ..armstrong_checker import armstrong_checker + + +class TestArmstrongChecker(unittest.TestCase): + """Test cases for the armstrong_checker function.""" + + def test_valid_armstrong_numbers(self): + """Test cases where the number is an Armstrong number.""" + self.assertEqual(armstrong_checker(153), "True") + self.assertEqual(armstrong_checker(9474), "True") + self.assertEqual(armstrong_checker(9475), "False") + + def test_non_armstrong_numbers(self): + """Test cases where the number is not an Armstrong number.""" + self.assertEqual(armstrong_checker(123), "False") + self.assertEqual(armstrong_checker(100), "False") + + def test_invalid_inputs(self): + """Test cases for invalid inputs.""" + self.assertEqual(armstrong_checker(-153), "Invalid input") + self.assertEqual(armstrong_checker("153"), "Invalid input") + self.assertEqual(armstrong_checker(0.5), "Invalid input") diff --git a/solutions/tests/test_armstrong_number.py b/solutions/tests/test_armstrong_number.py deleted file mode 100644 index e69de29bb..000000000 From 41a88f5f56462dfddf901bf5578d8adb4cd9fe1a Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Sat, 4 Jan 2025 12:38:57 +0400 Subject: [PATCH 085/151] Writing test cases for the function robot and fixing bugs --- solutions/robot.py | 14 +++++--- solutions/tests/test_robot.py | 62 +++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 8 deletions(-) diff --git a/solutions/robot.py b/solutions/robot.py index c3862c7ab..e141e8fbb 100644 --- a/solutions/robot.py +++ b/solutions/robot.py @@ -22,7 +22,7 @@ def robot_move(cell, rows, cols, memo) -> int: Parameters: cell: a tuple made of two elements refers to the current location - inside the grid + inside the grid - immutable, can be used as a key for dicts rows: The number of rows in the grid. cols: The number of columns in the grid. memo: a dictionary to save answers for memoization @@ -30,12 +30,16 @@ def robot_move(cell, rows, cols, memo) -> int: Returns -> The number of unique paths from the top-left corner to the bottom-right corner. """ + # if the cell is stored in the memo dict we return it if memo.get(cell): return memo.get(cell) + # if the cell is directly perpendicular to target, there's only one road if cell[1] >= cols - 1 or cell[0] >= rows - 1: return 1 + # otherwise, there's two roads to take, the answer is the sum of both memo[cell] = robot_move((cell[0] + 1, cell[1]), rows, cols, memo) + \ robot_move((cell[0], cell[1] + 1), rows, cols, memo) + # we save the answer in the memo for future referance and return it return memo[cell] @@ -64,10 +68,10 @@ def robot(rows: int, cols: int) -> int: """ # assert the values of rows and clos and make sure they are ints and # greater than 1 - assert isinstance(rows, int) and rows > 1, "Rows variables has to \ - be an integer greater than 1" - assert isinstance(cols, int) and cols > 1, "Cols variable has to be \ - greater than 1" + assert isinstance(rows, int) and rows > 0, "Rows variables has to \ + be an integer greater than 0" + assert isinstance(cols, int) and cols > 0, "Cols variable has to be \ + greater than 0" # use the helper function robot_move to determine the number of paths memo = {} diff --git a/solutions/tests/test_robot.py b/solutions/tests/test_robot.py index e1141b2eb..459699d5b 100644 --- a/solutions/tests/test_robot.py +++ b/solutions/tests/test_robot.py @@ -11,10 +11,66 @@ """ import unittest - +from ..robot import robot class TestRobot(unittest.TestCase): """Test the robot function""" + # Standard Cases + def test_base_2x2(self): + """A basic test with a small grid 2x2""" + self.assertEqual(robot(2, 2), 2) + + def test_base_3x3(self): + """A basic test with a small grid 3x3""" + self.assertEqual(robot(3, 3), 6) + + def test_base_3x7(self): + """A basic test with a small grid of 3x7""" + self.assertEqual(robot(3, 7), 28) + + def test_base_4x3(self): + """A basic test with a grid of 4x3""" + self.assertEqual(robot(4, 3), 10) + + # Edge Cases + def test_long_narrow(self): + """A test for a long narrow grid of 1x10""" + self.assertEqual(robot(1, 10), 1) + + def test_tall_narrow(self): + """A test for a tall narrow grid 10x1""" + self.assertEqual(robot(10, 1), 1) + + def test_large_grid(self): + """A test for a moderately large grid 10x10""" + self.assertEqual(robot(10, 10), 48620) + + def test_very_large_grid(self): + """A test for a very largey grid 20x15""" + self.assertEqual(robot(20, 15), 818809200) + + # Defensive Cases + def test_invalid_row(self): + """A test for an invalid row input - not an integer""" + with self.assertRaises(AssertionError): + robot("3", 7) + + def test_invalid_col(self): + """A test for an invalid column input - not an integer""" + with self.assertRaises(AssertionError): + robot(3, "7") + + def test_negative_value(self): + """A test with a negative dimension""" + with self.assertRaises(AssertionError): + robot(-1, 5) + + def test_zero_value(self): + """A test with zero value""" + with self.assertRaises(AssertionError): + robot(3, 0) - def test_base(self): - """A basic test""" + def test_non_integer_input(self): + """A test wit a non integer input for both dimensions""" + with self.assertRaises(AssertionError): + robot(2.5, 3.7) From 647a4eafc88927a32551dd636383da262b107a42 Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Sat, 4 Jan 2025 12:45:02 +0400 Subject: [PATCH 086/151] fixing ruff linting errors --- solutions/robot.py | 11 ++++------- solutions/tests/test_robot.py | 4 +++- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/solutions/robot.py b/solutions/robot.py index e141e8fbb..dda695760 100644 --- a/solutions/robot.py +++ b/solutions/robot.py @@ -37,8 +37,9 @@ def robot_move(cell, rows, cols, memo) -> int: if cell[1] >= cols - 1 or cell[0] >= rows - 1: return 1 # otherwise, there's two roads to take, the answer is the sum of both - memo[cell] = robot_move((cell[0] + 1, cell[1]), rows, cols, memo) + \ - robot_move((cell[0], cell[1] + 1), rows, cols, memo) + memo[cell] = robot_move((cell[0] + 1, cell[1]), rows, cols, memo) + robot_move( + (cell[0], cell[1] + 1), rows, cols, memo + ) # we save the answer in the memo for future referance and return it return memo[cell] @@ -75,8 +76,4 @@ def robot(rows: int, cols: int) -> int: # use the helper function robot_move to determine the number of paths memo = {} - return robot_move((0, 0), rows, cols, memo) # (0, 0) is the initial spot - - -if __name__ == "__main__": - print(robot(23, 12)) + return robot_move((0, 0), rows, cols, memo) # (0, 0) is the initial spot diff --git a/solutions/tests/test_robot.py b/solutions/tests/test_robot.py index 459699d5b..777f66803 100644 --- a/solutions/tests/test_robot.py +++ b/solutions/tests/test_robot.py @@ -13,8 +13,10 @@ import unittest from ..robot import robot + class TestRobot(unittest.TestCase): """Test the robot function""" + # Standard Cases def test_base_2x2(self): """A basic test with a small grid 2x2""" @@ -46,7 +48,7 @@ def test_large_grid(self): self.assertEqual(robot(10, 10), 48620) def test_very_large_grid(self): - """A test for a very largey grid 20x15""" + """A test for a very large grid 20x15""" self.assertEqual(robot(20, 15), 818809200) # Defensive Cases From 55746c157837b557ebb79477abadef64a39b08e7 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Sat, 4 Jan 2025 13:07:37 +0400 Subject: [PATCH 087/151] adding comments to describe the code functions --- solutions/armstrong_checker.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/solutions/armstrong_checker.py b/solutions/armstrong_checker.py index 794f203de..087d35cfb 100644 --- a/solutions/armstrong_checker.py +++ b/solutions/armstrong_checker.py @@ -28,8 +28,15 @@ def armstrong_checker(number: int) -> str: if not isinstance(number, int) or number < 0: return "Invalid input" + # Calculate the sum of the nth power of each digit in the number. digits = [int(d) for d in str(number)] + # digits puts each digit in the number into a list + n = len(digits) + # n is the number of digits in the number by using the len() function + armstrong_sum = sum(d**n for d in digits) + # armstrong_sum is the sum of the nth power of each digit in the number return "True" if armstrong_sum == number else "False" + # if the sum of the nth power of each digit in the number is equal to the number, return "True", otherwise return "False" From e1add4393e14518924c47b00a9ad4530f577f9f4 Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Sat, 4 Jan 2025 18:39:16 +0200 Subject: [PATCH 088/151] missed one docstring --- solutions/tests/test_copy_from_file_to_file.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solutions/tests/test_copy_from_file_to_file.py b/solutions/tests/test_copy_from_file_to_file.py index 0fea78e35..81d92e242 100644 --- a/solutions/tests/test_copy_from_file_to_file.py +++ b/solutions/tests/test_copy_from_file_to_file.py @@ -15,6 +15,8 @@ class TestCopyFromFileToFile(unittest.TestCase): + """Tests different cases when copying from one file to another""" + def test_des_not_exist(self): """This method test if Destination doesn't exist""" source_file = "solutions/source.txt" From 8261b38f721515791c6d3d7a3a8431c3ee718976 Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Sat, 4 Jan 2025 20:47:46 +0400 Subject: [PATCH 089/151] fixing Ruff linter --- solutions/fuel_gauge.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py index 641d65345..71091e5b4 100644 --- a/solutions/fuel_gauge.py +++ b/solutions/fuel_gauge.py @@ -1,3 +1,6 @@ +"""module calculates the percentage of fuel in a tank and returns a status indicator.""" + + def fuel_gauge(x: int, y: int) -> str: """ Calculates the percentage of fuel in a tank and returns a status indicator. @@ -7,7 +10,7 @@ def fuel_gauge(x: int, y: int) -> str: y (int): Tank capacity (must be > 0). Returns: - str: + str: - "F" if percentage >= 90. - "E" if percentage <= 10. - "M" for all other cases. From b2729d4f565259c4e08ab53734f0136094945f7c Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Sat, 4 Jan 2025 18:51:14 +0200 Subject: [PATCH 090/151] edits for docstring --- solutions/tests/test_copy_from_file_to_file.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/solutions/tests/test_copy_from_file_to_file.py b/solutions/tests/test_copy_from_file_to_file.py index 81d92e242..9c5a99c82 100644 --- a/solutions/tests/test_copy_from_file_to_file.py +++ b/solutions/tests/test_copy_from_file_to_file.py @@ -10,7 +10,9 @@ Returns -> None-The method performs the copying operation but does not return anything - Raises: AssertionError + Raises: + AssertionError: if the source file does not exist + AssertionError: if the source file or destination file is not a txt file """ From 82db1818f82abb657f58e51862253a552825e903 Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Sat, 4 Jan 2025 18:55:03 +0200 Subject: [PATCH 091/151] edits for docstring --- solutions/copy_from_file_to_file.py | 49 ++++++++++++++++++++ solutions/tests/test_word_count_from_file.py | 4 +- 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 solutions/copy_from_file_to_file.py diff --git a/solutions/copy_from_file_to_file.py b/solutions/copy_from_file_to_file.py new file mode 100644 index 000000000..a23e14d44 --- /dev/null +++ b/solutions/copy_from_file_to_file.py @@ -0,0 +1,49 @@ +import os + +""" + This Module can copy content from one file to another + + Module contents: + - .txt file: the file to read the content from + - .txt file: the file to write the content to + +created on 1 Jan 2025 "Happy new year" +@author: saja abusafia + +""" + + +def copy_file_to_file(source_file, destination_file): + """ + The function copies the content from one file to another file + + + Parameters: + source_file (str): the file to read the conent from + destination_file(str): the file to add the content to + + Returns: + none-The function performs the copying operation but does not return + anything + + + >>> copy_file_to_file("solutions/source.txt","solutions/destination.txt") + + + + """ + assert os.path.exists( + source_file + ), f"Error: Source file '{source_file}' doesn't exist." + assert source_file.endswith( + ".txt" + ), f"Error: Source file '{source_file}' is not a .txt file." + assert destination_file.endswith( + ".txt" + ), f"Error: Destination file '{destination_file}' is not a .txt file." + + with open(source_file, "r") as file_from: + file_content = file_from.read() + + with open(destination_file, "w") as file_to: + file_to.write(file_content) diff --git a/solutions/tests/test_word_count_from_file.py b/solutions/tests/test_word_count_from_file.py index ea3b6dac8..8030b0acd 100644 --- a/solutions/tests/test_word_count_from_file.py +++ b/solutions/tests/test_word_count_from_file.py @@ -10,7 +10,9 @@ Returns -> The total number of words in the file. -Raises: AssertionError +Raises: + AssertionError: if the file does not exist + AssertionError: if the file is not a .txt file """ From 19c32e9122f9e1518707f8920f6cd16aac94258a Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Sat, 4 Jan 2025 18:59:20 +0200 Subject: [PATCH 092/151] added one docstring --- solutions/word_count_from_file.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/solutions/word_count_from_file.py b/solutions/word_count_from_file.py index 2953073dc..2e721a342 100644 --- a/solutions/word_count_from_file.py +++ b/solutions/word_count_from_file.py @@ -21,6 +21,10 @@ def word_count_txt_file(file_name) -> int: Returns: int n: The total number of words + Raises: + AssertionError: if the file does not exist + AssertionError: if the file is not a .txt file + >>> word_count_txt_file("solutions/test_5.txt") 5 From 3cc9d24c581ab0221f806f47f9bdb36467dba1d1 Mon Sep 17 00:00:00 2001 From: ayhm01 Date: Sat, 4 Jan 2025 19:09:20 +0200 Subject: [PATCH 093/151] Revert "Merge branch 'main' of github.com:MIT-Emerging-Talent/ET6-foundations-group-27 into ayham/substitution_cipher" This reverts commit 9d534a47442aa6a23b13b4a03c7e8dae5289ab69, reversing changes made to da575ecb09e773d5cbd6576a8ade2bc9354f91ed. --- .github/PULL_REQUEST_TEMPLATE.md | 3 --- solutions/fuel_gauge.py | 20 -------------------- solutions/tests/test_fuel_gauge.py | 30 ------------------------------ 3 files changed, 53 deletions(-) delete mode 100644 solutions/fuel_gauge.py delete mode 100644 solutions/tests/test_fuel_gauge.py diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 6e269b4ad..330a04cbc 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -55,7 +55,6 @@ about: A template PR for code review with a checklist - [ ] The function's name describes it's behavior - [ ] The function's name matches the file name - [ ] The function has correct type annotations -- [ ] The function is not called in the function file ## Strategy @@ -83,7 +82,5 @@ about: A template PR for code review with a checklist - [ ] Variable names are clear and helpful - [ ] The code follows the strategy as simply as possible - [ ] The implementation is as simple as possible given the strategy -- [ ] There are no commented lines of code -- [ ] There are no `print` statements anywhere - [ ] The code includes defensive assertions - [ ] Defensive assertions include as little logic as possible diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py deleted file mode 100644 index 551098ee9..000000000 --- a/solutions/fuel_gauge.py +++ /dev/null @@ -1,20 +0,0 @@ -def fuel_gauge(x, y): - """ - This is a function that calculates the percentage of fuel in a tank. - - Parameters: - X= fuel in the tank (x value must be less than or equal to y) - Y= tank capacity (y value must be greater than 0)""" - if y == 0 or x > y: - """This is a condition that checks if the tank size is zero or if the fuel is more than the tank capacity.""" - return "Invalid input" - - percentage = (x / y) * 100 - """This is a formula that calculates the percentage of fuel in the tank.""" - if percentage >= 90: - return "F" - elif percentage > 10: - return "M" - elif percentage <= 10: - return "E" - return int(percentage) diff --git a/solutions/tests/test_fuel_gauge.py b/solutions/tests/test_fuel_gauge.py deleted file mode 100644 index d1d8aed8a..000000000 --- a/solutions/tests/test_fuel_gauge.py +++ /dev/null @@ -1,30 +0,0 @@ -import unittest - -from ..fuel_gauge import fuel_gauge - - -class TestFuelGauge(unittest.TestCase): - """Test cases for the fuel_gauge function.""" - - def test_full(self): - """Test cases where the percentage is 90% or more it should result in F.""" - self.assertEqual(fuel_gauge(90, 100), "F") - self.assertEqual(fuel_gauge(100, 100), "F") - self.assertEqual(fuel_gauge(97, 100), "F") - - def test_empty(self): - """Test cases where the percentage is 10% or less it should result E.""" - self.assertEqual(fuel_gauge(10, 100), "E") - self.assertEqual(fuel_gauge(0, 100), "E") - self.assertEqual(fuel_gauge(2, 100), "E") - - def test_percentage(self): - """Test cases where the result is between 90 and 10 it should be M.""" - self.assertEqual(fuel_gauge(71, 100), "M") - self.assertEqual(fuel_gauge(23, 100), "M") - self.assertEqual(fuel_gauge(10, 50), "M") - - def test_invalid_input(self): - """Test cases for invalid inputs.""" - self.assertEqual(fuel_gauge(6, 0), "Invalid input") - self.assertEqual(fuel_gauge(7, -1), "Invalid input") From 0d6e7bc8479f6d4a16ee487eee477362805ad259 Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Sat, 4 Jan 2025 19:13:46 +0200 Subject: [PATCH 094/151] docstring modification --- solutions/copy_from_file_to_file.py | 7 +++++-- solutions/tests/test_copy_from_file_to_file.py | 3 +-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/solutions/copy_from_file_to_file.py b/solutions/copy_from_file_to_file.py index 4ee07a3cf..81fee7f7b 100644 --- a/solutions/copy_from_file_to_file.py +++ b/solutions/copy_from_file_to_file.py @@ -7,8 +7,8 @@ - .txt file: the file to read the content from - .txt file: the file to write the content to -created on 1 Jan 2025 "Happy new year" -@author: saja abusafia + created on 1 Jan 2025 "Happy new year" + @author: saja abusafia """ @@ -25,6 +25,9 @@ def copy_file_to_file(source_file, destination_file): Returns: none-The function performs the copying operation but does not return anything + Raises: + AssertionError: if the source file does not exist + AssertionError: if the source or destination file is not a txt file >>> copy_file_to_file("solutions/source.txt","solutions/destination.txt") diff --git a/solutions/tests/test_copy_from_file_to_file.py b/solutions/tests/test_copy_from_file_to_file.py index 9c5a99c82..64101a3a0 100644 --- a/solutions/tests/test_copy_from_file_to_file.py +++ b/solutions/tests/test_copy_from_file_to_file.py @@ -7,10 +7,9 @@ Parameters: source_file (str): the file to read the conent from Destination_file(str): the file to add the content to - Returns -> None-The method performs the copying operation but does not return anything - Raises: + Raises: AssertionError: if the source file does not exist AssertionError: if the source file or destination file is not a txt file """ From 9c79077998570dc4628ff7fb67e1b6fb32c749d0 Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Sat, 4 Jan 2025 19:20:52 +0200 Subject: [PATCH 095/151] docstring modifications --- solutions/tests/test_word_count_from_file.py | 13 ++++++++----- solutions/word_count_from_file.py | 1 - 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/solutions/tests/test_word_count_from_file.py b/solutions/tests/test_word_count_from_file.py index 8030b0acd..82d75dd4c 100644 --- a/solutions/tests/test_word_count_from_file.py +++ b/solutions/tests/test_word_count_from_file.py @@ -10,7 +10,7 @@ Returns -> The total number of words in the file. -Raises: +Raises: AssertionError: if the file does not exist AssertionError: if the file is not a .txt file """ @@ -21,15 +21,18 @@ class TestWordCountFromFile(unittest.TestCase): def test_5(self): """This method test if the function returns the correct number""" - self.assertEqual(word_count_txt_file("solutions/test_5.txt"), 5) + actual = word_count_txt_file("solutions/test_5.txt") + self.assertEqual(actual, 5) def test_empty(self): """This method test an empty file""" - self.assertEqual(word_count_txt_file("solutions/test_empty.txt"), 0) + actual = word_count_txt_file("solutions/test_empty.txt") + self.assertEqual(actual, 0) def test_multiple_lines(self): """This method test when a file has multiple lines""" - self.assertEqual(word_count_txt_file("solutions/test_multiple.txt"), 10) + actual = word_count_txt_file("solutions/test_multiple.txt") + self.assertEqual(actual, 10) def test_file_not_exist(self): """This method test when a file has multiple lines""" @@ -37,6 +40,6 @@ def test_file_not_exist(self): word_count_txt_file("not_exist.txt") def test_not_a_txt_file(self): - """It should raise an assertion error if the argument is not an integer""" + """It should raise an error if the argument is not an integer""" with self.assertRaises(AssertionError): word_count_txt_file("test") diff --git a/solutions/word_count_from_file.py b/solutions/word_count_from_file.py index 2e721a342..559b762c1 100644 --- a/solutions/word_count_from_file.py +++ b/solutions/word_count_from_file.py @@ -18,7 +18,6 @@ def word_count_txt_file(file_name) -> int: Parameters: String: file_name (str): the file name to read the content from - Returns: int n: The total number of words Raises: From 2423cae8576fe757b454afb4e756cd366893ab41 Mon Sep 17 00:00:00 2001 From: Safi222 Date: Sat, 4 Jan 2025 20:22:18 +0300 Subject: [PATCH 096/151] adding assertions --- solutions/LowestCommonAncestor_in_BST.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/solutions/LowestCommonAncestor_in_BST.py b/solutions/LowestCommonAncestor_in_BST.py index 3a5efe452..7a90c807f 100644 --- a/solutions/LowestCommonAncestor_in_BST.py +++ b/solutions/LowestCommonAncestor_in_BST.py @@ -22,6 +22,9 @@ def lowestCommonAncestor(root: "TreeNode", p: "TreeNode", q: "TreeNode") -> "Tre Returns: TreeNode: The Lowest Common Ancestor of nodes p and q. + Raises: + ValueError: If any of the inputs (root, p, or q) is None. + Notes: - If both p and q are smaller than the current node, the LCA is in the left subtree. - If both p and q are larger than the current node, the LCA is in the right subtree. @@ -54,8 +57,13 @@ def lowestCommonAncestor(root: "TreeNode", p: "TreeNode", q: "TreeNode") -> "Tre Input: root = [5,3,8,1,4,7,9,null,2], p = 3, q = 4 Output: 3 """ + + # Check if root, p, or q are None and raise ValueError if so + if root is None or p is None or q is None: + raise ValueError("None of the inputs (root, p, q) can be None.") + candidate = root - # this tree satisfy BTS properties + # this tree satisfies BST properties while candidate: if p.value > candidate.value and q.value > candidate.value: candidate = candidate.right From 24a781f11c1d82e7bde0bd1901ede168c2f66521 Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Sat, 4 Jan 2025 19:24:52 +0200 Subject: [PATCH 097/151] delete dublicated file --- solutions/copy_from_file_to_file.py | 49 ----------------------------- 1 file changed, 49 deletions(-) delete mode 100644 solutions/copy_from_file_to_file.py diff --git a/solutions/copy_from_file_to_file.py b/solutions/copy_from_file_to_file.py deleted file mode 100644 index a23e14d44..000000000 --- a/solutions/copy_from_file_to_file.py +++ /dev/null @@ -1,49 +0,0 @@ -import os - -""" - This Module can copy content from one file to another - - Module contents: - - .txt file: the file to read the content from - - .txt file: the file to write the content to - -created on 1 Jan 2025 "Happy new year" -@author: saja abusafia - -""" - - -def copy_file_to_file(source_file, destination_file): - """ - The function copies the content from one file to another file - - - Parameters: - source_file (str): the file to read the conent from - destination_file(str): the file to add the content to - - Returns: - none-The function performs the copying operation but does not return - anything - - - >>> copy_file_to_file("solutions/source.txt","solutions/destination.txt") - - - - """ - assert os.path.exists( - source_file - ), f"Error: Source file '{source_file}' doesn't exist." - assert source_file.endswith( - ".txt" - ), f"Error: Source file '{source_file}' is not a .txt file." - assert destination_file.endswith( - ".txt" - ), f"Error: Destination file '{destination_file}' is not a .txt file." - - with open(source_file, "r") as file_from: - file_content = file_from.read() - - with open(destination_file, "w") as file_to: - file_to.write(file_content) From e48ef708634d387491203965a0153c21dedb264f Mon Sep 17 00:00:00 2001 From: mxz Date: Sat, 4 Jan 2025 21:10:37 +0200 Subject: [PATCH 098/151] adding my code --- .vscode/settings.json | 9 +++++--- solutions/game_greeting.py | 32 +++++++++++++++++++++++++++ solutions/tests/test_game_greeting.py | 23 +++++++++++++++++++ 3 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 solutions/game_greeting.py create mode 100644 solutions/tests/test_game_greeting.py diff --git a/.vscode/settings.json b/.vscode/settings.json index bbda5188d..3472299b2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -119,8 +119,11 @@ "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" } - } + }, + "cSpell.words": [ + "Testgamegreeting" + ] } diff --git a/solutions/game_greeting.py b/solutions/game_greeting.py new file mode 100644 index 000000000..f5d86ca8c --- /dev/null +++ b/solutions/game_greeting.py @@ -0,0 +1,32 @@ +""" +Module: generate a game welcome message + +the Module provides a function that generates a welcome message for a player joining a game. + +""" +# the function: + + +def game_greeting(name: str) -> str: + """ + the player inters his name as an input and in return he gets + a greeting welcome massage. + + + parameters: + name (string)- The player's name. can be empty string or special characters. + + Returns: + string- A formatted Welcome message in the form: + "Welcome, [name] to the game" + + Raises: + assertionError : if name is not a string + + Example: + >>> game_greeting({Mohamed}) + "Welcome, Mohamed to the game" + + """ + assert isinstance(name, str) + return f"Welcome, {name} to the game" diff --git a/solutions/tests/test_game_greeting.py b/solutions/tests/test_game_greeting.py new file mode 100644 index 000000000..71838ad1e --- /dev/null +++ b/solutions/tests/test_game_greeting.py @@ -0,0 +1,23 @@ +import unittest + +from ..game_greeting import game_greeting + + +class TestGameGreeting(unittest.TestCase): + # test game greeting function + def test_valid_name(self): + # test the function with a valid name + self.assertEqual(game_greeting("Mohamed"), "Welcome, Mohamed to the game") + + def test_empty_string(self): + # test the function with an empty string + self.assertEqual(game_greeting(""), "Welcome, to the game") + + def test_special_characters(self): + # test the function with special characters + self.assertEqual(game_greeting("mx@z*"), "Welcome, mx@z* to the game") + + def test_integers(self): + # test the function with integers + with self.assertRaises(AssertionError): + (game_greeting(573)) From 119895826cfceb748b79d0c474012fe4b8efd7c5 Mon Sep 17 00:00:00 2001 From: Safi222 Date: Sat, 4 Jan 2025 22:28:52 +0300 Subject: [PATCH 099/151] testing assertions --- .../tests/test_LowestCommonAncestor_in_BST.py | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/solutions/tests/test_LowestCommonAncestor_in_BST.py b/solutions/tests/test_LowestCommonAncestor_in_BST.py index 639af3e24..0826abd22 100644 --- a/solutions/tests/test_LowestCommonAncestor_in_BST.py +++ b/solutions/tests/test_LowestCommonAncestor_in_BST.py @@ -5,7 +5,6 @@ """ import unittest - from solutions.LowestCommonAncestor_in_BST import lowestCommonAncestor @@ -43,6 +42,7 @@ def setUp(self): self.root.right.right = TreeNode(9) self.root.left.left.right = TreeNode(2) + # Basic cases def test_level_1(self): """Test LCA of node 3 and node 8 on the same level""" p = self.root.left @@ -52,8 +52,8 @@ def test_level_1(self): def test_different_levels_case_1(self): """Test LCA for node 2 and node 9 on different levels""" - p = self.root.left.left.right # Node 2 - q = self.root.right.right # Node 9 + p = self.root.left.left.right + q = self.root.right.right candidate = lowestCommonAncestor(self.root, p, q) self.assertEqual(candidate.value, 5) @@ -85,9 +85,26 @@ def test_different_levels_root_2(self): candidate = lowestCommonAncestor(self.root, p, q) self.assertEqual(candidate.value, 5) + # Edge cases def test_ancestor_is_the_node_itself(self): """Test LCA where the ancestor is one of the nodes itself (3, 4)""" p = self.root.left q = self.root.left.right candidate = lowestCommonAncestor(self.root, p, q) self.assertEqual(candidate.value, 3) + + # AssertionError test cases + def test_assertion_error_root_none(self): + """Test when root is None""" + with self.assertRaises(ValueError): + lowestCommonAncestor(None, self.root.left, self.root.right) + + def test_assertion_error_p_none(self): + """Test when p is None""" + with self.assertRaises(ValueError): + lowestCommonAncestor(self.root, None, self.root.right) + + def test_assertion_error_q_none(self): + """Test when q is None""" + with self.assertRaises(ValueError): + lowestCommonAncestor(self.root, self.root.left, None) From 8d16abd9da49d5376235f4e8a5688434e590d789 Mon Sep 17 00:00:00 2001 From: mxz Date: Sat, 4 Jan 2025 22:22:50 +0200 Subject: [PATCH 100/151] adding the code files --- solutions/stars_draw.py | 0 solutions/tests/test_stars_draw.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 solutions/stars_draw.py create mode 100644 solutions/tests/test_stars_draw.py diff --git a/solutions/stars_draw.py b/solutions/stars_draw.py new file mode 100644 index 000000000..e69de29bb diff --git a/solutions/tests/test_stars_draw.py b/solutions/tests/test_stars_draw.py new file mode 100644 index 000000000..e69de29bb From 62a781add2b787c689646701302107809d8fa0f4 Mon Sep 17 00:00:00 2001 From: RAFAA ALI Date: Sun, 5 Jan 2025 01:15:39 +0400 Subject: [PATCH 101/151] fixing importing issues --- solutions/FooBar_code.py | 4 +- solutions/count_characters.py | 67 ++++++++++++++++++++++++ solutions/tests/test_FooBar_code.py | 4 +- solutions/tests/test_count_characters.py | 57 ++++++++++++++++++++ 4 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 solutions/count_characters.py create mode 100644 solutions/tests/test_count_characters.py diff --git a/solutions/FooBar_code.py b/solutions/FooBar_code.py index d73611426..8c5bf9fe3 100644 --- a/solutions/FooBar_code.py +++ b/solutions/FooBar_code.py @@ -13,10 +13,10 @@ def FooBar_code(n: int): based on their divisibility by 4 and 6. Parameters: - n (int):the last number in the list + n (int):the last number in the list Returns: - List containing the sequence with 'Foo', 'Bar', 'FooBar' or numbers + List containing the sequence with 'Foo', 'Bar', 'FooBar' or numbers assertion: n must be integer otherwise error diff --git a/solutions/count_characters.py b/solutions/count_characters.py new file mode 100644 index 000000000..d30cd0d12 --- /dev/null +++ b/solutions/count_characters.py @@ -0,0 +1,67 @@ +""" +Creates a function that counts the number of vowels (a, e, i, o, u) in a given string. +The function is case-insensitive, meaning both uppercase and lowercase vowels are counted. + +Author: Rafaa Ali +Created date: 3.1.2025 +""" + + +def count_characters(string: str) -> int: + """This function, `count_vowels`, counts the number of vowels in a given string, + ignoring case sensitivity. + + Parameters: + string (str): The input string to count vowels from + + Returns: + int: The total number of vowels in the string + + assertion: + string must be string type otherwise error + + example: + Edge cases: + >>> count_characters("") + 0 + >>> count_characters("krm") + 0 + >>> count_characters(" ") + 0 + + Standard cases: + >>> count_characters lowercase("hello") + 2 + >>> count_characters uppercase("RAFF") + 1 + >>>count_characters mixed case("aEiOu") + 5 + + Defensive cases: + >>> count_characters(123) + AssertionError: Input must be string + >>>count_characters(["hello"]) + AssertionError: Input must be string + >>> count_characters(None) + AssertionError: Input must be string + """ + # assert an error when input is not string + assert isinstance(string, str), "Input must be string" + + # Convert string to lowercase for case-insensitive counting + string = string.lower() + + # Define vowels to check against + vowels = "aeiou" + + # Initialize counter for vowels + count = 0 + + # Loop through each character in the string + for char in string: + # If character is a vowel, increment counter + if char in vowels: + count += 1 + + # Return the total count of vowels + return count diff --git a/solutions/tests/test_FooBar_code.py b/solutions/tests/test_FooBar_code.py index 412a520b7..33e4c2a32 100644 --- a/solutions/tests/test_FooBar_code.py +++ b/solutions/tests/test_FooBar_code.py @@ -1,9 +1,11 @@ +"""test module for FooBar_code function""" import unittest -from ..FooBar_code import FooBar_code +from FooBar_code import FooBar_code class TestFooBar(unittest.TestCase): + """ this class to test FooBar_code function """ # Edge cases: def test_int1(self): """check if the input is 1""" diff --git a/solutions/tests/test_count_characters.py b/solutions/tests/test_count_characters.py new file mode 100644 index 000000000..7493f3532 --- /dev/null +++ b/solutions/tests/test_count_characters.py @@ -0,0 +1,57 @@ +import unittest +from .. count_characters import count_characters + +class Testcount_characters(unittest.TestCase): + # Edge cases: + def test_empty_string(self): + """check if the input is empty string""" + self.assertEqual(count_characters(""), 0) + + def test_no_vowels(self): + """check if string has no vowels""" + self.assertEqual(count_characters("krm"), 0) + + """check if string is just whitespace""" + self.assertEqual(count_characters(" "), 0) + + # Standard cases: + def test_lowercase_word(self): + """check if handles lowercase correctly""" + self.assertEqual(count_characters("hello"), 2) + + def test_uppercase_word(self): + """check if handles uppercase correctly""" + self.assertEqual(count_characters("RAFF"), 1) + + def test_mixed_case(self): + """check if handles mixed case correctly""" + self.assertEqual(count_characters("aEiOu"), 5) + + def test_sentence(self): + """check if handles full sentence correctly""" + self.assertEqual(count_characters("Hello World"), 3) + + def test_all_vowels(self): + """check if counts all vowel types correctly""" + self.assertEqual(count_characters("AeIoU"), 5) + + # defensive cases + def test_number_input(self): + """It should raise AssertionError for integer input""" + with self.assertRaises(AssertionError): + count_characters(123) + + def test_list_input(self): + """It should raise AssertionError for list input""" + with self.assertRaises(AssertionError): + count_characters(["hello"]) + + def test_none_input(self): + """It should raise AssertionError for None input""" + with self.assertRaises(AssertionError): + count_characters(None) + + def test_float_input(self): + """It should raise AssertionError for float input""" + with self.assertRaises(AssertionError): + count_characters(3.14) \ No newline at end of file From 32be9d9998c8f04462933167e96f4bb21491b216 Mon Sep 17 00:00:00 2001 From: RAFAA ALI Date: Sun, 5 Jan 2025 01:27:55 +0400 Subject: [PATCH 102/151] fixing more issues --- solutions/tests/test_FooBar_code.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/solutions/tests/test_FooBar_code.py b/solutions/tests/test_FooBar_code.py index 33e4c2a32..3eb613132 100644 --- a/solutions/tests/test_FooBar_code.py +++ b/solutions/tests/test_FooBar_code.py @@ -1,11 +1,13 @@ """test module for FooBar_code function""" + import unittest -from FooBar_code import FooBar_code +from solutions.FooBar_code import FooBar_code class TestFooBar(unittest.TestCase): - """ this class to test FooBar_code function """ + """this class to test FooBar_code function""" + # Edge cases: def test_int1(self): """check if the input is 1""" From 1927605cffa83413b03d572c9438d0246c21a407 Mon Sep 17 00:00:00 2001 From: RAFAA ALI Date: Sun, 5 Jan 2025 03:31:56 +0400 Subject: [PATCH 103/151] fixing issues --- solutions/FooBar_code.py | 51 ++++++++---------- solutions/count_characters.py | 67 ------------------------ solutions/tests/test_FooBar_code.py | 28 +++++----- solutions/tests/test_count_characters.py | 57 -------------------- 4 files changed, 37 insertions(+), 166 deletions(-) delete mode 100644 solutions/count_characters.py delete mode 100644 solutions/tests/test_count_characters.py diff --git a/solutions/FooBar_code.py b/solutions/FooBar_code.py index 8c5bf9fe3..5b0f25329 100644 --- a/solutions/FooBar_code.py +++ b/solutions/FooBar_code.py @@ -9,21 +9,19 @@ def FooBar_code(n: int): - """This function, `FooBar_code`, creates a sequence that replaces numbers + """This function, FooBar_code, creates a sequence that replaces numbers based on their divisibility by 4 and 6. Parameters: - n (int):the last number in the list + n (int): The last number in the list. Returns: - List containing the sequence with 'Foo', 'Bar', 'FooBar' or numbers + List: A list containing the sequence with 'Foo', 'Bar', 'FooBar' or numbers. - assertion: - n must be integer otherwise error + Assertions: + n must be an integer; otherwise, an error will be raised. - - example: - Edge cases: + Example: >>> FooBar_code(1) [1] >>> FooBar_code(0) @@ -37,39 +35,36 @@ def FooBar_code(n: int): >>> FooBar_code(12) [1, 2, 3, 'Foo', 5, 'Bar', 7, 'Foo', 9, 10, 11, 'FooBar'] >>> FooBar_code(16) - [1, 2, 3, 'Foo', 5, 'Bar', 7, 'Foo', 9, 10, 11, 'FooBar', - 13, 14, 15, 'Foo'] + [1, 2, 3, 'Foo', 5, 'Bar', 7, 'Foo', 9, 10, 11, 'FooBar', 13, 14, 15, 'Foo'] Defensive cases: >>> FooBar_code("rafaa") - AssertionError: N must be integer + AssertionError: n must be an integer >>> FooBar_code(5.5) - AssertionError: N must be integer + AssertionError: n must be an integer >>> FooBar_code([1, 2, 3]) - AssertionError: N must be integer - - + AssertionError: n must be an integer """ - # assert an error when n is not integer - assert isinstance(n, int), "N must be integer" - # prepare empty list for the result + # Assert an error when n is not an integer + assert isinstance(n, int), "n must be an integer" + + # Prepare an empty list for the result result = [] - # loop for checking the sequence + + # Loop for checking the sequence for i in range(1, n + 1): - # checking if the number is devisable by 4 and 6 + # Check if the number is divisible by both 4 and 6 if i % 4 == 0 and i % 6 == 0: - # add FooBar to the list if it devisable by both 4,6 result.append("FooBar") - # checking if the number is devisable by 4 + # Check if the number is divisible by 4 elif i % 4 == 0: - # add Foo to the list if it devisable by 4 - result.append("foo") - # checking if the number is devisable by 6 + result.append("Foo") + # Check if the number is divisible by 6 elif i % 6 == 0: - # add Bar to the list if it devisable by 6 result.append("Bar") - # otherwise add the number to the list + # Otherwise, add the number to the list else: result.append(i) - # return the result's list + + # Return the result's list return result diff --git a/solutions/count_characters.py b/solutions/count_characters.py deleted file mode 100644 index d30cd0d12..000000000 --- a/solutions/count_characters.py +++ /dev/null @@ -1,67 +0,0 @@ -""" -Creates a function that counts the number of vowels (a, e, i, o, u) in a given string. -The function is case-insensitive, meaning both uppercase and lowercase vowels are counted. - -Author: Rafaa Ali -Created date: 3.1.2025 -""" - - -def count_characters(string: str) -> int: - """This function, `count_vowels`, counts the number of vowels in a given string, - ignoring case sensitivity. - - Parameters: - string (str): The input string to count vowels from - - Returns: - int: The total number of vowels in the string - - assertion: - string must be string type otherwise error - - example: - Edge cases: - >>> count_characters("") - 0 - >>> count_characters("krm") - 0 - >>> count_characters(" ") - 0 - - Standard cases: - >>> count_characters lowercase("hello") - 2 - >>> count_characters uppercase("RAFF") - 1 - >>>count_characters mixed case("aEiOu") - 5 - - Defensive cases: - >>> count_characters(123) - AssertionError: Input must be string - >>>count_characters(["hello"]) - AssertionError: Input must be string - >>> count_characters(None) - AssertionError: Input must be string - """ - # assert an error when input is not string - assert isinstance(string, str), "Input must be string" - - # Convert string to lowercase for case-insensitive counting - string = string.lower() - - # Define vowels to check against - vowels = "aeiou" - - # Initialize counter for vowels - count = 0 - - # Loop through each character in the string - for char in string: - # If character is a vowel, increment counter - if char in vowels: - count += 1 - - # Return the total count of vowels - return count diff --git a/solutions/tests/test_FooBar_code.py b/solutions/tests/test_FooBar_code.py index 3eb613132..f066f1c22 100644 --- a/solutions/tests/test_FooBar_code.py +++ b/solutions/tests/test_FooBar_code.py @@ -1,4 +1,4 @@ -"""test module for FooBar_code function""" +"""Test module for FooBar_code function""" import unittest @@ -6,45 +6,45 @@ class TestFooBar(unittest.TestCase): - """this class to test FooBar_code function""" + """This class tests the FooBar_code function""" # Edge cases: def test_int1(self): - """check if the input is 1""" + """Check if the input is 1""" self.assertEqual(FooBar_code(1), [1]) def test_int0(self): - """check if the input is 0""" + """Check if the input is 0""" self.assertEqual(FooBar_code(0), []) def test_negative_int(self): - """check if the input is negative""" + """Check if the input is negative""" self.assertEqual(FooBar_code(-1), []) # Standard cases: def test_int8(self): - """check if the input is 8""" - self.assertEqual(FooBar_code(8), [1, 2, 3, "foo", 5, "Bar", 7, "foo"]) + """Check if the input is 8""" + self.assertEqual(FooBar_code(8), [1, 2, 3, "Foo", 5, "Bar", 7, "Foo"]) def test_int12(self): - """check if the input is 12""" + """Check if the input is 12""" self.assertEqual( - FooBar_code(12), [1, 2, 3, "foo", 5, "Bar", 7, "foo", 9, 10, 11, "FooBar"] + FooBar_code(12), [1, 2, 3, "Foo", 5, "Bar", 7, "Foo", 9, 10, 11, "FooBar"] ) def test_is_int(self): - """check if the input is large number""" + """Check if the input is a large number""" self.assertEqual( FooBar_code(16), [ 1, 2, 3, - "foo", + "Foo", 5, "Bar", 7, - "foo", + "Foo", 9, 10, 11, @@ -52,11 +52,11 @@ def test_is_int(self): 13, 14, 15, - "foo", + "Foo", ], ) - # defensive cases + # Defensive cases: def test_string_input(self): """It should raise AssertionError for string input""" with self.assertRaises(AssertionError): diff --git a/solutions/tests/test_count_characters.py b/solutions/tests/test_count_characters.py deleted file mode 100644 index 7493f3532..000000000 --- a/solutions/tests/test_count_characters.py +++ /dev/null @@ -1,57 +0,0 @@ -import unittest -from .. count_characters import count_characters - -class Testcount_characters(unittest.TestCase): - # Edge cases: - def test_empty_string(self): - """check if the input is empty string""" - self.assertEqual(count_characters(""), 0) - - def test_no_vowels(self): - """check if string has no vowels""" - self.assertEqual(count_characters("krm"), 0) - - """check if string is just whitespace""" - self.assertEqual(count_characters(" "), 0) - - # Standard cases: - def test_lowercase_word(self): - """check if handles lowercase correctly""" - self.assertEqual(count_characters("hello"), 2) - - def test_uppercase_word(self): - """check if handles uppercase correctly""" - self.assertEqual(count_characters("RAFF"), 1) - - def test_mixed_case(self): - """check if handles mixed case correctly""" - self.assertEqual(count_characters("aEiOu"), 5) - - def test_sentence(self): - """check if handles full sentence correctly""" - self.assertEqual(count_characters("Hello World"), 3) - - def test_all_vowels(self): - """check if counts all vowel types correctly""" - self.assertEqual(count_characters("AeIoU"), 5) - - # defensive cases - def test_number_input(self): - """It should raise AssertionError for integer input""" - with self.assertRaises(AssertionError): - count_characters(123) - - def test_list_input(self): - """It should raise AssertionError for list input""" - with self.assertRaises(AssertionError): - count_characters(["hello"]) - - def test_none_input(self): - """It should raise AssertionError for None input""" - with self.assertRaises(AssertionError): - count_characters(None) - - def test_float_input(self): - """It should raise AssertionError for float input""" - with self.assertRaises(AssertionError): - count_characters(3.14) \ No newline at end of file From aecfc5af0f78051f25b87ad09587574a1d35e8b9 Mon Sep 17 00:00:00 2001 From: mxz Date: Sun, 5 Jan 2025 17:03:19 +0200 Subject: [PATCH 104/151] adding test module --- solutions/game_greeting.py | 3 ++- solutions/tests/test_game_greeting.py | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/solutions/game_greeting.py b/solutions/game_greeting.py index f5d86ca8c..deb2b9177 100644 --- a/solutions/game_greeting.py +++ b/solutions/game_greeting.py @@ -28,5 +28,6 @@ def game_greeting(name: str) -> str: "Welcome, Mohamed to the game" """ - assert isinstance(name, str) + assert isinstance(name, str), "Name should be string" + return f"Welcome, {name} to the game" diff --git a/solutions/tests/test_game_greeting.py b/solutions/tests/test_game_greeting.py index 71838ad1e..b6accfe67 100644 --- a/solutions/tests/test_game_greeting.py +++ b/solutions/tests/test_game_greeting.py @@ -1,3 +1,10 @@ +""" +test_game_greeting.py + +this module contains unit tests for the 'game_greeting' function. + +""" + import unittest from ..game_greeting import game_greeting From e3478d355582093bb7ecfb617361e0a2c30162cd Mon Sep 17 00:00:00 2001 From: mxz Date: Sun, 5 Jan 2025 17:14:58 +0200 Subject: [PATCH 105/151] adding a new test --- solutions/tests/test_game_greeting.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/solutions/tests/test_game_greeting.py b/solutions/tests/test_game_greeting.py index b6accfe67..de7fd81af 100644 --- a/solutions/tests/test_game_greeting.py +++ b/solutions/tests/test_game_greeting.py @@ -28,3 +28,7 @@ def test_integers(self): # test the function with integers with self.assertRaises(AssertionError): (game_greeting(573)) + + def test_whitespace_name(self): + # test the function with whitespace + self.assertEqual(game_greeting(" "), "Welcome, to the game") From d2dcdc1b8851225194ac03d75e4b71cb4a38a59b Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Sun, 5 Jan 2025 18:27:09 +0200 Subject: [PATCH 106/151] final edits --- solutions/{test_5.txt => test_5_words.txt} | 0 solutions/tests/test_word_count_from_file.py | 62 +++++++++++--------- solutions/word_count_from_file.py | 37 +++++++----- 3 files changed, 54 insertions(+), 45 deletions(-) rename solutions/{test_5.txt => test_5_words.txt} (100%) diff --git a/solutions/test_5.txt b/solutions/test_5_words.txt similarity index 100% rename from solutions/test_5.txt rename to solutions/test_5_words.txt diff --git a/solutions/tests/test_word_count_from_file.py b/solutions/tests/test_word_count_from_file.py index 82d75dd4c..7acd3f2fa 100644 --- a/solutions/tests/test_word_count_from_file.py +++ b/solutions/tests/test_word_count_from_file.py @@ -1,45 +1,49 @@ -import unittest - -from ..word_count_from_file import word_count_txt_file - """ -Counts the number of words in a .txt file. - -Parameters: - file_name (str) - The name of the file +Unit tests for the `word_count_txt_file` function. + +Tests the following scenarios: + - Correct word count for a file with a known number of words. + - Handling of an empty file. + - Word count for a file with multiple lines. + - Assertion errors for non-existent files. + - Assertion errors for non-.txt files. +""" -Returns -> The total number of words in the file. +import unittest -Raises: - AssertionError: if the file does not exist - AssertionError: if the file is not a .txt file -""" +from ..word_count_from_file import word_count_txt_file class TestWordCountFromFile(unittest.TestCase): - """Test the words counting function""" + """Unit tests for the `word_count_txt_file` function.""" - def test_5(self): - """This method test if the function returns the correct number""" - actual = word_count_txt_file("solutions/test_5.txt") - self.assertEqual(actual, 5) + def test_correct_word_count(self): + """Test if the method correctly counts words in a file with 5 words.""" + actual = word_count_txt_file("solutions/test_5_words.txt") + self.assertEqual(actual, 5, "The word count should be 5.") - def test_empty(self): - """This method test an empty file""" + def test_empty_file(self): + """Test if the method returns 0 for an empty file.""" actual = word_count_txt_file("solutions/test_empty.txt") - self.assertEqual(actual, 0) + self.assertEqual(actual, 0, "word count must be 0 for an empty file.") - def test_multiple_lines(self): - """This method test when a file has multiple lines""" + def test_multiple_lines_file(self): + """Test if the method correctly counts words in a multi-line file.""" actual = word_count_txt_file("solutions/test_multiple.txt") - self.assertEqual(actual, 10) + self.assertEqual( + actual, 10, "The word count should be 10 for a multi-line file." + ) def test_file_not_exist(self): - """This method test when a file has multiple lines""" - with self.assertRaises(AssertionError): - word_count_txt_file("not_exist.txt") + """Test if the method raises an error for a non-existent file.""" + with self.assertRaises( + AssertionError, msg="An error if the file does not exist." + ): + word_count_txt_file("non_existent_file.txt") def test_not_a_txt_file(self): - """It should raise an error if the argument is not an integer""" - with self.assertRaises(AssertionError): + """Test if the method raises an error for a non-.txt file.""" + with self.assertRaises( + AssertionError, msg="Should raise an error for a non-.txt file." + ): word_count_txt_file("test") diff --git a/solutions/word_count_from_file.py b/solutions/word_count_from_file.py index 559b762c1..cc3236e59 100644 --- a/solutions/word_count_from_file.py +++ b/solutions/word_count_from_file.py @@ -1,29 +1,31 @@ -import os - """ -A Module for counting the number of words in a .txt file +A Module for counting the number of words in a .txt file. Module contents: - - .txt file: the file to read the content from - - Number: the number of words in the file + - Function: `word_count_txt_file` for counting words in a file. + - Input: `.txt` file to read the content from. + - Output: Total number of words in the file. -created on 30 Dec 2024 -@author: saja abusafia +Created on 30 Dec 2024 +@author: Saja Abusafia """ +import os + def word_count_txt_file(file_name) -> int: """ - The function counts the total number of words in a file + Counts the total number of words in a .txt file. Parameters: - String: file_name (str): the file name to read the content from + file_name (str): The name of the file to read the content from. + Returns: - int n: The total number of words - Raises: - AssertionError: if the file does not exist - AssertionError: if the file is not a .txt file + int: The total number of words in the file. + Raises: + AssertionError: If the file does not exist. + AssertionError: If the file is not a .txt file. >>> word_count_txt_file("solutions/test_5.txt") 5 @@ -33,24 +35,27 @@ def word_count_txt_file(file_name) -> int: 10 """ + # Defensive assertions assert os.path.exists(file_name), f"Error:file '{file_name}' doesn't exist" assert file_name.endswith( ".txt" ), f"Error: The file '{file_name}' does not have a .txt extension." + # Open the file safely f = open(file_name, "r") file_size = os.path.getsize(file_name) + + # Return 0 if the file is empty if file_size == 0: return 0 - + # Read the file's content file_content = f.read() i = 0 - for n in file_content: if n == "": i += 1 - break + break # Don't increment unless it reach the end of a word elif n == " ": i += 1 # Increment if the character is a space elif n == "\n": From 0beb468847eeefa0a9955dbb4b4ec299d437e463 Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Sun, 5 Jan 2025 20:36:14 +0400 Subject: [PATCH 107/151] edit the docstring --- solutions/tests/test_game_greeting.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/solutions/tests/test_game_greeting.py b/solutions/tests/test_game_greeting.py index de7fd81af..3cb22ebd6 100644 --- a/solutions/tests/test_game_greeting.py +++ b/solutions/tests/test_game_greeting.py @@ -11,24 +11,25 @@ class TestGameGreeting(unittest.TestCase): - # test game greeting function + """test game greeting function""" + def test_valid_name(self): - # test the function with a valid name + """test the function with a valid name""" self.assertEqual(game_greeting("Mohamed"), "Welcome, Mohamed to the game") def test_empty_string(self): - # test the function with an empty string + """test the function with an empty string""" self.assertEqual(game_greeting(""), "Welcome, to the game") def test_special_characters(self): - # test the function with special characters + """test the function with special characters""" self.assertEqual(game_greeting("mx@z*"), "Welcome, mx@z* to the game") def test_integers(self): - # test the function with integers + """test the function with integers""" with self.assertRaises(AssertionError): (game_greeting(573)) def test_whitespace_name(self): - # test the function with whitespace + """test the function with whitespace""" self.assertEqual(game_greeting(" "), "Welcome, to the game") From 1620b0f0d50a0e87fe8aa13d6758f5f7bca32ffd Mon Sep 17 00:00:00 2001 From: sajaabusafia Date: Sun, 5 Jan 2025 18:39:20 +0200 Subject: [PATCH 108/151] final edits --- solutions/copy_from_file_to_file.py | 45 +++++++++------- .../tests/test_copy_from_file_to_file.py | 54 ++++++++++++------- 2 files changed, 62 insertions(+), 37 deletions(-) diff --git a/solutions/copy_from_file_to_file.py b/solutions/copy_from_file_to_file.py index 81fee7f7b..d8b118107 100644 --- a/solutions/copy_from_file_to_file.py +++ b/solutions/copy_from_file_to_file.py @@ -1,39 +1,42 @@ -import os - """ - This Module can copy content from one file to another +This module copies content from one file to another. - Module contents: - - .txt file: the file to read the content from - - .txt file: the file to write the content to - - created on 1 Jan 2025 "Happy new year" - @author: saja abusafia +Module contents: + - `source_file` (.txt): the file to read content from. + - `destination_file` (.txt): the file to write content to. +Created on 1 Jan 2025 "Happy New Year!" +@author: Saja Abusafia """ +import os + -def copy_file_to_file(source_file, destination_file): +def copy_file_to_file(source_file: str, destination_file: str) -> None: """ - The function copies the content from one file to another file - + Copies content from a source file to a destination file. Parameters: - source_file (str): the file to read the conent from - destination_file(str): the file to add the content to + source_file (str): The file to read the content from. + destination_file (str): The file to write the content to. Returns: - none-The function performs the copying operation but does not return - anything + None:Method performs the copying operation but doesn't return anything. + Raises: - AssertionError: if the source file does not exist - AssertionError: if the source or destination file is not a txt file + AssertionError: If the source file does not exist. + AssertionError: If the source file is not a .txt file. + AssertionError: If the destination file is not a .txt file. + - >>> copy_file_to_file("solutions/source.txt","solutions/destination.txt") + >>> copy_file_to_file("solutions/source.txt", "solutions/destination.txt") + >>> copy_file_to_file("solutions/empty.txt", "solutions/destination.txt") + >>> copy_file_to_file("solutions/destination.txt", "solutions/empty.txt") """ + # Defensive checks assert os.path.exists( source_file ), f"Error: Source file '{source_file}' doesn't exist." @@ -44,8 +47,12 @@ def copy_file_to_file(source_file, destination_file): ".txt" ), f"Error: Destination file '{destination_file}' is not a .txt file." + # Copy operation: Open the source file in read mode with open(source_file, "r") as file_from: + # Read the entire content of the source file file_content = file_from.read() + # Open the destination file in write mode with open(destination_file, "w") as file_to: + # Write the content read from the source file into the destination file file_to.write(file_content) diff --git a/solutions/tests/test_copy_from_file_to_file.py b/solutions/tests/test_copy_from_file_to_file.py index 64101a3a0..f17a00ebb 100644 --- a/solutions/tests/test_copy_from_file_to_file.py +++ b/solutions/tests/test_copy_from_file_to_file.py @@ -1,67 +1,85 @@ -import unittest +""" +This function copies content from one file to another. -from ..copy_from_file_to_file import copy_file_to_file +Parameters: + source_file (str): The file to read the content from + destination_file (str): The file to write the content to -""" - copy the content from one file to another file - Parameters: - source_file (str): the file to read the conent from - Destination_file(str): the file to add the content to - Returns -> - None-The method performs the copying operation but does not return anything - Raises: - AssertionError: if the source file does not exist - AssertionError: if the source file or destination file is not a txt file +Returns: + None: The function performs the copying operation but does not return anything + +Raises: + AssertionError: If the source file does not exist + AssertionError: If the source or destination file is not a .txt file """ +import unittest + +from ..copy_from_file_to_file import copy_file_to_file + class TestCopyFromFileToFile(unittest.TestCase): - """Tests different cases when copying from one file to another""" + """Test various scenarios for copying content from one file to another""" def test_des_not_exist(self): - """This method test if Destination doesn't exist""" + """Test when the destination file does not exist""" source_file = "solutions/source.txt" destination_file = "solutions/destination.txt" + + # Call the function to copy content from source to destination copy_file_to_file(source_file, destination_file) + + # Open both files and check if the content matches with ( open("solutions/source.txt", "r") as source, open("solutions/destination.txt", "r") as destination, ): + # Assert that content of the source is identical to the destination self.assertEqual(source.read(), destination.read()) def test_copy_to_file(self): - """This method test when the file we copy already exist""" + """Test when the destination file already exists""" source_file = "solutions/source.txt" destination_file = "solutions/destination.txt" + + # Call the function to copy content from source to destination copy_file_to_file(source_file, destination_file) + # Open both files and compare their content with ( open("solutions/source.txt", "r") as source, open("solutions/destination.txt", "r") as destination, ): + # Assert that content of the source is identical to the destination self.assertEqual(source.read(), destination.read()) def test_not_a_txt_file(self): - """It should raise an assertion error if file is not .txt""" + """It raises an assertion error if the source file is not a .txt file""" with self.assertRaises(AssertionError): + # Call the function with a source file that is not a .txt file copy_file_to_file("solutions/Source.", "solutions/destination.txt") def test_source_file_empty(self): - """The method test when the source file is empty""" + """Test when the source file is empty""" source_file = "solutions/empty.txt" destination_file = "solutions/destination.txt" + + # Copy content from an empty source file to the destination file copy_file_to_file(source_file, destination_file) + # Open both files and compare their content with ( open("solutions/empty.txt", "r") as source, open("solutions/destination.txt", "r") as destination, ): + # Assert that both the source and destination are empty (no content) self.assertEqual(source.read(), destination.read()) def test_src_not_exist(self): - """This method test if Source doesn't exist""" + """Test when the source file does not exist""" source_file = "solutions/not_exist.txt" destination_file = "solutions/destination.txt" + # Check if it raises an assertion error when the source does not exist with self.assertRaises(AssertionError): copy_file_to_file(source_file, destination_file) From ed4f3e30106b0c637ece3bd56ddf7117fdfe65bd Mon Sep 17 00:00:00 2001 From: mxz Date: Sun, 5 Jan 2025 19:04:51 +0200 Subject: [PATCH 109/151] adding the code --- solutions/draw_triangle.py | 49 +++++++++++++++++++ .../test_draw_triangle.py} | 0 solutions/tests/test_stars_draw.py | 0 3 files changed, 49 insertions(+) create mode 100644 solutions/draw_triangle.py rename solutions/{stars_draw.py => tests/test_draw_triangle.py} (100%) delete mode 100644 solutions/tests/test_stars_draw.py diff --git a/solutions/draw_triangle.py b/solutions/draw_triangle.py new file mode 100644 index 000000000..12dd5591b --- /dev/null +++ b/solutions/draw_triangle.py @@ -0,0 +1,49 @@ +""" +module'draw': it prints a triangle pattern made of stars (*). + +the user enters a number and get a triangle of stars in descending order. + +""" +# the function + + +def draw_triangle(n: int) -> None: + """ + Prints a descending triangle pattern of stars (*). + + + parameters: + n (int): The number of stars in the first row. + Must be a positive integer. + + Returns: + None: The function prints the pattern but does not return any value. + + + Raises: + assertionError: if 'n' is not an integer + assertionError: if 'n' is less than one + + + Examples: + >>> draw_triangle(5) + ***** + **** + *** + ** + * + + >>> draw_triangle(3) + *** + ** + * + + """ + + assert isinstance(n, int), " parameter 'n' must be an integer" + + if n < 1: + raise ValueError("parameter 'n' must be greater than or equal to 1.") + + for a in range(n, 0, -1): + print("*" * a) diff --git a/solutions/stars_draw.py b/solutions/tests/test_draw_triangle.py similarity index 100% rename from solutions/stars_draw.py rename to solutions/tests/test_draw_triangle.py diff --git a/solutions/tests/test_stars_draw.py b/solutions/tests/test_stars_draw.py deleted file mode 100644 index e69de29bb..000000000 From a83f7b50a95137ceb1eaac8512f72a67369d88fa Mon Sep 17 00:00:00 2001 From: ayhm01 Date: Sun, 5 Jan 2025 19:16:22 +0200 Subject: [PATCH 110/151] applied saja's suggestions --- solutions/substitution_cipher.py | 21 +++++++-------------- solutions/tests/test_substitution_cipher.py | 6 +++++- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/solutions/substitution_cipher.py b/solutions/substitution_cipher.py index 3f742a1ca..dcce693bc 100644 --- a/solutions/substitution_cipher.py +++ b/solutions/substitution_cipher.py @@ -13,9 +13,14 @@ def cipher(text: str) -> str: """ Parameters: text (str): The text to be encrypted. + Assumes input consists of alphabetic chars, optionally mixed with non alphabetic chars + those would remain unchanged. + Returns: - str: The encrypted text. + str: The encrypted text. only alphabetic characters shifted by 3 positions + and non alphabetical values unchanged. + >>> cipher("abc") 'def' @@ -24,6 +29,7 @@ def cipher(text: str) -> str: >>> cipher("Hello!") 'Khoor!' """ + shift_value = 3 # Validate that the input is a string. @@ -46,16 +52,3 @@ def shift_alphabet(alphabet: str) -> str: # Create a translation table to map characters to their shifted counterparts. table = str.maketrans(final_alphabet, final_shifted_alphabet) return text.translate(table) - - -if __name__ == "__main__": - # Prompt the user for input text. - plain_text = input("Enter a word: ").strip() - - # Reprompt the user if the input is empty. - while not plain_text: - print("Input cannot be empty. Please enter a valid word.") - plain_text = input("Enter a word: ").strip() - - # Encrypt the input text and display the result. - print(f"Encrypted word: {cipher(plain_text)}") diff --git a/solutions/tests/test_substitution_cipher.py b/solutions/tests/test_substitution_cipher.py index ab3198fb1..61f3e29ca 100644 --- a/solutions/tests/test_substitution_cipher.py +++ b/solutions/tests/test_substitution_cipher.py @@ -1,9 +1,13 @@ +""" +Unit tests for the cipher function +""" + import unittest from solutions.substitution_cipher import cipher -class TestCipher(unittest.TestCase): +class TestSubstitutionCipher(unittest.TestCase): """ testing cipher function """ From 09812256ff8095b2d0c2b06f3da37a3d3381e660 Mon Sep 17 00:00:00 2001 From: Omnia-Agabani Date: Sun, 5 Jan 2025 21:20:59 +0400 Subject: [PATCH 111/151] enhancement --- solutions/harmonic_sequence.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/solutions/harmonic_sequence.py b/solutions/harmonic_sequence.py index 66b373614..8e05c2656 100644 --- a/solutions/harmonic_sequence.py +++ b/solutions/harmonic_sequence.py @@ -7,7 +7,7 @@ """ -def harmonic_sequence(a: int, d: int, n: int) -> list: +def harmonic_sequence(a: int, d: int, n: int) -> list[float]: """ This function ,`harmonic_sequence`, creates a harmonic sequence, based on formula: A(n): 1/ (a +(n-1) *d) @@ -18,7 +18,7 @@ def harmonic_sequence(a: int, d: int, n: int) -> list: n (int): Number of terms to generate Returns: - List: List containing the harmonic sequence + List [float]: List containing the harmonic sequence Assertions: - a must be integer @@ -65,8 +65,9 @@ def harmonic_sequence(a: int, d: int, n: int) -> list: assert isinstance(a, int), "A must be integer" assert isinstance(d, int), "D must be integer" assert isinstance(n, int), "N must be integer" - - # Create an empty list to save the sequence + if not isinstance: + assert TypeError + # Create an empty list to save the sequence sequence = [] # If n is less than or equal to 0, return empty list if n <= 0: From a996b1b2ddb4b6b152db9fcfaf951d0e2e606a46 Mon Sep 17 00:00:00 2001 From: RAFAA ALI Date: Sun, 5 Jan 2025 21:21:31 +0400 Subject: [PATCH 112/151] editing the review comment --- solutions/FooBar_code.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/solutions/FooBar_code.py b/solutions/FooBar_code.py index 5b0f25329..12870214a 100644 --- a/solutions/FooBar_code.py +++ b/solutions/FooBar_code.py @@ -47,7 +47,8 @@ def FooBar_code(n: int): """ # Assert an error when n is not an integer assert isinstance(n, int), "n must be an integer" - + if not isinstance: + assert TypeError # Prepare an empty list for the result result = [] From 5a2a9057bcb5cfb432f74ad73a7df5c47baedd88 Mon Sep 17 00:00:00 2001 From: ayhm01 Date: Sun, 5 Jan 2025 19:40:57 +0200 Subject: [PATCH 113/151] minor adjustments --- solutions/substitution_cipher.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/solutions/substitution_cipher.py b/solutions/substitution_cipher.py index dcce693bc..32fb65a52 100644 --- a/solutions/substitution_cipher.py +++ b/solutions/substitution_cipher.py @@ -21,6 +21,8 @@ def cipher(text: str) -> str: str: The encrypted text. only alphabetic characters shifted by 3 positions and non alphabetical values unchanged. + Raises: + ValueError: If input is not a string >>> cipher("abc") 'def' @@ -28,6 +30,7 @@ def cipher(text: str) -> str: 'rpqld' >>> cipher("Hello!") 'Khoor!' + """ shift_value = 3 From d0503fc7706ae4769041bf28c0f93b0015c0a270 Mon Sep 17 00:00:00 2001 From: RAFAA ALI Date: Sun, 5 Jan 2025 21:43:15 +0400 Subject: [PATCH 114/151] delete extra files --- solutions/FooBar_code.py | 75 ----------------------------- solutions/tests/test_FooBar_code.py | 73 ---------------------------- 2 files changed, 148 deletions(-) delete mode 100644 solutions/FooBar_code.py delete mode 100644 solutions/tests/test_FooBar_code.py diff --git a/solutions/FooBar_code.py b/solutions/FooBar_code.py deleted file mode 100644 index 8c5bf9fe3..000000000 --- a/solutions/FooBar_code.py +++ /dev/null @@ -1,75 +0,0 @@ -""" -Creates a sequence where numbers divisible by 4 return 'Foo', -numbers divisible by 6 return 'Bar', numbers divisible by both -return 'FooBar', and other numbers remain unchanged. - -Author: Rafaa Ali -Created date: 1.1.2025 -""" - - -def FooBar_code(n: int): - """This function, `FooBar_code`, creates a sequence that replaces numbers - based on their divisibility by 4 and 6. - - Parameters: - n (int):the last number in the list - - Returns: - List containing the sequence with 'Foo', 'Bar', 'FooBar' or numbers - - assertion: - n must be integer otherwise error - - - example: - Edge cases: - >>> FooBar_code(1) - [1] - >>> FooBar_code(0) - [] - >>> FooBar_code(-1) - [] - - Standard cases: - >>> FooBar_code(8) - [1, 2, 3, 'Foo', 5, 'Bar', 7, 'Foo'] - >>> FooBar_code(12) - [1, 2, 3, 'Foo', 5, 'Bar', 7, 'Foo', 9, 10, 11, 'FooBar'] - >>> FooBar_code(16) - [1, 2, 3, 'Foo', 5, 'Bar', 7, 'Foo', 9, 10, 11, 'FooBar', - 13, 14, 15, 'Foo'] - - Defensive cases: - >>> FooBar_code("rafaa") - AssertionError: N must be integer - >>> FooBar_code(5.5) - AssertionError: N must be integer - >>> FooBar_code([1, 2, 3]) - AssertionError: N must be integer - - - """ - # assert an error when n is not integer - assert isinstance(n, int), "N must be integer" - # prepare empty list for the result - result = [] - # loop for checking the sequence - for i in range(1, n + 1): - # checking if the number is devisable by 4 and 6 - if i % 4 == 0 and i % 6 == 0: - # add FooBar to the list if it devisable by both 4,6 - result.append("FooBar") - # checking if the number is devisable by 4 - elif i % 4 == 0: - # add Foo to the list if it devisable by 4 - result.append("foo") - # checking if the number is devisable by 6 - elif i % 6 == 0: - # add Bar to the list if it devisable by 6 - result.append("Bar") - # otherwise add the number to the list - else: - result.append(i) - # return the result's list - return result diff --git a/solutions/tests/test_FooBar_code.py b/solutions/tests/test_FooBar_code.py deleted file mode 100644 index 3eb613132..000000000 --- a/solutions/tests/test_FooBar_code.py +++ /dev/null @@ -1,73 +0,0 @@ -"""test module for FooBar_code function""" - -import unittest - -from solutions.FooBar_code import FooBar_code - - -class TestFooBar(unittest.TestCase): - """this class to test FooBar_code function""" - - # Edge cases: - def test_int1(self): - """check if the input is 1""" - self.assertEqual(FooBar_code(1), [1]) - - def test_int0(self): - """check if the input is 0""" - self.assertEqual(FooBar_code(0), []) - - def test_negative_int(self): - """check if the input is negative""" - self.assertEqual(FooBar_code(-1), []) - - # Standard cases: - def test_int8(self): - """check if the input is 8""" - self.assertEqual(FooBar_code(8), [1, 2, 3, "foo", 5, "Bar", 7, "foo"]) - - def test_int12(self): - """check if the input is 12""" - self.assertEqual( - FooBar_code(12), [1, 2, 3, "foo", 5, "Bar", 7, "foo", 9, 10, 11, "FooBar"] - ) - - def test_is_int(self): - """check if the input is large number""" - self.assertEqual( - FooBar_code(16), - [ - 1, - 2, - 3, - "foo", - 5, - "Bar", - 7, - "foo", - 9, - 10, - 11, - "FooBar", - 13, - 14, - 15, - "foo", - ], - ) - - # defensive cases - def test_string_input(self): - """It should raise AssertionError for string input""" - with self.assertRaises(AssertionError): - FooBar_code("rafaa") - - def test_is_float_input(self): - """It should raise AssertionError for float input""" - with self.assertRaises(AssertionError): - FooBar_code(5.5) - - def test_is_list_input(self): - """It should raise AssertionError for list input""" - with self.assertRaises(AssertionError): - FooBar_code([1, 2, 3]) From 1886a9fec6eec4bf171e7ca55d5dbc0146c0a7e4 Mon Sep 17 00:00:00 2001 From: RAFAA ALI Date: Sun, 5 Jan 2025 21:49:44 +0400 Subject: [PATCH 115/151] solving ruff issues --- solutions/tests/test_count_characters.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/solutions/tests/test_count_characters.py b/solutions/tests/test_count_characters.py index 7493f3532..0adadd5f4 100644 --- a/solutions/tests/test_count_characters.py +++ b/solutions/tests/test_count_characters.py @@ -1,5 +1,6 @@ import unittest -from .. count_characters import count_characters +from ..count_characters import count_characters + class Testcount_characters(unittest.TestCase): # Edge cases: @@ -54,4 +55,4 @@ def test_none_input(self): def test_float_input(self): """It should raise AssertionError for float input""" with self.assertRaises(AssertionError): - count_characters(3.14) \ No newline at end of file + count_characters(3.14) From 88af8f311949319fd397c9f7729a6fa94f91115c Mon Sep 17 00:00:00 2001 From: mxz Date: Sun, 5 Jan 2025 21:03:23 +0200 Subject: [PATCH 116/151] adding the code tests --- .vscode/settings.json | 3 +- solutions/tests/test_draw_triangle.py | 52 +++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 89cc035cc..4c2f0d21a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -124,6 +124,7 @@ } }, "cSpell.words": [ - "Mayar" + "Mayar", + "Testdraw" ] } diff --git a/solutions/tests/test_draw_triangle.py b/solutions/tests/test_draw_triangle.py index e69de29bb..63386a330 100644 --- a/solutions/tests/test_draw_triangle.py +++ b/solutions/tests/test_draw_triangle.py @@ -0,0 +1,52 @@ +""" +test_draw_triangle.py + +this module contains unit tests for the 'draw_triangle' function. + +""" + +import unittest +from io import StringIO +import sys +from ..draw_triangle import draw_triangle + + +class TestDrawTriangle(unittest.TestCase): + """test the draw triangle function""" + + def setUp(self): + """set up for capturing printed output""" + self.captured_output = StringIO() + sys.stdout = self.captured_output + + def tearDown(self): + """reset standard output""" + sys.stdout = sys.__stdout__ + + def test_valid_input(self): + """test the function with valid input""" + draw_triangle(4) + self.assertEqual(self.captured_output.getvalue(), "****\n***\n**\n*\n") + + def test_large_input(self): + """test the function with a large input""" + draw_triangle(7) + self.assertEqual( + self.captured_output.getvalue(), + "*******\n******\n*****\n****\n***\n**\n*\n", + ) + + def test_non_integer_input(self): + """test the function with a non integer input""" + with self.assertRaises(AssertionError): + draw_triangle("aa") + + def test_negative_input(self): + """test the function with a negative input""" + with self.assertRaises(ValueError): + draw_triangle(-3) + + def test_zero_input(self): + """test the function with zero as the input""" + with self.assertRaises(ValueError): + draw_triangle(0) From 2df9d5812f89899c5c5f2bcf80a431408112a060 Mon Sep 17 00:00:00 2001 From: safaishag Date: Mon, 6 Jan 2025 04:55:52 +0200 Subject: [PATCH 117/151] factorial challenges --- solutions/factorial.py | 53 +++++++++++++++++++++++++++++ solutions/tests/test_factorial.py | 55 +++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 solutions/factorial.py create mode 100644 solutions/tests/test_factorial.py diff --git a/solutions/factorial.py b/solutions/factorial.py new file mode 100644 index 000000000..2009bfee1 --- /dev/null +++ b/solutions/factorial.py @@ -0,0 +1,53 @@ +""" +This module provides a function to calculate the factorial of a number recursively. + +The factorial function is defined only for non-negative integers. + +Created on 01/01/2025 + +@author: Safa Ishag + +Challenge is from the Leetcode website. + +""" + + +def factorial(n: int) -> int: + """ + Calculate the factorial of a given non-negative integer. + + Parameters: + n (int): The number whose factorial is to be calculated. Must be >= 0. + + Returns: + int: The factorial of the input number. + + Raises: + ValueError: If `n` is negative. + + Doctests: + >>> factorial(0) + 1 + >>> factorial(1) + 1 + >>> factorial(5) + 120 + >>> factorial(-1) + Traceback (most recent call last): + ... + ValueError: Input must be a non-negative integer. + """ + # Defensive assertion: Input must be a non-negative integer + if not isinstance(n, int): + raise TypeError("Input must be an integer.") + if n < 0: + raise ValueError("Input must be a non-negative integer.") + if n in (0, 1): + return 1 + return n * factorial(n - 1) + + +if __name__ == "__main__": + import doctest + + doctest.testmod() diff --git a/solutions/tests/test_factorial.py b/solutions/tests/test_factorial.py new file mode 100644 index 000000000..264ad2c1f --- /dev/null +++ b/solutions/tests/test_factorial.py @@ -0,0 +1,55 @@ +""" +Unit tests for factorial_calculator.py. +""" + +import unittest + +from solutions.factorial import factorial + + +class TestSolutionFactorial(unittest.TestCase): + """ + Unit tests for the factorial function. + """ + + def test_factorial_zero(self): + """ + Test factorial of 0 is 1. + """ + self.assertEqual(factorial(0), 1) + + def test_factorial_one(self): + """ + Test factorial of 1 is 1. + """ + self.assertEqual(factorial(1), 1) + + def test_factorial_positive(self): + """ + Test factorial of a positive integer. + """ + self.assertEqual(factorial(5), 120) + + def test_large_factorial(self): + """ + Test factorial of a larger number. + """ + self.assertEqual(factorial(10), 3628800) + + def test_negative_input(self): + """ + Test that negative inputs raise a ValueError. + """ + with self.assertRaises(ValueError): + factorial(-5) + + def test_non_integer_input(self): + """ + Test that non-integer inputs raise a TypeError. + """ + with self.assertRaises(TypeError): + factorial(5.5) + + +if __name__ == "__main__": + unittest.main() From 2c9177bfedaaf52477618468148429b0f5fbf398 Mon Sep 17 00:00:00 2001 From: safaishag Date: Mon, 6 Jan 2025 05:23:26 +0200 Subject: [PATCH 118/151] summation challenges --- solutions/summation.py | 56 +++++++++++++++++++++++++++ solutions/tests/test_summation.py | 64 +++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 solutions/summation.py create mode 100644 solutions/tests/test_summation.py diff --git a/solutions/summation.py b/solutions/summation.py new file mode 100644 index 000000000..d32885492 --- /dev/null +++ b/solutions/summation.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +A module for determining whether a given number is a sum of a defined number. + +Module contents: + - sum: checks if a given integer is a sum of those given numbers. + +Created on 01/01/2025 + +@author: Safa Ishag + +Challenge is from the Leetcode website. + +Defining the sum of a given number: + +""" + + +def sum(*args: float) -> float: + """ + Return the sum of all input numbers. + + Parameters: + *args (int or float): The number to check and is the variable. + + Returns: + int or float: The sum of all input numbers. + + Raises: + TypeError: If any input is not a number. + + Example: + >>> sum(1, 2, 3, 4, 5) + 15 + >>> sum(3, 6, 2, 1, 8) + 20 + >>> sum(4, 9, 7, 2, 5) + 27 + + """ + # Defensive assertion: Ensure all inputs are numbers + if not all(isinstance(arg, (int, float)) for arg in args): + raise TypeError("All inputs must be numeric (int or float).") + + # Initialize a running total to zero + total = 0 + + # Iterate through the input arguments and calculate the sum + + total = 0 + + for i in args: + total += i + + return total diff --git a/solutions/tests/test_summation.py b/solutions/tests/test_summation.py new file mode 100644 index 000000000..696550f68 --- /dev/null +++ b/solutions/tests/test_summation.py @@ -0,0 +1,64 @@ +import unittest + +from solutions.summation import sum + + +class TestSum(unittest.TestCase): + def test_sum_positive_numbers(self): + """It should return the sum of a positive numbers""" + actual = sum(1, 2, 3, 4, 5) # noqa: F841 + expected = 15 # noqa: F841 + self.assertEqual(actual, expected) # noqa: F821 + + def test_sum_negative_numbers(self): + """It should return the sum of a negative numbers""" + actual = sum(-1, -2, -3, -5) # noqa: F841 + expected = -11 + self.assertEqual(actual, expected) + + def test_sum_mixed_numbers(self): + """It should return the sum of a mix numbers""" + + actual = sum(10, -20, -40, 50) + expected = 0 + self.assertEqual(actual, expected) + + def test_sum_float_numbers(self): + """It should return the sum of a float numbers""" + + actual = sum(1.5, 2.5, 3.7, 4.5) + expected = 12.2 + self.assertEqual(actual, expected) + + def test_sum_zero_numbers(self): + """It should return the sum of zero numbers""" + actual = sum(0, 0, 0, 0) + expected = 0 + self.assertEqual(actual, expected) + + def test_sum_single_argument(self): + """It should return the single argument when only one is provided.""" + actual = sum(10) + expected = 10 + self.assertEqual(actual, expected) + + def test_sum_no_arguments(self): + """It should return 0 when no arguments are provided.""" + actual = sum() + expected = 0 + self.assertEqual(actual, expected) + + def test_invalid_input_string(self): + """It should raise a TypeError for string input.""" + with self.assertRaises(TypeError): + sum(1, 2, "string", 4) + + def test_invalid_input_none(self): + """It should raise a TypeError for None as an input.""" + with self.assertRaises(TypeError): + sum(1, None, 3) + + def test_invalid_input_mixed(self): + """It should raise a TypeError for mixed valid and invalid inputs.""" + with self.assertRaises(TypeError): + sum(10, 5, "invalid", 2) From 0b64d33eed6e4c79ae1534a937ec36171ea9b09e Mon Sep 17 00:00:00 2001 From: Safi222 Date: Mon, 6 Jan 2025 13:46:14 +0300 Subject: [PATCH 119/151] Fixing upon reviewing request --- solutions/LowestCommonAncestor_in_BST.py | 7 +++++++ solutions/tests/test_LowestCommonAncestor_in_BST.py | 3 +++ 2 files changed, 10 insertions(+) diff --git a/solutions/LowestCommonAncestor_in_BST.py b/solutions/LowestCommonAncestor_in_BST.py index 7a90c807f..650025d83 100644 --- a/solutions/LowestCommonAncestor_in_BST.py +++ b/solutions/LowestCommonAncestor_in_BST.py @@ -1,3 +1,10 @@ +""" +This module for Lowest_Common_Ancestor_in Binary Search Tree function. +Author: Safia Gibril +Created on: 2.1.2025 +""" + + class TreeNode: """Define class for TreeNode""" diff --git a/solutions/tests/test_LowestCommonAncestor_in_BST.py b/solutions/tests/test_LowestCommonAncestor_in_BST.py index 0826abd22..c04aa676d 100644 --- a/solutions/tests/test_LowestCommonAncestor_in_BST.py +++ b/solutions/tests/test_LowestCommonAncestor_in_BST.py @@ -2,9 +2,12 @@ # -*- coding: utf-8 -*- """ Test module for Lowest Common Ancestor in Binary Search Tree function. +Author: Safia Gibril +Created on: 2.1.2025 """ import unittest + from solutions.LowestCommonAncestor_in_BST import lowestCommonAncestor From e8da0cbaa35180bd3850eb8d97d4d3eb14c9e58a Mon Sep 17 00:00:00 2001 From: Safi222 Date: Mon, 6 Jan 2025 13:57:14 +0300 Subject: [PATCH 120/151] Fixing upon reviewing request --- solutions/Roman_to_integer.py | 3 +++ solutions/tests/test_Roman_to_integer.py | 3 +++ 2 files changed, 6 insertions(+) diff --git a/solutions/Roman_to_integer.py b/solutions/Roman_to_integer.py index 44e15c9a6..39086037c 100644 --- a/solutions/Roman_to_integer.py +++ b/solutions/Roman_to_integer.py @@ -5,6 +5,9 @@ Provides the RomanConverter class with a method to convert valid Roman numeral strings into their integer representation. + +Author: Safia Gibril +Created on: 2.1.2025 """ diff --git a/solutions/tests/test_Roman_to_integer.py b/solutions/tests/test_Roman_to_integer.py index 16f400443..623ad4152 100644 --- a/solutions/tests/test_Roman_to_integer.py +++ b/solutions/tests/test_Roman_to_integer.py @@ -2,6 +2,9 @@ # -*- coding: utf-8 -*- """ Test module for Roman to integer function. + +Author: Safia Gibril +Created on: 2.1.2025 """ import unittest From a5646120f06b94790a24dfc958806889a991d28a Mon Sep 17 00:00:00 2001 From: ayhm01 Date: Mon, 6 Jan 2025 13:22:24 +0200 Subject: [PATCH 121/151] added factorial_calculator --- solutions/factorial_calculator.py | 39 +++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 solutions/factorial_calculator.py diff --git a/solutions/factorial_calculator.py b/solutions/factorial_calculator.py new file mode 100644 index 000000000..c89f8392a --- /dev/null +++ b/solutions/factorial_calculator.py @@ -0,0 +1,39 @@ +"""factorial calculator""" + + +def factorial(n: int) -> int: + """ + Parameters: + n(int): The number to calculate the factorial of. it should be a positive integer only + + Returns: + int: the factorial of the given number + + Raises: + ValueError -> If the input is None or a Negative integer + TypeError -> if the input is not an integer + + Examples: + + >>> factorial(5) + 120 + >>> factorial(0) + 1 + >>> factorial(3) + 6 + + """ + + if n is None: + raise ValueError("Input cannot be None") + + if not isinstance(n, int): + raise TypeError("Input must be an integer") + + if n < 0: + raise ValueError("Factorial is not defined for negative numbers") + + fact = 1 + for i in range(1, n + 1): + fact *= i + return fact From 24c85ef977fc634811cb6c0c574de30e83820e8f Mon Sep 17 00:00:00 2001 From: ayhm01 Date: Mon, 6 Jan 2025 15:03:08 +0200 Subject: [PATCH 122/151] update factorial implementation --- solutions/factorial_calculator.py | 2 + solutions/tests/test_factorial_calculator.py | 46 ++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 solutions/tests/test_factorial_calculator.py diff --git a/solutions/factorial_calculator.py b/solutions/factorial_calculator.py index c89f8392a..eb7dce91c 100644 --- a/solutions/factorial_calculator.py +++ b/solutions/factorial_calculator.py @@ -33,7 +33,9 @@ def factorial(n: int) -> int: if n < 0: raise ValueError("Factorial is not defined for negative numbers") + # initialize the result variable fact = 1 + # a loop to compute the factorial for i in range(1, n + 1): fact *= i return fact diff --git a/solutions/tests/test_factorial_calculator.py b/solutions/tests/test_factorial_calculator.py new file mode 100644 index 000000000..ddf8ce8ff --- /dev/null +++ b/solutions/tests/test_factorial_calculator.py @@ -0,0 +1,46 @@ +"""unit tests for the factorial function in the factorial calculator module""" + +# Ayham +import unittest + +from ..factorial_calculator import factorial + + +class TestFactorial(unittest.TestCase): + """ + testing the factorial function. (edge cases and invalid inputs) + """ + + def test_factorial_positive(self): + """It should return the factorial of positive integers.""" + self.assertEqual(factorial(5), 120) + + def test_factorial_zero(self): + """it should return the factorial of zero > 1""" + self.assertEqual(factorial(0), 1) + + def test_factorial_negative(self): + """it should raise VAlueError for negative integers input""" + with self.assertRaises(ValueError): + factorial(-5) + + def test_factorial_none(self): + """It should raise a ValueError for None as an input""" + with self.assertRaises(ValueError): + factorial(None) + + def test_factorial_non_integer(self): + """It should raise TypeError when passing non integer values""" + with self.assertRaises(TypeError): + factorial(3.5) + with self.assertRaises(TypeError): + factorial("234fas") + + def test_factorial_large_numbers(self): + """ensuring it would compute the factorial for large inputs""" + self.assertEqual(factorial(14), 87178291200) + self.assertEqual(factorial(20), 2432902008176640000) + + +if __name__ == "__main__": + unittest.main() From 08cc083f3fad5578b4a3204481ef3e086f5758ca Mon Sep 17 00:00:00 2001 From: mxz Date: Mon, 6 Jan 2025 16:19:42 +0200 Subject: [PATCH 123/151] adding a comment --- solutions/draw_triangle.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/solutions/draw_triangle.py b/solutions/draw_triangle.py index 12dd5591b..d470ed105 100644 --- a/solutions/draw_triangle.py +++ b/solutions/draw_triangle.py @@ -33,7 +33,7 @@ def draw_triangle(n: int) -> None: ** * - >>> draw_triangle(3) + >>> draw_triangle(3) *** ** * @@ -46,4 +46,5 @@ def draw_triangle(n: int) -> None: raise ValueError("parameter 'n' must be greater than or equal to 1.") for a in range(n, 0, -1): + """ creates a sequence from n down to 1""" print("*" * a) From 567826b5c3110f011780694c208b21f45c8b2de5 Mon Sep 17 00:00:00 2001 From: mxz Date: Mon, 6 Jan 2025 16:49:59 +0200 Subject: [PATCH 124/151] adding author and date --- solutions/draw_triangle.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solutions/draw_triangle.py b/solutions/draw_triangle.py index d470ed105..5cfbc1d36 100644 --- a/solutions/draw_triangle.py +++ b/solutions/draw_triangle.py @@ -3,6 +3,8 @@ the user enters a number and get a triangle of stars in descending order. +Author: Mohamed Tilal +Created date: 6.1.2025 """ # the function From 96d037100994f1d895a618846ef1ecb1c68e351c Mon Sep 17 00:00:00 2001 From: mxz Date: Mon, 6 Jan 2025 16:54:02 +0200 Subject: [PATCH 125/151] adding author and date --- solutions/game_greeting.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solutions/game_greeting.py b/solutions/game_greeting.py index f5d86ca8c..bc64dc093 100644 --- a/solutions/game_greeting.py +++ b/solutions/game_greeting.py @@ -3,6 +3,8 @@ the Module provides a function that generates a welcome message for a player joining a game. +Author: Mohamed Tilal +Created date: 6.1.2025 """ # the function: From 9f54d05bfde9e9cd857623521a189510a486840f Mon Sep 17 00:00:00 2001 From: safaishag Date: Mon, 6 Jan 2025 16:54:32 +0200 Subject: [PATCH 126/151] added docstring --- solutions/tests/test_summation.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/solutions/tests/test_summation.py b/solutions/tests/test_summation.py index 696550f68..37b25de32 100644 --- a/solutions/tests/test_summation.py +++ b/solutions/tests/test_summation.py @@ -1,9 +1,14 @@ import unittest +""" +unit tests for the summation function + +""" from solutions.summation import sum class TestSum(unittest.TestCase): + """tests for the sum function""" def test_sum_positive_numbers(self): """It should return the sum of a positive numbers""" actual = sum(1, 2, 3, 4, 5) # noqa: F841 From 2a36a0fe993380f861875de9aa14c0944c7b39e9 Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Mon, 6 Jan 2025 19:24:41 +0400 Subject: [PATCH 127/151] Adding date and author --- solutions/is_anagram.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solutions/is_anagram.py b/solutions/is_anagram.py index 2a63f3b34..f66888800 100644 --- a/solutions/is_anagram.py +++ b/solutions/is_anagram.py @@ -8,6 +8,8 @@ True if the two strings are anagrams, False otherwise +Created on 2024-01-02 +Author: Reem Osama """ from collections import Counter From 7329b598109c37478e76f241c138ec448c91398a Mon Sep 17 00:00:00 2001 From: RAFAA ALI Date: Mon, 6 Jan 2025 19:32:16 +0400 Subject: [PATCH 128/151] docstring editing --- .vscode/settings.json | 2 +- solutions/count_characters.py | 2 +- solutions/tests/test_count_characters.py | 10 +++++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 252022b48..84916e5c9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,7 +3,7 @@ //-------- Editor configuration -------- // Controls auto save of editors that have unsaved changes.: https://code.visualstudio.com/docs/editor/codebasics#_save-auto-save - "files.autoSave": "onFocusChange", + "files.autoSave": "off", // Format a file on save. A formatter must be available. "editor.formatOnSave": true, diff --git a/solutions/count_characters.py b/solutions/count_characters.py index d30cd0d12..6ea62bebf 100644 --- a/solutions/count_characters.py +++ b/solutions/count_characters.py @@ -12,7 +12,7 @@ def count_characters(string: str) -> int: ignoring case sensitivity. Parameters: - string (str): The input string to count vowels from + string (str): The input string to count vowels characters Returns: int: The total number of vowels in the string diff --git a/solutions/tests/test_count_characters.py b/solutions/tests/test_count_characters.py index 0adadd5f4..104e4715c 100644 --- a/solutions/tests/test_count_characters.py +++ b/solutions/tests/test_count_characters.py @@ -1,8 +1,16 @@ +""" +test_count_characters.py +this module contains unit tests for the 'count_characters' +function + +""" + import unittest + from ..count_characters import count_characters -class Testcount_characters(unittest.TestCase): +class TestCountCharacters(unittest.TestCase): # Edge cases: def test_empty_string(self): """check if the input is empty string""" From a9dc6174c75e46272572db8242c34bb3c9e427d0 Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Mon, 6 Jan 2025 19:35:21 +0400 Subject: [PATCH 129/151] Adding Value error when the variables value is less than 1 --- solutions/robot.py | 13 +++++++++---- solutions/tests/test_robot.py | 10 ++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/solutions/robot.py b/solutions/robot.py index dda695760..719a17ed4 100644 --- a/solutions/robot.py +++ b/solutions/robot.py @@ -12,6 +12,9 @@ Constraints: The test cases are generated so that the answer will be less than or equal to 2 * 109. + +Created on 2024-01-01 +Author: Reem Osama """ @@ -69,10 +72,12 @@ def robot(rows: int, cols: int) -> int: """ # assert the values of rows and clos and make sure they are ints and # greater than 1 - assert isinstance(rows, int) and rows > 0, "Rows variables has to \ - be an integer greater than 0" - assert isinstance(cols, int) and cols > 0, "Cols variable has to be \ - greater than 0" + assert isinstance(rows, int), "Rows variables has to be an integer" + if rows <= 0: + raise ValueError("The 'rows' variable must be greater than 0.") + assert isinstance(cols, int), "Cols variable has to be an integer" + if cols <= 0: + raise ValueError("The 'cols' variables must be greater than 0.") # use the helper function robot_move to determine the number of paths memo = {} diff --git a/solutions/tests/test_robot.py b/solutions/tests/test_robot.py index 777f66803..c21b23bb5 100644 --- a/solutions/tests/test_robot.py +++ b/solutions/tests/test_robot.py @@ -8,6 +8,8 @@ - Edge cases - Defensive tests +Created on 2024-01-02 +Author: Reem Osama """ import unittest @@ -18,6 +20,10 @@ class TestRobot(unittest.TestCase): """Test the robot function""" # Standard Cases + def test_base_1x1(self): + """A basic test with a small grid 1x1""" + self.assertEqual(robot(1, 1), 1) + def test_base_2x2(self): """A basic test with a small grid 2x2""" self.assertEqual(robot(2, 2), 2) @@ -64,12 +70,12 @@ def test_invalid_col(self): def test_negative_value(self): """A test with a negative dimension""" - with self.assertRaises(AssertionError): + with self.assertRaises(ValueError): robot(-1, 5) def test_zero_value(self): """A test with zero value""" - with self.assertRaises(AssertionError): + with self.assertRaises(ValueError): robot(3, 0) def test_non_integer_input(self): From c64c272bb77f227309d6a2975dbf3c9e60599a1f Mon Sep 17 00:00:00 2001 From: ayhm01 Date: Mon, 6 Jan 2025 18:09:57 +0200 Subject: [PATCH 130/151] Modified files based on Mayar's review --- solutions/factorial_calculator.py | 13 ++++++++++++- solutions/tests/test_factorial_calculator.py | 3 --- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/solutions/factorial_calculator.py b/solutions/factorial_calculator.py index eb7dce91c..629799c6c 100644 --- a/solutions/factorial_calculator.py +++ b/solutions/factorial_calculator.py @@ -1,4 +1,15 @@ -"""factorial calculator""" +""" +factorial calculator, +This module provides a function to calculate the factorial of a given non-negative integer. + +Mathematical Definition: +n! = n * (n - 1) * (n - 2) * ... * 1 + +By convention, 0! = 1. + +""" + +# Author: AYHAM, 6/jan/2025 def factorial(n: int) -> int: diff --git a/solutions/tests/test_factorial_calculator.py b/solutions/tests/test_factorial_calculator.py index ddf8ce8ff..9cf5e9d65 100644 --- a/solutions/tests/test_factorial_calculator.py +++ b/solutions/tests/test_factorial_calculator.py @@ -33,13 +33,10 @@ def test_factorial_non_integer(self): """It should raise TypeError when passing non integer values""" with self.assertRaises(TypeError): factorial(3.5) - with self.assertRaises(TypeError): - factorial("234fas") def test_factorial_large_numbers(self): """ensuring it would compute the factorial for large inputs""" self.assertEqual(factorial(14), 87178291200) - self.assertEqual(factorial(20), 2432902008176640000) if __name__ == "__main__": From a8105d6a1c08fc7ed358a616b58fa5ba895eb730 Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Mon, 6 Jan 2025 20:13:35 +0400 Subject: [PATCH 131/151] Removing arithemetic sequence test --- solutions/tests/test_arithmetic_sequence.py | 164 -------------------- 1 file changed, 164 deletions(-) delete mode 100644 solutions/tests/test_arithmetic_sequence.py diff --git a/solutions/tests/test_arithmetic_sequence.py b/solutions/tests/test_arithmetic_sequence.py deleted file mode 100644 index 5fe1172a3..000000000 --- a/solutions/tests/test_arithmetic_sequence.py +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Created on Monday/30/December/2024 -@author:Mayar Ali -""" - -import unittest - -# ---imports & test class before documenting and testing--- -# from ..arithmetic_sequence import arithmetic_sequence -# class TestArithmeticSequence(unittest.TestCase): -# ---imports & test class after documenting and testing--- - -from ..arithmetic_sequence import arithmetic_sequence - - -class TestArithmeticSequence(unittest.TestCase): - """Test the arithmetic_sequence function""" - - def test_0(self): - "It should evaluate 0 to []" - self.assertEqual(arithmetic_sequence(0), []) - - def test_1(self): - "Should evaluate 1 to [0]" - self.assertEqual(arithmetic_sequence(1), [1]) - - def test_2(self): - "Should evaluate 2 to [0,1]" - self.assertEqual(arithmetic_sequence(2), [0, 1]) - - def test_3(self): - "Should evaluate 3 to [0, 1, 5]" - self.assertEqual(arithmetic_sequence(3), [0, 1, 4]) - - # defensive cases - - def test_0_less_than_0(self): - """It should raise an assertion error if the argument is less than 0""" - with self.assertRaises(AssertionError): - arithmetic_sequence(-1) - - def test_1_not_an_integer(self): - """Should raise an assertion error if the argument is a float""" - with self.assertRaises(AssertionError): - arithmetic_sequence(1.0) - - def test_2_not_an_integer(self): - """Should raise an assertion error if the argument is not an integer""" - with self.assertRaises(AssertionError): - arithmetic_sequence(["1", 2, 3]) - - # Edge case - - def test_a_big_number(self): - "Should evaluate 100 to [0, 1, 5]" - self.assertEqual( - arithmetic_sequence(102), - [ - 0, - 1, - 4, - 7, - 10, - 13, - 16, - 19, - 22, - 25, - 28, - 31, - 34, - 37, - 40, - 43, - 46, - 49, - 52, - 55, - 58, - 61, - 64, - 67, - 70, - 73, - 76, - 79, - 82, - 85, - 88, - 91, - 94, - 97, - 100, - 103, - 106, - 109, - 112, - 115, - 118, - 121, - 124, - 127, - 130, - 133, - 136, - 139, - 142, - 145, - 148, - 151, - 154, - 157, - 160, - 163, - 166, - 169, - 172, - 175, - 178, - 181, - 184, - 187, - 190, - 193, - 196, - 199, - 202, - 205, - 208, - 211, - 214, - 217, - 220, - 223, - 226, - 229, - 232, - 235, - 238, - 241, - 244, - 247, - 250, - 253, - 256, - 259, - 262, - 265, - 268, - 271, - 274, - 277, - 280, - 283, - 286, - 289, - 292, - 295, - 298, - 301, - ], - ) From 4b364d359c6eee4650e4a94ddb738b7dd9c8b57c Mon Sep 17 00:00:00 2001 From: ayhm01 Date: Mon, 6 Jan 2025 18:16:42 +0200 Subject: [PATCH 132/151] Added date --- solutions/substitution_cipher.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/substitution_cipher.py b/solutions/substitution_cipher.py index 32fb65a52..ca8f0d43b 100644 --- a/solutions/substitution_cipher.py +++ b/solutions/substitution_cipher.py @@ -4,7 +4,7 @@ shifting lower and uppercase letter by a fixed value of 3 (as per the challenge) """ -# Author: AYHAM +# Author: AYHAM, 1/1/2025 import string From 240ab59a31821b59ee139683a0978fc2db130cb1 Mon Sep 17 00:00:00 2001 From: reunicorn1 <138371895+reunicorn1@users.noreply.github.com> Date: Mon, 6 Jan 2025 20:26:48 +0400 Subject: [PATCH 133/151] Fixing failing checks --- solutions/tests/test_arithmetic_sequence.py | 164 -------------------- 1 file changed, 164 deletions(-) delete mode 100644 solutions/tests/test_arithmetic_sequence.py diff --git a/solutions/tests/test_arithmetic_sequence.py b/solutions/tests/test_arithmetic_sequence.py deleted file mode 100644 index 5fe1172a3..000000000 --- a/solutions/tests/test_arithmetic_sequence.py +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Created on Monday/30/December/2024 -@author:Mayar Ali -""" - -import unittest - -# ---imports & test class before documenting and testing--- -# from ..arithmetic_sequence import arithmetic_sequence -# class TestArithmeticSequence(unittest.TestCase): -# ---imports & test class after documenting and testing--- - -from ..arithmetic_sequence import arithmetic_sequence - - -class TestArithmeticSequence(unittest.TestCase): - """Test the arithmetic_sequence function""" - - def test_0(self): - "It should evaluate 0 to []" - self.assertEqual(arithmetic_sequence(0), []) - - def test_1(self): - "Should evaluate 1 to [0]" - self.assertEqual(arithmetic_sequence(1), [1]) - - def test_2(self): - "Should evaluate 2 to [0,1]" - self.assertEqual(arithmetic_sequence(2), [0, 1]) - - def test_3(self): - "Should evaluate 3 to [0, 1, 5]" - self.assertEqual(arithmetic_sequence(3), [0, 1, 4]) - - # defensive cases - - def test_0_less_than_0(self): - """It should raise an assertion error if the argument is less than 0""" - with self.assertRaises(AssertionError): - arithmetic_sequence(-1) - - def test_1_not_an_integer(self): - """Should raise an assertion error if the argument is a float""" - with self.assertRaises(AssertionError): - arithmetic_sequence(1.0) - - def test_2_not_an_integer(self): - """Should raise an assertion error if the argument is not an integer""" - with self.assertRaises(AssertionError): - arithmetic_sequence(["1", 2, 3]) - - # Edge case - - def test_a_big_number(self): - "Should evaluate 100 to [0, 1, 5]" - self.assertEqual( - arithmetic_sequence(102), - [ - 0, - 1, - 4, - 7, - 10, - 13, - 16, - 19, - 22, - 25, - 28, - 31, - 34, - 37, - 40, - 43, - 46, - 49, - 52, - 55, - 58, - 61, - 64, - 67, - 70, - 73, - 76, - 79, - 82, - 85, - 88, - 91, - 94, - 97, - 100, - 103, - 106, - 109, - 112, - 115, - 118, - 121, - 124, - 127, - 130, - 133, - 136, - 139, - 142, - 145, - 148, - 151, - 154, - 157, - 160, - 163, - 166, - 169, - 172, - 175, - 178, - 181, - 184, - 187, - 190, - 193, - 196, - 199, - 202, - 205, - 208, - 211, - 214, - 217, - 220, - 223, - 226, - 229, - 232, - 235, - 238, - 241, - 244, - 247, - 250, - 253, - 256, - 259, - 262, - 265, - 268, - 271, - 274, - 277, - 280, - 283, - 286, - 289, - 292, - 295, - 298, - 301, - ], - ) From 36de9fc843e2749a7b1442cfa0a940f6b86eda9d Mon Sep 17 00:00:00 2001 From: ayhm01 Date: Mon, 6 Jan 2025 18:28:02 +0200 Subject: [PATCH 134/151] added factorial calculator --- solutions/factorial_calculator.py | 1 - 1 file changed, 1 deletion(-) diff --git a/solutions/factorial_calculator.py b/solutions/factorial_calculator.py index 629799c6c..c6d3165cf 100644 --- a/solutions/factorial_calculator.py +++ b/solutions/factorial_calculator.py @@ -8,7 +8,6 @@ By convention, 0! = 1. """ - # Author: AYHAM, 6/jan/2025 From 19af515e1bfe764d1b0a1b09d082181b6c9ebd0a Mon Sep 17 00:00:00 2001 From: ayhm01 Date: Mon, 6 Jan 2025 18:49:26 +0200 Subject: [PATCH 135/151] added factorial_calculator --- solutions/factorial_calculator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/solutions/factorial_calculator.py b/solutions/factorial_calculator.py index c6d3165cf..e0860ff34 100644 --- a/solutions/factorial_calculator.py +++ b/solutions/factorial_calculator.py @@ -8,7 +8,8 @@ By convention, 0! = 1. """ -# Author: AYHAM, 6/jan/2025 +# Author: AYHAM +# Date: 6/jan/2025 def factorial(n: int) -> int: From 4d11fb04b9a97c6c4be8ef5686524b4fb685fc90 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Mon, 6 Jan 2025 22:23:20 +0400 Subject: [PATCH 136/151] Modified the code by restructuring the if/elif and the parameters names --- solutions/fuel_gauge.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py index fbc35ca08..543e2d6c2 100644 --- a/solutions/fuel_gauge.py +++ b/solutions/fuel_gauge.py @@ -1,13 +1,13 @@ """module calculates the percentage of fuel in a tank and returns a status indicator.""" -def fuel_gauge(x: int, y: int) -> str: +def fuel_gauge(fuel_amount: int, tank_capacity: int) -> str: """ Calculates the percentage of fuel in a tank and returns a status indicator. Parameters: - x (int): Fuel in the tank (must be ≤ y). - y (int): Tank capacity (must be > 0). + fuel_amount (int): Fuel in the tank (must be ≤ tank_capacity). + tank_capacity (int): Tank capacity (must be > 0). Returns: str: @@ -17,7 +17,7 @@ def fuel_gauge(x: int, y: int) -> str: - "Invalid input" for invalid inputs. Raises: - AssertionError: If y <= 0 or x > y. + AssertionError: If tank_capacity <= 0 or fuel_amount > tank_capacity. Examples: >>> fuel_gauge(90, 100) @@ -27,13 +27,13 @@ def fuel_gauge(x: int, y: int) -> str: >>> fuel_gauge(50, 100) 'M' """ - if y == 0 or x > y: - return "Invalid input" + if tank_capacity <= 0 or fuel_amount > tank_capacity: + raise AssertionError("Invalid tank capacity or fuel amount") + + percentage = (fuel_amount / tank_capacity) * 100 - percentage = (x / y) * 100 if percentage >= 90: return "F" - elif percentage <= 10: + if percentage <= 10: return "E" - else: - return "M" + return "M" From 7210394075c14fad48c8259c6106dec3e2a09e80 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Mon, 6 Jan 2025 22:34:01 +0400 Subject: [PATCH 137/151] Fixing the pytest --- solutions/tests/test_fuel_gauge.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/solutions/tests/test_fuel_gauge.py b/solutions/tests/test_fuel_gauge.py index d1d8aed8a..4d7072eea 100644 --- a/solutions/tests/test_fuel_gauge.py +++ b/solutions/tests/test_fuel_gauge.py @@ -26,5 +26,7 @@ def test_percentage(self): def test_invalid_input(self): """Test cases for invalid inputs.""" - self.assertEqual(fuel_gauge(6, 0), "Invalid input") - self.assertEqual(fuel_gauge(7, -1), "Invalid input") + with self.assertRaises(AssertionError): + fuel_gauge(6, 0) + with self.assertRaises(AssertionError): + fuel_gauge(7, -1) From 876216910c31ff8b34a41b641dd1645f655e7f63 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Mon, 6 Jan 2025 22:46:33 +0400 Subject: [PATCH 138/151] keeping only one in the unittests --- solutions/fuel_gauge.py | 4 +++- solutions/tests/test_fuel_gauge.py | 9 +++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py index 543e2d6c2..b78b93b65 100644 --- a/solutions/fuel_gauge.py +++ b/solutions/fuel_gauge.py @@ -1,4 +1,6 @@ -"""module calculates the percentage of fuel in a tank and returns a status indicator.""" +"""module calculates the percentage of fuel in a tank and returns a status indicator. +Created on Sunday/29/December/2024 +Author: Ahmed Elhassan""" def fuel_gauge(fuel_amount: int, tank_capacity: int) -> str: diff --git a/solutions/tests/test_fuel_gauge.py b/solutions/tests/test_fuel_gauge.py index 4d7072eea..7f743115f 100644 --- a/solutions/tests/test_fuel_gauge.py +++ b/solutions/tests/test_fuel_gauge.py @@ -9,24 +9,21 @@ class TestFuelGauge(unittest.TestCase): def test_full(self): """Test cases where the percentage is 90% or more it should result in F.""" self.assertEqual(fuel_gauge(90, 100), "F") - self.assertEqual(fuel_gauge(100, 100), "F") - self.assertEqual(fuel_gauge(97, 100), "F") def test_empty(self): """Test cases where the percentage is 10% or less it should result E.""" - self.assertEqual(fuel_gauge(10, 100), "E") self.assertEqual(fuel_gauge(0, 100), "E") - self.assertEqual(fuel_gauge(2, 100), "E") def test_percentage(self): """Test cases where the result is between 90 and 10 it should be M.""" - self.assertEqual(fuel_gauge(71, 100), "M") self.assertEqual(fuel_gauge(23, 100), "M") - self.assertEqual(fuel_gauge(10, 50), "M") def test_invalid_input(self): """Test cases for invalid inputs.""" with self.assertRaises(AssertionError): fuel_gauge(6, 0) + + def test_negative_input(self): + """Test cases for negative inputs.""" with self.assertRaises(AssertionError): fuel_gauge(7, -1) From 581e942e99fad6308e3bdd80617032dc7332b8ab Mon Sep 17 00:00:00 2001 From: safaishag Date: Mon, 6 Jan 2025 21:51:08 +0200 Subject: [PATCH 139/151] modification --- solutions/summation.py | 5 +--- solutions/tests/test_summation.py | 39 +++++++++++++++++-------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/solutions/summation.py b/solutions/summation.py index d32885492..f2a3c4c11 100644 --- a/solutions/summation.py +++ b/solutions/summation.py @@ -43,10 +43,7 @@ def sum(*args: float) -> float: if not all(isinstance(arg, (int, float)) for arg in args): raise TypeError("All inputs must be numeric (int or float).") - # Initialize a running total to zero - total = 0 - - # Iterate through the input arguments and calculate the sum + # Iterate through the input arguments and calculate the sum total = 0 diff --git a/solutions/tests/test_summation.py b/solutions/tests/test_summation.py index 37b25de32..8f495548e 100644 --- a/solutions/tests/test_summation.py +++ b/solutions/tests/test_summation.py @@ -1,69 +1,74 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- import unittest -""" -unit tests for the summation function - -""" from solutions.summation import sum class TestSum(unittest.TestCase): - """tests for the sum function""" + """It should return the sum of positive numbers""" + def test_sum_positive_numbers(self): - """It should return the sum of a positive numbers""" actual = sum(1, 2, 3, 4, 5) # noqa: F841 expected = 15 # noqa: F841 self.assertEqual(actual, expected) # noqa: F821 + """It should return the sum of a negative numbers""" + def test_sum_negative_numbers(self): - """It should return the sum of a negative numbers""" actual = sum(-1, -2, -3, -5) # noqa: F841 expected = -11 self.assertEqual(actual, expected) - def test_sum_mixed_numbers(self): - """It should return the sum of a mix numbers""" + """It should return the sum of a mix numbers""" + def test_sum_mixed_numbers(self): actual = sum(10, -20, -40, 50) expected = 0 self.assertEqual(actual, expected) - def test_sum_float_numbers(self): - """It should return the sum of a float numbers""" + """It should return the sum of a float numbers""" + def test_sum_float_numbers(self): actual = sum(1.5, 2.5, 3.7, 4.5) expected = 12.2 self.assertEqual(actual, expected) + """It should return the sum of zero numbers""" + def test_sum_zero_numbers(self): - """It should return the sum of zero numbers""" actual = sum(0, 0, 0, 0) expected = 0 self.assertEqual(actual, expected) + """It should return the single argument when only one is provided.""" + def test_sum_single_argument(self): - """It should return the single argument when only one is provided.""" actual = sum(10) expected = 10 self.assertEqual(actual, expected) + """It should return 0 when no arguments are provided.""" + def test_sum_no_arguments(self): - """It should return 0 when no arguments are provided.""" actual = sum() expected = 0 self.assertEqual(actual, expected) + """It should raise a TypeError for string input.""" + def test_invalid_input_string(self): - """It should raise a TypeError for string input.""" with self.assertRaises(TypeError): sum(1, 2, "string", 4) + """It should raise a TypeError for None as an input.""" + def test_invalid_input_none(self): - """It should raise a TypeError for None as an input.""" with self.assertRaises(TypeError): sum(1, None, 3) + """It should raise a TypeError for mixed valid and invalid inputs.""" + def test_invalid_input_mixed(self): - """It should raise a TypeError for mixed valid and invalid inputs.""" with self.assertRaises(TypeError): sum(10, 5, "invalid", 2) From 0f1f34bdcbebdc629d28b926b3b72ea65599c499 Mon Sep 17 00:00:00 2001 From: mxz Date: Mon, 6 Jan 2025 22:51:40 +0200 Subject: [PATCH 140/151] adding a new test --- solutions/tests/test_draw_triangle.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/solutions/tests/test_draw_triangle.py b/solutions/tests/test_draw_triangle.py index 63386a330..d9c19f578 100644 --- a/solutions/tests/test_draw_triangle.py +++ b/solutions/tests/test_draw_triangle.py @@ -50,3 +50,8 @@ def test_zero_input(self): """test the function with zero as the input""" with self.assertRaises(ValueError): draw_triangle(0) + + def test_small_input(self): + """test the function with the smallest input""" + draw_triangle(1) + self.assertEqual(self.captured_output.getvalue(), "*\n") From 1a81f85d223ff6929ab3804f2603ecf7ee38ecf1 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Tue, 7 Jan 2025 09:34:42 +0400 Subject: [PATCH 141/151] fixing conflict 1 --- how {pull_request_id} | 50 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 how {pull_request_id} diff --git a/how {pull_request_id} b/how {pull_request_id} new file mode 100644 index 000000000..6a6a3d653 --- /dev/null +++ b/how {pull_request_id} @@ -0,0 +1,50 @@ +commit 876216910c31ff8b34a41b641dd1645f655e7f63 (HEAD -> fuel-gauge, origin/fuel-gauge) +Author: Goutbi +Date: Mon Jan 6 22:46:33 2025 +0400 + + keeping only one in the unittests + +diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py +index 543e2d6..b78b93b 100644 +--- a/solutions/fuel_gauge.py ++++ b/solutions/fuel_gauge.py +@@ -1,4 +1,6 @@ +-"""module calculates the percentage of fuel in a tank and returns a status indicator.""" ++"""module calculates the percentage of fuel in a tank and returns a status indicator. ++Created on Sunday/29/December/2024 ++Author: Ahmed Elhassan""" +  +  + def fuel_gauge(fuel_amount: int, tank_capacity: int) -> str: +diff --git a/solutions/tests/test_fuel_gauge.py b/solutions/tests/test_fuel_gauge.py +index 4d7072e..7f74311 100644 +--- a/solutions/tests/test_fuel_gauge.py ++++ b/solutions/tests/test_fuel_gauge.py +@@ -9,24 +9,21 @@ class TestFuelGauge(unittest.TestCase): + def test_full(self): + """Test cases where the percentage is 90% or more it should result in F.""" + self.assertEqual(fuel_gauge(90, 100), "F") +- self.assertEqual(fuel_gauge(100, 100), "F") +- self.assertEqual(fuel_gauge(97, 100), "F") +  + def test_empty(self): + """Test cases where the percentage is 10% or less it should result E.""" +- self.assertEqual(fuel_gauge(10, 100), "E") + self.assertEqual(fuel_gauge(0, 100), "E") +- self.assertEqual(fuel_gauge(2, 100), "E") +  + def test_percentage(self): + """Test cases where the result is between 90 and 10 it should be M.""" +- self.assertEqual(fuel_gauge(71, 100), "M") + self.assertEqual(fuel_gauge(23, 100), "M") +- self.assertEqual(fuel_gauge(10, 50), "M") +  + def test_invalid_input(self): + """Test cases for invalid inputs.""" + with self.assertRaises(AssertionError): + fuel_gauge(6, 0) ++ ++ def test_negative_input(self): ++ """Test cases for negative inputs.""" + with self.assertRaises(AssertionError): + fuel_gauge(7, -1) From 6c75c290ea4032a3a732304ea16a0f03b5af4da4 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Tue, 7 Jan 2025 09:36:55 +0400 Subject: [PATCH 142/151] fixing conflict 2 --- how {pull_request_id} | 50 ------------------------------------------- 1 file changed, 50 deletions(-) delete mode 100644 how {pull_request_id} diff --git a/how {pull_request_id} b/how {pull_request_id} deleted file mode 100644 index 6a6a3d653..000000000 --- a/how {pull_request_id} +++ /dev/null @@ -1,50 +0,0 @@ -commit 876216910c31ff8b34a41b641dd1645f655e7f63 (HEAD -> fuel-gauge, origin/fuel-gauge) -Author: Goutbi -Date: Mon Jan 6 22:46:33 2025 +0400 - - keeping only one in the unittests - -diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py -index 543e2d6..b78b93b 100644 ---- a/solutions/fuel_gauge.py -+++ b/solutions/fuel_gauge.py -@@ -1,4 +1,6 @@ --"""module calculates the percentage of fuel in a tank and returns a status indicator.""" -+"""module calculates the percentage of fuel in a tank and returns a status indicator. -+Created on Sunday/29/December/2024 -+Author: Ahmed Elhassan""" -  -  - def fuel_gauge(fuel_amount: int, tank_capacity: int) -> str: -diff --git a/solutions/tests/test_fuel_gauge.py b/solutions/tests/test_fuel_gauge.py -index 4d7072e..7f74311 100644 ---- a/solutions/tests/test_fuel_gauge.py -+++ b/solutions/tests/test_fuel_gauge.py -@@ -9,24 +9,21 @@ class TestFuelGauge(unittest.TestCase): - def test_full(self): - """Test cases where the percentage is 90% or more it should result in F.""" - self.assertEqual(fuel_gauge(90, 100), "F") -- self.assertEqual(fuel_gauge(100, 100), "F") -- self.assertEqual(fuel_gauge(97, 100), "F") -  - def test_empty(self): - """Test cases where the percentage is 10% or less it should result E.""" -- self.assertEqual(fuel_gauge(10, 100), "E") - self.assertEqual(fuel_gauge(0, 100), "E") -- self.assertEqual(fuel_gauge(2, 100), "E") -  - def test_percentage(self): - """Test cases where the result is between 90 and 10 it should be M.""" -- self.assertEqual(fuel_gauge(71, 100), "M") - self.assertEqual(fuel_gauge(23, 100), "M") -- self.assertEqual(fuel_gauge(10, 50), "M") -  - def test_invalid_input(self): - """Test cases for invalid inputs.""" - with self.assertRaises(AssertionError): - fuel_gauge(6, 0) -+ -+ def test_negative_input(self): -+ """Test cases for negative inputs.""" - with self.assertRaises(AssertionError): - fuel_gauge(7, -1) From bd8b380d10159c9dcbfcc55da7f5ce16af9f24cf Mon Sep 17 00:00:00 2001 From: safaishag Date: Tue, 7 Jan 2025 14:15:27 +0200 Subject: [PATCH 143/151] adding docstring --- solutions/tests/test_summation.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/solutions/tests/test_summation.py b/solutions/tests/test_summation.py index 8f495548e..7ac83fa8e 100644 --- a/solutions/tests/test_summation.py +++ b/solutions/tests/test_summation.py @@ -1,9 +1,12 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +"" +unit tests for the summation function +""" import unittest from solutions.summation import sum - +"""tests for the sum function""" class TestSum(unittest.TestCase): """It should return the sum of positive numbers""" From 3d07ec7f959b9744cfc0e31f20d054c44d9a0ff9 Mon Sep 17 00:00:00 2001 From: safaishag Date: Tue, 7 Jan 2025 20:53:41 +0200 Subject: [PATCH 144/151] modified file --- solutions/tests/test_summation.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/solutions/tests/test_summation.py b/solutions/tests/test_summation.py index 7ac83fa8e..382471f40 100644 --- a/solutions/tests/test_summation.py +++ b/solutions/tests/test_summation.py @@ -1,13 +1,16 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -"" +""" unit tests for the summation function """ + import unittest from solutions.summation import sum + """tests for the sum function""" + class TestSum(unittest.TestCase): """It should return the sum of positive numbers""" From 8a820f7a5e6a94242753f37985ee41e4f67c4033 Mon Sep 17 00:00:00 2001 From: Goutbi Date: Wed, 8 Jan 2025 00:03:08 +0400 Subject: [PATCH 145/151] modified the tests and added boundry tests --- solutions/armstrong_checker.py | 22 ++++++-------- solutions/tests/test_armstrong_checker.py | 35 +++++++++++++++++------ 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/solutions/armstrong_checker.py b/solutions/armstrong_checker.py index 087d35cfb..d203b79d5 100644 --- a/solutions/armstrong_checker.py +++ b/solutions/armstrong_checker.py @@ -1,4 +1,7 @@ -"""Module checks if a number is an Armstrong number.""" +"""Module checks if a number is an Armstrong number. +Created on 2025-01-02 +Author: Ahmed +""" def armstrong_checker(number: int) -> str: @@ -12,31 +15,24 @@ def armstrong_checker(number: int) -> str: str: - "True" if the number is an Armstrong number. - "False" if the number is not an Armstrong number. - - "Invalid input" for invalid inputs. Raises: - AssertionError: If the input is not a positive integer. + ValueError: If the input is not a positive integer. Examples: >>> armstrong_checker(153) 'True' >>> armstrong_checker(123) 'False' - >>> armstrong_checker(-153) - 'Invalid input' + >>> armstrong_checker(9474) + 'True' """ - if not isinstance(number, int) or number < 0: - return "Invalid input" + if not isinstance(number, int) or number <= 0: + raise ValueError("Invalid input: number must be a positive integer.") # Calculate the sum of the nth power of each digit in the number. digits = [int(d) for d in str(number)] - # digits puts each digit in the number into a list - n = len(digits) - # n is the number of digits in the number by using the len() function - armstrong_sum = sum(d**n for d in digits) - # armstrong_sum is the sum of the nth power of each digit in the number return "True" if armstrong_sum == number else "False" - # if the sum of the nth power of each digit in the number is equal to the number, return "True", otherwise return "False" diff --git a/solutions/tests/test_armstrong_checker.py b/solutions/tests/test_armstrong_checker.py index 54aec7a8a..82ec5b0d4 100644 --- a/solutions/tests/test_armstrong_checker.py +++ b/solutions/tests/test_armstrong_checker.py @@ -1,3 +1,7 @@ +""" +Unit tests for the armstrong_checker module. +""" + import unittest from ..armstrong_checker import armstrong_checker @@ -9,16 +13,31 @@ class TestArmstrongChecker(unittest.TestCase): def test_valid_armstrong_numbers(self): """Test cases where the number is an Armstrong number.""" self.assertEqual(armstrong_checker(153), "True") - self.assertEqual(armstrong_checker(9474), "True") - self.assertEqual(armstrong_checker(9475), "False") def test_non_armstrong_numbers(self): """Test cases where the number is not an Armstrong number.""" self.assertEqual(armstrong_checker(123), "False") - self.assertEqual(armstrong_checker(100), "False") - def test_invalid_inputs(self): - """Test cases for invalid inputs.""" - self.assertEqual(armstrong_checker(-153), "Invalid input") - self.assertEqual(armstrong_checker("153"), "Invalid input") - self.assertEqual(armstrong_checker(0.5), "Invalid input") + def test_invalid_input_negative_number(self): + """Test case for a negative number input.""" + with self.assertRaises(ValueError): + armstrong_checker(-153) + + def test_invalid_input_string(self): + """Test case for a string input.""" + with self.assertRaises(ValueError): + armstrong_checker("153") + + def test_invalid_input_float(self): + """Test case for a float input.""" + with self.assertRaises(ValueError): + armstrong_checker(0.5) + + def test_armstrong_number_single_digit(self): + """Test a single-digit Armstrong number.""" + self.assertEqual(armstrong_checker(5), "True") + + def test_invalid_input_zero(self): + """Test zero as input (invalid).""" + with self.assertRaises(ValueError): + armstrong_checker(0) From 426e1e2c77964590958da492698710f6dd64a38f Mon Sep 17 00:00:00 2001 From: safaishag Date: Thu, 9 Jan 2025 00:30:28 +0200 Subject: [PATCH 146/151] modified file --- collaboration/retrospective.md | 131 ++++++++++++++++++++++++++++++--- 1 file changed, 119 insertions(+), 12 deletions(-) diff --git a/collaboration/retrospective.md b/collaboration/retrospective.md index 74e18813b..5c9993511 100644 --- a/collaboration/retrospective.md +++ b/collaboration/retrospective.md @@ -1,23 +1,130 @@ - +# **Project Retrospective** -# Retrospective +This retrospective document summarizes the team's experience, +achievements, and lessons learned during this project cycle. -## Stop Doing +--- -## Continue Doing +## **What Went Well** -## Start Doing +- **Timing & Schedule Adherence**: The team consistently adhered to the + schedule, completing the project ahead of time. +- **Collaboration**: Teamwork was exceptional, with strong collaboration + and active participation from all members. +- **Communication**: Open, transparent communication fostered + a positive and supportive environment. +- **Team Dynamics**: Members formed strong friendships and + created a safe, welcoming atmosphere for collaboration. +- **Task Contributions**: Every member contributed meaningfully, + creating a healthy and efficient workflow. +- **Supportive Environment**: Everyone was willing to assist each + other, ensuring no one was left behind. -## Lessons Learned +--- -______________________________________________________________________ +## **What Didn’t Go as Planned** -## Strategy vs. Board +- **Code Quality Checks**: CI checks were sometimes overlooked +- before merging branches, leading to issues in others’ code. +- **Task Distribution**: Tasks could have been distributed more + evenly among team members. +- **Skill Building**: More focus on coding fundamentals + (e.g., Python basics) was desired, as most workshops emphasized GitHub usage. +- **Workflow Alignment**: The project board alignment could have + been improved for clarity. +- **Time Management**: A few tasks were delayed due + to personal circumstances, highlighting the need for better time tracking. -### What parts of your plan went as expected? +--- -### What parts of your plan did not work out? +## **Unexpected Surprises** -### Did you need to add things that weren't in your strategy? +- **Team Compatibility**: The level of compatibility and cooperation + among team members exceeded expectations. +- **Cultural Connections**: Discovering shared cultural backgrounds + and personal histories created a deeper bond. +- **Willingness to Help**: Team members showed exceptional willingness + to support one another. +- **Friendliness**: Getting to know the team was easy due to their + approachable and collaborative nature. -### Or remove extra steps? +--- + +## **Team Ratings** + +- **Communication and Collaboration**: 4.55/5 average rating. +- **Leadership Effectiveness**: Leadership was highly effective and + supportive, with excellent coordination. + +--- + +## **Challenges and Improvements** + +### **Challenges Encountered** + +- Some inconsistencies in workflow processes (e.g., CI checks, issue handling). +- Occasional delays in task delivery due to individual circumstances. +- Balancing skill levels among experienced and beginner team members. + +### **Improvements Suggested** + +- Distribute tasks more equitably among team members. +- Introduce periodic skill-sharing and mentoring sessions to balance knowledge levels. +- Conduct retrospectives to reflect on learnings and refine workflows. +- Implement structured CI checks to avoid errors in merged branches. + +--- + +## **Key Skills Gained** + +- **Technical**: Proficiency in GitHub, command-line tools, and basic algorithms. +- **Collaboration**: Improved communication, problem-solving, + and teamwork in remote settings. +- **Coding Practices**: Enhanced understanding of coding standards and efficiency. +- **Leadership**: Confidence in guiding and supporting others. + +--- + +## **Future Recommendations** + +### **For Team Collaboration** + +- Continue fostering open communication and collaboration. +- Provide tailored support to address individual strengths and weaknesses. +- Organize more friendly meetings to maintain a positive team spirit. + +### **For Leadership** + +- Assign backup leaders for meetings if the main leader is unavailable. +- Enhance task detailing and ensure equitable workload distribution. + +### **For Workflow** + +- Begin projects earlier to reduce anxiety and ensure ample planning time. +- Periodically review workflows for continuous improvement. + +--- + +## **Next Steps** + +### **Focus Areas for Next Sprint** + +- Enhance coding and problem-solving skills. +- Refine time management strategies. +- Explore more challenging exercises to deepen understanding of key concepts. +- Encourage frequent check-ins and cross-team collaboration to + address potential roadblocks early. + +### **New Skills to Learn** + +- Gain deeper proficiency in advanced coding techniques. +- Improve overall efficiency in managing workflows and deadlines. + +--- + +### **Final Note** + +The success of this project was a testament to the team's dedication, +openness, and collaborative spirit. By building on these strengths and + addressing the identified areas of improvement, future projects can be + even more effective and rewarding. From 9adc1c798370fe31c976cac2fdec751c89f90c0d Mon Sep 17 00:00:00 2001 From: safaishag Date: Thu, 9 Jan 2025 14:12:34 +0200 Subject: [PATCH 147/151] adding word --- collaboration/retrospective.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collaboration/retrospective.md b/collaboration/retrospective.md index 5c9993511..f5e0f1fa1 100644 --- a/collaboration/retrospective.md +++ b/collaboration/retrospective.md @@ -8,7 +8,7 @@ achievements, and lessons learned during this project cycle. ## **What Went Well** - **Timing & Schedule Adherence**: The team consistently adhered to the - schedule, completing the project ahead of time. + schedule,completing the project ahead of time. - **Collaboration**: Teamwork was exceptional, with strong collaboration and active participation from all members. - **Communication**: Open, transparent communication fostered From 5811cba3025d9fddde56880a69c20f526dc1f887 Mon Sep 17 00:00:00 2001 From: Safi222 Date: Sun, 12 Jan 2025 16:28:03 +0300 Subject: [PATCH 148/151] addig enhancements --- solutions/LowestCommonAncestor_in_BST.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/solutions/LowestCommonAncestor_in_BST.py b/solutions/LowestCommonAncestor_in_BST.py index 650025d83..53bfd5068 100644 --- a/solutions/LowestCommonAncestor_in_BST.py +++ b/solutions/LowestCommonAncestor_in_BST.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- """ This module for Lowest_Common_Ancestor_in Binary Search Tree function. Author: Safia Gibril From 424849624309e3d036db9893c94ad5100b49d27b Mon Sep 17 00:00:00 2001 From: Safi222 Date: Sun, 12 Jan 2025 16:47:57 +0300 Subject: [PATCH 149/151] adding enhancements --- solutions/armstrong_checker.py | 42 ---- solutions/even_number_count.py | 46 ---- solutions/fuel_gauge.py | 39 --- solutions/tests/test_armstrong_checker.py | 24 -- solutions/tests/test_even_number_count.py | 274 ---------------------- 5 files changed, 425 deletions(-) delete mode 100644 solutions/armstrong_checker.py delete mode 100644 solutions/even_number_count.py delete mode 100644 solutions/fuel_gauge.py delete mode 100644 solutions/tests/test_armstrong_checker.py delete mode 100644 solutions/tests/test_even_number_count.py diff --git a/solutions/armstrong_checker.py b/solutions/armstrong_checker.py deleted file mode 100644 index 087d35cfb..000000000 --- a/solutions/armstrong_checker.py +++ /dev/null @@ -1,42 +0,0 @@ -"""Module checks if a number is an Armstrong number.""" - - -def armstrong_checker(number: int) -> str: - """ - Checks if a given positive integer is an Armstrong number. - - Parameters: - number (int): The number to check (must be > 0). - - Returns: - str: - - "True" if the number is an Armstrong number. - - "False" if the number is not an Armstrong number. - - "Invalid input" for invalid inputs. - - Raises: - AssertionError: If the input is not a positive integer. - - Examples: - >>> armstrong_checker(153) - 'True' - >>> armstrong_checker(123) - 'False' - >>> armstrong_checker(-153) - 'Invalid input' - """ - if not isinstance(number, int) or number < 0: - return "Invalid input" - - # Calculate the sum of the nth power of each digit in the number. - digits = [int(d) for d in str(number)] - # digits puts each digit in the number into a list - - n = len(digits) - # n is the number of digits in the number by using the len() function - - armstrong_sum = sum(d**n for d in digits) - # armstrong_sum is the sum of the nth power of each digit in the number - - return "True" if armstrong_sum == number else "False" - # if the sum of the nth power of each digit in the number is equal to the number, return "True", otherwise return "False" diff --git a/solutions/even_number_count.py b/solutions/even_number_count.py deleted file mode 100644 index 4f076d41c..000000000 --- a/solutions/even_number_count.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -A function that counts the number of even numbers in a countdown from n to 1 - -Module contents: - - even_number_count: gen number for even numbers in the list. - -Created on Monday/ 30/ December/ 2024 -@author: Mayar Ali. -""" - - -def even_number_count(number: list) -> int: - """Returns the number of even numbers on the list. - - Parameters: - int: list, the input list to process - - return - > int: indicating the number of even number in the list - - Raises: - AssertionError: - - Examples: - >>> even_number_count ([1]) - 0 - >>> even_number_count ([2,1]) - 1 - >>> even_number_count ([3,2,1]) - 1 - """ - assert isinstance(number, list) - for num in number: - assert isinstance(num, int) - - count = 0 - - for num in number: - if num % 2 == 0: - count += 1 - return count - - -if __name__ == "__main__": - print(even_number_count([1, 2, 3, 4, 5])) diff --git a/solutions/fuel_gauge.py b/solutions/fuel_gauge.py deleted file mode 100644 index fbc35ca08..000000000 --- a/solutions/fuel_gauge.py +++ /dev/null @@ -1,39 +0,0 @@ -"""module calculates the percentage of fuel in a tank and returns a status indicator.""" - - -def fuel_gauge(x: int, y: int) -> str: - """ - Calculates the percentage of fuel in a tank and returns a status indicator. - - Parameters: - x (int): Fuel in the tank (must be ≤ y). - y (int): Tank capacity (must be > 0). - - Returns: - str: - - "F" if percentage >= 90. - - "E" if percentage <= 10. - - "M" for all other cases. - - "Invalid input" for invalid inputs. - - Raises: - AssertionError: If y <= 0 or x > y. - - Examples: - >>> fuel_gauge(90, 100) - 'F' - >>> fuel_gauge(10, 100) - 'E' - >>> fuel_gauge(50, 100) - 'M' - """ - if y == 0 or x > y: - return "Invalid input" - - percentage = (x / y) * 100 - if percentage >= 90: - return "F" - elif percentage <= 10: - return "E" - else: - return "M" diff --git a/solutions/tests/test_armstrong_checker.py b/solutions/tests/test_armstrong_checker.py deleted file mode 100644 index 54aec7a8a..000000000 --- a/solutions/tests/test_armstrong_checker.py +++ /dev/null @@ -1,24 +0,0 @@ -import unittest - -from ..armstrong_checker import armstrong_checker - - -class TestArmstrongChecker(unittest.TestCase): - """Test cases for the armstrong_checker function.""" - - def test_valid_armstrong_numbers(self): - """Test cases where the number is an Armstrong number.""" - self.assertEqual(armstrong_checker(153), "True") - self.assertEqual(armstrong_checker(9474), "True") - self.assertEqual(armstrong_checker(9475), "False") - - def test_non_armstrong_numbers(self): - """Test cases where the number is not an Armstrong number.""" - self.assertEqual(armstrong_checker(123), "False") - self.assertEqual(armstrong_checker(100), "False") - - def test_invalid_inputs(self): - """Test cases for invalid inputs.""" - self.assertEqual(armstrong_checker(-153), "Invalid input") - self.assertEqual(armstrong_checker("153"), "Invalid input") - self.assertEqual(armstrong_checker(0.5), "Invalid input") diff --git a/solutions/tests/test_even_number_count.py b/solutions/tests/test_even_number_count.py deleted file mode 100644 index 303ee6a07..000000000 --- a/solutions/tests/test_even_number_count.py +++ /dev/null @@ -1,274 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Created on Monday/ 30/ December/2024 -@author: Mayar Ali - -""" - -import unittest - -# --- imports & test class before documenting and testing --- - -# from ..TestEvenNumberCount import TestEvenNumberCount - -# class TestTestEvenNumberCount(unittest.TestCase): - -# --- imports & test class after documenting and testing --- - -from ..even_number_count import even_number_count # type: ignore - - -class TestEvenNumberCount(unittest.TestCase): - """test the even_number_count function""" - - def test_0(self): - """It should return zero""" - self.assertEqual(even_number_count([1]), 0) - - def test_1(self): - """Count the number of even numbers in a countdown from n to 1""" - self.assertEqual(even_number_count([1, 2]), 1) - - def test_2(self): - """Count the number of even numbers in a countdown from n to 1""" - self.assertEqual(even_number_count([1, 2, 3]), 1) - - def test_3(self): - """Count the number of even numbers in a countdown from n to 1""" - self.assertEqual(even_number_count([1, 2, 3, 4]), 2) - - def test_4(self): - """Count the number of even numbers in a countdown from n to 1""" - self.assertEqual(even_number_count([1, 2, 3, 4, 5]), 2) - - def test_5(self): - """Count the number of even numbers in a countdown from n to 1""" - self.assertEqual(even_number_count([1, 2, 3, 4, 5, 6]), 3) - - def test_6(self): - """Count the number of even numbers in a countdown from n to 1""" - self.assertEqual(even_number_count([1, 2, 3, 4, 5, 6, 7]), 3) - - # Boundary case - - def test_big_numbers(self): - """it should evaluate 100 to [1,2,3,4,5,...]""" - self.assertEqual( - even_number_count( - [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 96, - 97, - 98, - 99, - 100, - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120, - 121, - 122, - 123, - 124, - 125, - 126, - 127, - 128, - 129, - 130, - 131, - 132, - 133, - 134, - 135, - 136, - 137, - 138, - 139, - 140, - 141, - 142, - 143, - 145, - 146, - 147, - 148, - 149, - 150, - 151, - 152, - 153, - 154, - 155, - 156, - 157, - 158, - 159, - 160, - 161, - 162, - 163, - 164, - 165, - 166, - 167, - 168, - 169, - 170, - 171, - 172, - 173, - 174, - 175, - 176, - 177, - 178, - 179, - 180, - 181, - 182, - 183, - 184, - 185, - 186, - 187, - 188, - 189, - 190, - 191, - 192, - 193, - 194, - 195, - 196, - 197, - 198, - 199, - 200, - ] - ), - 99, - ) - - # Defensive cases - - def test_0_less_than_0(self): - """Raise an assertion error if the there is a string within a list""" - with self.assertRaises(AssertionError): - (even_number_count([1, 2, "-6", 4]),) - - def test_0_less_than_1(self): - """Raise an assertion error if the there is a list within a list""" - with self.assertRaises(AssertionError): - even_number_count([1, 2, [1, 2, 3], 4]) From f648c98d3976fbd73c79076dcc40ff9ce860bdde Mon Sep 17 00:00:00 2001 From: Safi222 Date: Sun, 12 Jan 2025 17:55:33 +0300 Subject: [PATCH 150/151] solving conflicts --- solutions/copy_from_file_to_file.py | 18 +++++++++--------- solutions/word_count_from_file.py | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/solutions/copy_from_file_to_file.py b/solutions/copy_from_file_to_file.py index d8b118107..65d9f2bcd 100644 --- a/solutions/copy_from_file_to_file.py +++ b/solutions/copy_from_file_to_file.py @@ -37,15 +37,15 @@ def copy_file_to_file(source_file: str, destination_file: str) -> None: """ # Defensive checks - assert os.path.exists( - source_file - ), f"Error: Source file '{source_file}' doesn't exist." - assert source_file.endswith( - ".txt" - ), f"Error: Source file '{source_file}' is not a .txt file." - assert destination_file.endswith( - ".txt" - ), f"Error: Destination file '{destination_file}' is not a .txt file." + assert os.path.exists(source_file), ( + f"Error: Source file '{source_file}' doesn't exist." + ) + assert source_file.endswith(".txt"), ( + f"Error: Source file '{source_file}' is not a .txt file." + ) + assert destination_file.endswith(".txt"), ( + f"Error: Destination file '{destination_file}' is not a .txt file." + ) # Copy operation: Open the source file in read mode with open(source_file, "r") as file_from: diff --git a/solutions/word_count_from_file.py b/solutions/word_count_from_file.py index cc3236e59..7dc4925d7 100644 --- a/solutions/word_count_from_file.py +++ b/solutions/word_count_from_file.py @@ -37,9 +37,9 @@ def word_count_txt_file(file_name) -> int: # Defensive assertions assert os.path.exists(file_name), f"Error:file '{file_name}' doesn't exist" - assert file_name.endswith( - ".txt" - ), f"Error: The file '{file_name}' does not have a .txt extension." + assert file_name.endswith(".txt"), ( + f"Error: The file '{file_name}' does not have a .txt extension." + ) # Open the file safely f = open(file_name, "r") From a0f676df473030fe0e9bd02a7c3f78851fc02922 Mon Sep 17 00:00:00 2001 From: Safi222 Date: Sun, 12 Jan 2025 18:01:30 +0300 Subject: [PATCH 151/151] solving conflicts --- solutions/LowestCommonAncestor_in_BST.py | 35 +---------------- .../tests/test_LowestCommonAncestor_in_BST.py | 39 ------------------- 2 files changed, 2 insertions(+), 72 deletions(-) diff --git a/solutions/LowestCommonAncestor_in_BST.py b/solutions/LowestCommonAncestor_in_BST.py index dc5816a93..53bfd5068 100644 --- a/solutions/LowestCommonAncestor_in_BST.py +++ b/solutions/LowestCommonAncestor_in_BST.py @@ -1,5 +1,5 @@ -<<<<<<< HEAD -======= +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- """ This module for Lowest_Common_Ancestor_in Binary Search Tree function. Author: Safia Gibril @@ -7,7 +7,6 @@ """ ->>>>>>> 2d84195a2d885aeea30f21022568857153a396d5 class TreeNode: """Define class for TreeNode""" @@ -18,19 +17,6 @@ def __init__(self, value=0, left=None, right=None): def lowestCommonAncestor(root: "TreeNode", p: "TreeNode", q: "TreeNode") -> "TreeNode": -<<<<<<< HEAD - """ - Finds the Lowest Common Ancestor (LCA) of two nodes in a Binary Search Tree. - - The Lowest Common Ancestor between two nodes p and q is the lowest node in the tree T - such that both p and q are descendants of the node. The ancestor is allowed to be a - descendant of itself. - - Args: - root (TreeNode): The root of the Binary Search Tree. - p (TreeNode): The first node in the BST. - q (TreeNode): The second node in the BST to find LCA with. -======= r""" Finds the Lowest Common Ancestor (LCA) of two nodes in a Binary Search Tree. @@ -41,22 +27,10 @@ def lowestCommonAncestor(root: "TreeNode", p: "TreeNode", q: "TreeNode") -> "Tre root (TreeNode): The root node of the Binary Search Tree. p (TreeNode): The first node in the tree. q (TreeNode): The second node in the tree. ->>>>>>> 2d84195a2d885aeea30f21022568857153a396d5 Returns: TreeNode: The Lowest Common Ancestor of nodes p and q. -<<<<<<< HEAD - Examples: - Given the Binary Search Tree Structure: - 5 - / \ - 3 8 - / \ / \ - 1 4 7 9 - \ - 2 -======= Raises: ValueError: If any of the inputs (root, p, or q) is None. @@ -83,7 +57,6 @@ def lowestCommonAncestor(root: "TreeNode", p: "TreeNode", q: "TreeNode") -> "Tre 1 4 7 9 \\ 2 ->>>>>>> 2d84195a2d885aeea30f21022568857153a396d5 Example 1: Input: root = [5,3,8,1,4,7,9,null,2], p = 3, q = 8 @@ -93,9 +66,6 @@ def lowestCommonAncestor(root: "TreeNode", p: "TreeNode", q: "TreeNode") -> "Tre Input: root = [5,3,8,1,4,7,9,null,2], p = 3, q = 4 Output: 3 """ -<<<<<<< HEAD - start = root -======= # Check if root, p, or q are None and raise ValueError if so if root is None or p is None or q is None: @@ -110,4 +80,3 @@ def lowestCommonAncestor(root: "TreeNode", p: "TreeNode", q: "TreeNode") -> "Tre candidate = candidate.left else: return candidate ->>>>>>> 2d84195a2d885aeea30f21022568857153a396d5 diff --git a/solutions/tests/test_LowestCommonAncestor_in_BST.py b/solutions/tests/test_LowestCommonAncestor_in_BST.py index b2e00ae40..c04aa676d 100644 --- a/solutions/tests/test_LowestCommonAncestor_in_BST.py +++ b/solutions/tests/test_LowestCommonAncestor_in_BST.py @@ -1,23 +1,15 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ -<<<<<<< HEAD -Test module for Lowest Common Ancestor in Binary search tree function. - -======= Test module for Lowest Common Ancestor in Binary Search Tree function. Author: Safia Gibril Created on: 2.1.2025 ->>>>>>> 2d84195a2d885aeea30f21022568857153a396d5 """ import unittest -<<<<<<< HEAD -======= from solutions.LowestCommonAncestor_in_BST import lowestCommonAncestor ->>>>>>> 2d84195a2d885aeea30f21022568857153a396d5 class TreeNode: """Define class for TreeNode""" @@ -29,36 +21,6 @@ def __init__(self, value=0, left=None, right=None): class TestLowestCommonAncestor(unittest.TestCase): -<<<<<<< HEAD - """Test the Lowest common Ancestor in Binary search tree function - Binary Search Tree structure: - - 5 - / \ - 3 8 - / \ / \ - 1 4 7 9 - \ - 2 - - """ - - -def setUp_BTS(self): - "create Binary search tree from the example" - self.root = TreeNode(5) - self.root.left = TreeNode(3) - self.root.right = TreeNode(8) - self.root.left.left = TreeNode(1) - self.root.left.right = TreeNode(4) - self.root.right.left = TreeNode(7) - self.root.right.right = TreeNode(9) - self.root.left.left.right = TreeNode(2) - - -def test_case_1(self): - "This test case 1" -======= """Test the Lowest Common Ancestor in Binary Search Tree function. Binary Search Tree structure: @@ -149,4 +111,3 @@ def test_assertion_error_q_none(self): """Test when q is None""" with self.assertRaises(ValueError): lowestCommonAncestor(self.root, self.root.left, None) ->>>>>>> 2d84195a2d885aeea30f21022568857153a396d5