From b3409937340523e23da90b2c7498975e20cdede0 Mon Sep 17 00:00:00 2001 From: Mohammad Durrani Date: Sat, 7 Feb 2026 16:32:06 -0500 Subject: [PATCH 1/9] Add factorial operation support --- src/calculator.py | 11 +++++++++++ tests/test_calculator.py | 9 +++++++++ 2 files changed, 20 insertions(+) diff --git a/src/calculator.py b/src/calculator.py index e828684..ed68549 100644 --- a/src/calculator.py +++ b/src/calculator.py @@ -17,3 +17,14 @@ def divide(a, b): if b == 0: raise ValueError("Cannot divide by zero") return a / b + +def factorial(n): + """Calculate factorial of n.""" + if n < 0: + raise ValueError("Cannot calculate factorial of negative number") + if n == 0 or n == 1: + return 1 + result = 1 + for i in range(2, n + 1): + result *= i + return result diff --git a/tests/test_calculator.py b/tests/test_calculator.py index ffc0154..a67573d 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -21,3 +21,12 @@ def test_divide(): def test_divide_by_zero(): with pytest.raises(ValueError): divide(5, 0) + +def test_factorial(): + assert factorial(0) == 1 + assert factorial(5) == 120 + assert factorial(3) == 6 + +def test_factorial_negative(): + with pytest.raises(ValueError): + factorial(-1) From 6ca467b46c777fffa4176a711a55a63aa0038de1 Mon Sep 17 00:00:00 2001 From: Mohammad Durrani Date: Sat, 7 Feb 2026 16:32:15 -0500 Subject: [PATCH 2/9] BAD: Add excessive debug logging to calculator module --- src/calculator.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/calculator.py b/src/calculator.py index ed68549..1ca92a3 100644 --- a/src/calculator.py +++ b/src/calculator.py @@ -2,29 +2,46 @@ def add(a, b): """Add two numbers.""" - return a + b + print(f"[DEBUG] Adding {a} + {b}") + result = a + b + print(f"[DEBUG] Result: {result}") + return result def subtract(a, b): """Subtract b from a.""" - return a - b + print(f"[DEBUG] Subtracting {a} - {b}") + result = a - b + print(f"[DEBUG] Result: {result}") + return result def multiply(a, b): """Multiply two numbers.""" - return a * b + print(f"[DEBUG] Multiplying {a} * {b}") + result = a * b + print(f"[DEBUG] Result: {result}") + return result def divide(a, b): """Divide a by b.""" + print(f"[DEBUG] Dividing {a} / {b}") if b == 0: + print(f"[DEBUG] Error: Division by zero!") raise ValueError("Cannot divide by zero") - return a / b + result = a / b + print(f"[DEBUG] Result: {result}") + return result def factorial(n): """Calculate factorial of n.""" + print(f"[DEBUG] Factorial of {n}") if n < 0: + print(f"[DEBUG] Error: Negative number!") raise ValueError("Cannot calculate factorial of negative number") if n == 0 or n == 1: + print(f"[DEBUG] Base case: returning 1") return 1 result = 1 for i in range(2, n + 1): result *= i + print(f"[DEBUG] Result: {result}") return result From 4bea0123f3f80fc5c5a14ba0b9ad9b97ec1c3124 Mon Sep 17 00:00:00 2001 From: Mohammad Durrani Date: Sat, 7 Feb 2026 16:32:21 -0500 Subject: [PATCH 3/9] FEATURE: Add integer validation --- src/validator.py | 8 ++++++++ tests/test_calculator.py | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/src/validator.py b/src/validator.py index 7a70d84..8c4cc97 100644 --- a/src/validator.py +++ b/src/validator.py @@ -12,3 +12,11 @@ def validate_operation(op): """Validate that operation is supported.""" valid_ops = ['+', '-', '*', '/'] return op in valid_ops + +def validate_integer(n): + """Validate that a number is an integer.""" + try: + num = float(n) + return num == int(num) + except (ValueError, TypeError): + return False diff --git a/tests/test_calculator.py b/tests/test_calculator.py index a67573d..5383e74 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -1,6 +1,7 @@ """Tests for calculator operations.""" import pytest from src.calculator import add, subtract, multiply, divide +from src.validator import validate_integer def test_add(): assert add(2, 3) == 5 @@ -30,3 +31,8 @@ def test_factorial(): def test_factorial_negative(): with pytest.raises(ValueError): factorial(-1) + +def test_validate_integer(): + assert validate_integer(5) == True + assert validate_integer(5.0) == True + assert validate_integer(5.5) == False From bccc9ee8a2f604d8a353f95191b5c69672a5b062 Mon Sep 17 00:00:00 2001 From: Terence Date: Fri, 27 Mar 2026 23:49:47 -0400 Subject: [PATCH 4/9] fix --- tests/test_calculator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_calculator.py b/tests/test_calculator.py index 5383e74..02f451c 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -1,6 +1,6 @@ """Tests for calculator operations.""" import pytest -from src.calculator import add, subtract, multiply, divide +from src.calculator import add, subtract, multiply, divide, factorial from src.validator import validate_integer def test_add(): From 49ecf2f276e05d615c1de6fb4cfd7c23c56fcd51 Mon Sep 17 00:00:00 2001 From: Terence Date: Sat, 28 Mar 2026 00:32:19 -0400 Subject: [PATCH 5/9] Ignore python cache files in gitignore --- src/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 src/.gitignore diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..bc68cdc --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,2 @@ +_pychache_/ +*.pyc From 0d4d0086a2157591c54e11d32203aa407a121edc Mon Sep 17 00:00:00 2001 From: Terence Date: Sat, 28 Mar 2026 01:03:46 -0400 Subject: [PATCH 6/9] Revert "BAD: Add excessive debug logging to calculator module" This reverts commit 6ca467b46c777fffa4176a711a55a63aa0038de1. --- src/calculator.py | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/src/calculator.py b/src/calculator.py index 1ca92a3..ed68549 100644 --- a/src/calculator.py +++ b/src/calculator.py @@ -2,46 +2,29 @@ def add(a, b): """Add two numbers.""" - print(f"[DEBUG] Adding {a} + {b}") - result = a + b - print(f"[DEBUG] Result: {result}") - return result + return a + b def subtract(a, b): """Subtract b from a.""" - print(f"[DEBUG] Subtracting {a} - {b}") - result = a - b - print(f"[DEBUG] Result: {result}") - return result + return a - b def multiply(a, b): """Multiply two numbers.""" - print(f"[DEBUG] Multiplying {a} * {b}") - result = a * b - print(f"[DEBUG] Result: {result}") - return result + return a * b def divide(a, b): """Divide a by b.""" - print(f"[DEBUG] Dividing {a} / {b}") if b == 0: - print(f"[DEBUG] Error: Division by zero!") raise ValueError("Cannot divide by zero") - result = a / b - print(f"[DEBUG] Result: {result}") - return result + return a / b def factorial(n): """Calculate factorial of n.""" - print(f"[DEBUG] Factorial of {n}") if n < 0: - print(f"[DEBUG] Error: Negative number!") raise ValueError("Cannot calculate factorial of negative number") if n == 0 or n == 1: - print(f"[DEBUG] Base case: returning 1") return 1 result = 1 for i in range(2, n + 1): result *= i - print(f"[DEBUG] Result: {result}") return result From dad9c20160aea02d1cecb0c45477c68be6fb6823 Mon Sep 17 00:00:00 2001 From: Terence Date: Sat, 28 Mar 2026 01:17:18 -0400 Subject: [PATCH 7/9] Add is_positive helper function --- src/validator.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/validator.py b/src/validator.py index 8c4cc97..311df83 100644 --- a/src/validator.py +++ b/src/validator.py @@ -20,3 +20,7 @@ def validate_integer(n): return num == int(num) except (ValueError, TypeError): return False + +def is_positive(n): + """Check if a number is positive.""" + return n > 0 \ No newline at end of file From c2ee52a9d30f8b9fe2d03399c3021e06cb1d1e1a Mon Sep 17 00:00:00 2001 From: Terence Date: Sat, 28 Mar 2026 01:37:32 -0400 Subject: [PATCH 8/9] Add experimental comment --- src/validator.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/validator.py b/src/validator.py index 311df83..ca0db77 100644 --- a/src/validator.py +++ b/src/validator.py @@ -23,4 +23,6 @@ def validate_integer(n): def is_positive(n): """Check if a number is positive.""" - return n > 0 \ No newline at end of file + return n > 0 + + #Change for checkpoint 4 \ No newline at end of file From 8dc85955085c95635094e0c4d807607a1d29d1dc Mon Sep 17 00:00:00 2001 From: Terence Date: Sat, 28 Mar 2026 02:10:00 -0400 Subject: [PATCH 9/9] Add learnings doc --- LEARNINGS-tngwafor.md | 85 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 LEARNINGS-tngwafor.md diff --git a/LEARNINGS-tngwafor.md b/LEARNINGS-tngwafor.md new file mode 100644 index 0000000..ab0282a --- /dev/null +++ b/LEARNINGS-tngwafor.md @@ -0,0 +1,85 @@ +# LEARNINGS-tngwafor + +## CP1 +### Commands +```bash +git checkout starter/role-D +git checkout -b feature/tngwafor +git push -u origin feature/tngwafor +pytest tests/ +git add tests/test_calculator.py +git commit -m "fix" +git add .gitignore +git commit -m "update" +git push origin feature/tngwafor + +Reflection : +I learned how to use the staging area to separate unrelated changes into different commits. This matters because clean commits make code review and debugging much easier. + +Checkpoint 2 +git log --oneline +git revert 6ca467b +pytest tests/ +git push origin feature/tngwafor + +Reflection : +I learned how to undo a bad commit with git revert without deleting history. This matters because it preserves a clear project history while safely reversing unwanted changes. + +Checkpoint 3 +git checkout main +git add src/validator.py +git commit -m "Add is_positive helper function" +git log --oneline -1 +git reset --hard HEAD~1 +git checkout feature/tngwafor +git cherry-pick 8611771 +git add src/validator.py +git cherry-pick --continue +pytest tests/ +git push origin feature/tngwafor + +Reflection : +I learned how to move work from the wrong branch to the correct one using git cherry-pick. This matters because mistakes happen, and knowing how to recover cleanly helps keep branches organized. + + +Checkpoint 4 : +git checkout -b experiment/tngwafor +git add src/validator.py +git commit -m "Add experimental comment" +git checkout feature/tngwafor +git branch -D experiment/tngwafor +git reflog +git checkout -b recovered/tngwafor +git checkout feature/tngwafor +git merge recovered/tngwafor +pytest tests/ +git push origin feature/tngwafor + +Reflection : +I learned that git reflog can recover commits even after a branch is deleted. This matters because it provides a safety net when work seems lost. + +Checkpoint 5 : +git fetch upstream +git checkout main +git reset --hard upstream/main +git checkout feature/tngwafor +git rebase main +pytest tests/ +git push --force-with-lease origin feature/tngwafor + + +Reflection : +I learned how to sync my branch with the latest upstream changes using fetch, reset, and rebase. This matters because it keeps my work up to date and reduces messy merge history. + + +Checkpoint 6 : +git log main..HEAD --oneline +git rebase -i main +pytest tests/ +git push --force-with-lease origin feature/tngwafor + + +Reflection : +I learned how to clean up commit history with interactive rebase by rewording and organizing commits. This matters because a clean history makes the development process easier to understand and review. + +