diff --git a/LEARNINGS-120080258.md b/LEARNINGS-120080258.md new file mode 100644 index 0000000..2c253b4 --- /dev/null +++ b/LEARNINGS-120080258.md @@ -0,0 +1,86 @@ +# LEARNINGS-120080258 + +## cp1: staging is not committing + +**Commands:** +``` +git checkout -b starter/role-B origin/starter/role-B +git checkout -b feature/120080258 +git add tests/test_calculator.py +git commit -m "fix" +git add src/validator.py +git commit -m "update" +``` + +**Reflection:** The staging area lets you pick which changes go into each commit and when multiple files are modified. This keeps history clean and makes each commit tell anyone what went on. + + +## cp2: undo without erasing history + +**Commands:** +``` +git log --oneline +git revert b19f233 --no-edit +``` + +**Reflection:** git revert undoes a commit by adding a new one and history stays intact. This is safe for shared branches since it doesn't rewrite anything at all. + +## cp3: moving a commit to the right branch + +**Commands:** +``` +git checkout main +git add src/validator.py +git commit -m "Add is_positive helper function" +git reset --hard HEAD~1 +git checkout feature/120080258 +git cherry-pick 38d4a17 +git add src/validator.py +git cherry-pick --continue --no-edit +``` + +**Reflection:** git cherry-pick lets you replay a specific commit onto any branch. Conflicts just mean both branches touched the same file — resolve them by keeping both sides. + +## cp4: recovering lost work with reflog + +**Commands:** +``` +git checkout -b experiment/120080258 +git add src/calculator.py +git commit -m "Experiment: add placeholder comment for future features" +git checkout feature/120080258 +git branch -D experiment/120080258 +git reflog +git checkout -b recovered/120080258 ea413e6 +git merge recovered/120080258 --no-edit +``` + +**Reflection:** Deleting a branch doesn't delete its commits all git reflog does is tracks every HEAD movement and lets you recover orphaned lost work. + + +## cp5: syncing with upstream + +**Commands:** +``` +git remote add upstream +git fetch upstream +git checkout main +git merge upstream/main +git checkout feature/120080258 +git rebase main +git push --force-with-lease origin feature/120080258 +``` + +**Reflection:** Having a separate upstream remote lets you pull changes from the source project into your fork. Rebasing keeps history linear and makes PRs easier to review. + +## cp6: interactive rebase to clean up history + +**Commands:** +``` +git log main..HEAD --oneline +git rebase -i HEAD~8 +# reworded "fix" and "update" to descriptive messages +git push --force-with-lease origin feature/120080258 +``` + +**Reflection:** Interactive rebase lets you clean up commits before code review — reorder, squash, or reword them. Using --force-with-lease instead of --force prevents overwriting someone else's pushes. diff --git a/src/calculator.py b/src/calculator.py index e828684..672379a 100644 --- a/src/calculator.py +++ b/src/calculator.py @@ -17,3 +17,8 @@ def divide(a, b): if b == 0: raise ValueError("Cannot divide by zero") return a / b + +def power(a, b): + """Raise a to the power of b.""" + return a ** b +# Experimental feature placeholder diff --git a/src/validator.py b/src/validator.py index 7a70d84..04d8a5e 100644 --- a/src/validator.py +++ b/src/validator.py @@ -1,4 +1,8 @@ -"""Input validation for calculator.""" +"""Input validation for calculator. + +handles validation of numbers and operations before they are used +in any calculator function. +""" def validate_number(value): """Validate that value can be converted to a number.""" @@ -12,3 +16,15 @@ def validate_operation(op): """Validate that operation is supported.""" valid_ops = ['+', '-', '*', '/'] return op in valid_ops + +def validate_positive(n): + """Validate that a number is positive.""" + try: + num = float(n) + return num > 0 + except (ValueError, TypeError): + return False + +def is_positive(n): + """check if a number is positive.""" + return n > 0 diff --git a/tests/test_calculator.py b/tests/test_calculator.py index ffc0154..a52231d 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.calculator import add, subtract, multiply, divide, power +from src.validator import validate_positive def test_add(): assert add(2, 3) == 5 @@ -21,3 +22,16 @@ def test_divide(): def test_divide_by_zero(): with pytest.raises(ValueError): divide(5, 0) + +def test_power(): + assert power(2, 3) == 8 + assert power(5, 2) == 25 + assert power(10, 0) == 1 + assert power(2, -1) == 0.5 + assert power(0, 5) == 0 + assert power(1, 100) == 1 + +def test_validate_positive(): + assert validate_positive(5) == True + assert validate_positive(-5) == False + assert validate_positive(0) == False