Add a power operator
Done- Plan (done)
- Code (done)
- Test (done)
- Review (done)
- Finish (done)
Cost
$0.0077
Tests
Passed
Iterations
1
Re-plans
0
LLM calls
14
Prompt read from cache
67%
Usage by agent
- Cache read
- Cache write
- Input
- Output
View as table
| Agent | Cost | Cache read | Cache write | Input | Output |
|---|---|---|---|---|---|
| planner | $0.0013 | 4,329 | 3,085 | 8 | 1,820 |
| coder | $0.0027 | 21,899 | 7,674 | 12 | 2,993 |
| tester | $0.0025 | 18,776 | 8,673 | 10 | 2,373 |
| reviewer | $0.0012 | 4,879 | 5,536 | 6 | 928 |
Timeline
-
planner iteration 1 Finished 3 calls · 9,242 tokens · $0.0013 · 11.1s
Loading…
-
coder iteration 1 Finished 5 calls · 32.6K tokens · $0.0027 · 17.9s
Loading…
-
tester iteration 1 Finished 4 calls · 29.8K tokens · $0.0025 · 15.5s
Loading…
-
verify iteration 1 Passed 0.6s
.................... [100%] 20 passed in 0.07s
-
reviewer iteration 1 Finished 2 calls · 11.3K tokens · $0.0012 · 6.3s
Loading…
Final diff
diff --git a/README.md b/README.md index 14ba480..1cf9d54 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,5 @@ A tiny calculator with a known bug, used to demonstrate [DevSwarm](https://githu ```bash python calc.py 8 / 2 ``` + +Exponents use `^`, e.g. `python calc.py 2 ^ 3` prints `8.0`. diff --git a/calc.py b/calc.py index f16c6ca..5c9cde0 100644 --- a/calc.py +++ b/calc.py @@ -16,6 +16,16 @@ def calculate(left: float, operator: str, right: float) -> float: return left * right if operator == "/": return left / right + if operator == "^": + try: + result = left ** right + except ZeroDivisionError: + raise CalculatorError("0 cannot be raised to a negative power") + except OverflowError: + raise CalculatorError("result is too large") + if isinstance(result, complex): + raise CalculatorError("result is not a real number") + return result raise CalculatorError(f"unknown operator: {operator}") diff --git a/test_calc.py b/test_calc.py index 856b0c9..7dce994 100644 --- a/test_calc.py +++ b/test_calc.py @@ -4,7 +4,16 @@ from calc import CalculatorError, calculate, main @pytest.mark.parametrize( ("left", "operator", "right", "expected"), - [(2, "+", 3, 5), (5, "-", 3, 2), (2, "*", 3, 6), (8, "/", 2, 4)], + [ + (2, "+", 3, 5), + (5, "-", 3, 2), + (2, "*", 3, 6), + (8, "/", 2, 4), + (2, "^", 3, 8), + (2, "^", 0, 1), + (9, "^", 0.5, 3.0), + (2, "^", -1, 0.5), + ], ) def test_operations(left, operator, right, expected): assert calculate(left, operator, right) == expected @@ -15,6 +24,21 @@ def test_unknown_operator(): calculate(1, "%", 2) +def test_power_zero_to_negative_power_raises(): + with pytest.raises(CalculatorError): + calculate(0, "^", -1) + + +def test_power_overflow_raises(): + with pytest.raises(CalculatorError): + calculate(10.0, "^", 400.0) + + +def test_power_negative_base_fractional_exponent_raises(): + with pytest.raises(CalculatorError): + calculate(-8, "^", 1 / 3) + + def test_main_prints_result(capsys): assert main(["8", "/", "2"]) == 0 assert capsys.readouterr().out.strip() == "4.0" @@ -23,3 +47,46 @@ def test_main_prints_result(capsys): def test_main_reports_unknown_operator(capsys): assert main(["1", "%", "2"]) == 1 assert "unknown operator" in capsys.readouterr().err + + +def test_main_power(capsys): + assert main(["2", "^", "3"]) == 0 + assert capsys.readouterr().out.strip() == "8.0" + + +def test_main_reports_power_error(capsys): + assert main(["0", "^", "-1"]) == 1 + assert "error:" in capsys.readouterr().err + + +def test_main_power_overflow_reports_error(capsys): + assert main(["10", "^", "400"]) == 1 + assert "error:" in capsys.readouterr().err + + +def test_main_power_complex_result_reports_error(capsys): + assert main(["-8", "^", "0.5"]) == 1 + captured = capsys.readouterr() + assert "error:" in captured.err + assert "j" not in captured.out + + +def test_power_negative_base_integer_exponent_is_real(): + assert calculate(-2, "^", 3) == -8 + + +def test_power_cli_subprocess_prints_8_0(): + import subprocess + import sys + from pathlib import Path + + script = Path(__file__).parent / "calc.py" + completed = subprocess.run( + [sys.executable, str(script), "2", "^", "3"], + capture_output=True, + text=True, + check=False, + ) + assert completed.returncode == 0 + assert completed.stdout.strip() == "8.0" + assert "Traceback" not in completed.stderr