Project 1: The “Homework Destroyer” (Equation Solver)
Build a deterministic CLI equation solver that handles linear and quadratic equations and explains every algebra step.
Quick Reference
| Attribute | Value |
|---|---|
| Difficulty | Beginner (Level 1) |
| Time Estimate | 6-10 hours |
| Main Programming Language | Python |
| Alternative Programming Languages | JavaScript, C++ |
| Key Topics | Linear equations, quadratic equations, discriminant, algebraic invariants |
| Input Mode | CLI string input (single equation) |
| Output Mode | Step-by-step transcript + structured result + exit code |
| Deterministic Requirements | Fixed formatting, fixed rounding mode, fixed error messages |
1) Learning Objectives
By the end of this project, you should be able to:
- Convert an equation from free-form input into a normalized mathematical form.
- Explain why algebraic transformations preserve truth only when applied symmetrically.
- Solve linear equations and quadratic equations by deterministic decision rules.
- Classify solution sets correctly: one solution, two solutions, repeated root, no real root, infinite solutions, inconsistent equation.
- Verify computed solutions by substitution and tolerance checks.
- Design predictable CLI behavior with explicit success and error exit codes.
2) All Theory Needed (Per-Concept Breakdown)
Concept A: Equality-Preserving Transformations
Fundamentals
An equation is a claim that two expressions have equal value. If you do the same legal operation on both sides, equality remains true. This is the core invariant of algebraic solving. If you add 5 to the left side, you must add 5 to the right side. If you divide by a value, that value cannot be zero. The solver is not “doing tricks”; it is preserving a truth statement while reshaping it into a form where the unknown is isolated.
Definitions and key terms
- Equation: A statement of equality between two expressions.
- Invariant: A property that must remain true at every transformation step.
- Legal transformation: An operation that preserves equivalence under required constraints.
- Equivalent equations: Different-looking equations with the same solution set.
Mental model diagram (ASCII)
Original claim: Left(x) == Right(x)
|
| apply SAME operation F to both sides
v
Transformed claim: F(Left(x)) == F(Right(x))
Invariant: solution set does not change
How it works (step-by-step with failure modes)
- Start from parsed left and right expressions.
- Move all terms to one side to form canonical equation.
- Simplify coefficients.
- Apply solving rule (linear or quadratic).
- Validate by substitution.
Failure modes:
- Division by zero during transformation.
- Accidental asymmetric operation (bug in step logger).
- Rounding-only equality instead of tolerance-based validation.
Minimal concrete example (pseudocode)
Given: 2x + 3 = 11
Step 1: subtract 3 on both sides -> 2x = 8
Step 2: divide both sides by 2 -> x = 4
Check: 2*4 + 3 == 11 (true)
Common misconceptions
- “You can move a term and just change sign” is not magic; it is shorthand for adding/subtracting both sides.
- Equivalent form does not mean same shape; it means same solutions.
- Verification is not optional if you want reliability.
Concept B: Canonical Form and Coefficient Extraction
Fundamentals
Computers solve equations best after normalization. For this project, normalize to ax^2 + bx + c = 0 with missing coefficients allowed. Linear equations are a special case with a = 0. Canonical form gives one consistent pathway for classification and solving. Without normalization, many string patterns explode into edge cases.
Definitions and key terms
- Canonical form: Standard equation layout used for solving.
- Coefficient: Numeric multiplier of variable power.
- Degree: Highest power of the variable in the equation.
- Reducible equation: Expression that simplifies to lower degree.
Mental model diagram (ASCII)
Input string
|
v
Tokenizer -> Parsed terms -> Move all to left -> Combine like terms
|
v
ax^2 + bx + c = 0
How it works
- Parse both sides into term lists.
- Subtract right-side terms from left-side terms.
- Aggregate coefficients by degree.
- Detect highest degree.
- Dispatch to linear/quadratic/unsupported flow.
Failure modes:
- Implicit multiplication not recognized (
2x). - Duplicate signs (
x--2). - Unsupported tokens (functions, powers above 2).
Minimal concrete example (pseudocode)
Input: 3x - 7 = 2x + 5
Normalize:
(3x - 7) - (2x + 5) = 0
x - 12 = 0
a=0, b=1, c=-12
Common misconceptions
- “Linear equations do not need canonical form.” They still benefit from shared classification flow.
- Coefficients are not only integers; rational and decimal inputs must be handled.
Concept C: Quadratic Discriminant Logic
Fundamentals
For ax^2 + bx + c = 0, the discriminant D = b^2 - 4ac determines root behavior in real numbers. If D > 0, two distinct real roots. If D = 0, one repeated real root. If D < 0, no real roots (complex roots exist but can be out-of-scope unless extension). This lets the solver classify before computing roots.
Definitions and key terms
- Discriminant: Quantity controlling root count/type for a quadratic.
- Repeated root: Same real root appearing twice.
- Real root: Solution in real number line.
- Complex root: Solution involving imaginary unit.
Mental model diagram (ASCII)
D = b^2 - 4ac
|
+-----------+-----------+
| | |
D > 0 D = 0 D < 0
2 real 1 real no real
distinct repeated roots
How it works
- Ensure
a != 0for quadratic branch. - Compute
D. - Branch on sign of
D. - If real roots requested and
D < 0, return “no real solution” classification. - Verify each reported root by substitution within tolerance.
Failure modes:
- Negative
Dwith naive square root call causing runtime error. - Catastrophic cancellation for extreme values (advanced concern).
- Root formatting inconsistency causing deterministic test drift.
Minimal concrete example (pseudocode)
Equation: x^2 - 5x + 6 = 0
a=1, b=-5, c=6
D=25-24=1 > 0
x=(5 +- 1)/2 -> x=2, x=3
Common misconceptions
D < 0does not mean “unsolved”; it is a valid classification.D = 0is one unique real value, not two different roots.
Concept D: Validation, Rounding, and Determinism
Fundamentals
Numerical tools must separate mathematical truth from string formatting. Two values can be mathematically equal but printed differently. Deterministic behavior requires fixed rounding rules, stable sort order of roots, and fixed tolerance for substitution checks. Without this, tests become flaky and users lose trust.
Definitions and key terms
- Tolerance: Acceptable numeric deviation (for floating point checks).
- Deterministic output: Same input always yields byte-identical output format.
- Stable ordering: Roots printed in consistent sorted order.
- Golden transcript: Fixed expected output used for acceptance.
Mental model diagram (ASCII)
Compute roots -> Sort -> Round -> Print
| |
+-> Substitute check -+
Pass if residual <= epsilon
How it works
- Compute symbolic/numeric result.
- Sort roots ascending.
- Round to fixed precision (for display only).
- Substitute unrounded values into original equation.
- Print standardized message and exit code.
Failure modes:
- Comparing floats with
==. - Inconsistent locale decimal separator.
- Different rounding in separate output branches.
Minimal concrete example (pseudocode)
for each root r:
residual = abs(LHS(r) - RHS(r))
if residual > 1e-9:
mark invalid
Common misconceptions
- Rounded display value is not always the internal value.
- Deterministic formatting is not “cosmetic”; it is test infrastructure.
3) Project Specification
3.1 Functional Requirements
- Accept one equation input in one variable (
x) from CLI. - Support linear and quadratic polynomials only (degree <= 2).
- Support integers and decimals in coefficients.
- Normalize equation to canonical form and display that form.
- Produce step-by-step solving transcript.
- Classify solution type explicitly.
- Verify solutions by substitution and print residual.
- Return deterministic exit codes.
3.2 Non-Functional Requirements
- Performance: Solve single equation under 100 ms on typical laptop.
- Reliability: Invalid syntax and unsupported degree must not crash.
- Usability: Error messages must identify cause and correction hint.
- Determinism: Same input produces identical text output (line order, precision, labels).
3.3 Example Input/Output Contract
Input shape:
--equation "<expression>=<expression>"
--precision <int> (optional, default 4)
Output shape (success):
STATUS: OK
TYPE: linear|quadratic
CANONICAL: ax^2 + bx + c = 0
STEPS:
[numbered lines]
SOLUTIONS: [ordered list]
CHECK:
residual(root_1)=...
EXIT_CODE: 0
Output shape (failure):
STATUS: ERROR
ERROR_CODE: PARSE_ERROR|UNSUPPORTED_DEGREE|DIVISION_BY_ZERO
MESSAGE: ...
EXIT_CODE: 2
3.4 Edge Cases and Expected Behavior
0x + 5 = 5-> infinite solutions.0x + 5 = 3-> inconsistent, no solution.x^2 + 1 = 0-> no real roots.2x+ = 3-> parse error.x^3 - 1 = 0-> unsupported degree.- Equivalent but differently spaced input (
2x +3=11) -> same normalized output.
3.5 Real World Outcome (Deterministic Transcript)
How to run
$ python3 p01_equation_solver.py --equation "2x+3=11"
Golden path transcript (success)
$ python3 p01_equation_solver.py --equation "x^2-5x+6=0" --precision 4
STATUS: OK
TYPE: quadratic
CANONICAL: 1.0000x^2 + -5.0000x + 6.0000 = 0
STEP 1: Compute discriminant D = b^2 - 4ac = 1.0000
STEP 2: D > 0, so there are two real roots
STEP 3: x1 = 2.0000, x2 = 3.0000
SOLUTIONS: [2.0000, 3.0000]
CHECK: residual(2.0000)=0.0000, residual(3.0000)=0.0000
EXIT_CODE: 0
Failure transcript
$ python3 p01_equation_solver.py --equation "x^3-2=0"
STATUS: ERROR
ERROR_CODE: UNSUPPORTED_DEGREE
MESSAGE: Degree 3 detected. This project supports degree <= 2.
EXIT_CODE: 2
4) Solution Architecture
4.1 High-Level ASCII Diagram
CLI Input
|
v
+------------------+
| Argument Handler |
+------------------+
|
v
+------------------+ +------------------+
| Equation Parser | --> | Normalizer |
+------------------+ +------------------+
|
v
+------------------+
| Solver Dispatcher|
+------------------+
| linear | quadratic
v v
+------------------+
| Step Generator |
+------------------+
|
v
+------------------+
| Validator + I/O |
+------------------+
4.2 Key Components
| Component | Responsibility | Notes |
|---|---|---|
| CLI Handler | Parse flags and enforce required arguments | Keep strict and explicit |
| Parser | Convert equation string into structured terms | Reject unsupported tokens early |
| Normalizer | Move all terms to left and combine coefficients | Produces canonical form |
| Solver | Apply linear/quadratic strategy | Deterministic branch rules |
| Step Logger | Record human-readable algebra steps | Must match math operations exactly |
| Validator | Substitute roots and compute residuals | Uses fixed epsilon |
| Formatter | Stable output formatting and exit code mapping | Drives golden transcripts |
4.3 Algorithm Overview
Core algorithm (conceptual pseudocode):
parse(input_equation)
normalized = canonicalize(left, right)
(a, b, c, degree) = extract_coefficients(normalized)
if degree > 2: error UNSUPPORTED_DEGREE
if degree == 1: solve linear
if degree == 2: solve quadratic via discriminant
for each solution:
residual = abs(LHS(solution) - RHS(solution))
attach check
format deterministic report
Complexity (single equation):
- Time: O(n) for parsing string length
n - Space: O(n) for token/AST representation
5) Implementation Guide
5.1 Setup
# from repository root
$ cd project_based_ideas/MATH/LEARN_HIGH_SCHOOL_MATH_WITH_PYTHON
$ python3 --version
Python 3.10+ required
$ mkdir -p p01_equation_solver/{docs,tests,fixtures}
5.2 Suggested Project Structure
p01_equation_solver/
docs/
transcript_golden.txt
fixtures/
equations_valid.txt
equations_invalid.txt
tests/
parser_cases.md
solver_cases.md
README.md
5.3 Core Question
“How do I convert algebra rules into a reproducible procedure that never lies about what step happened?”
5.4 Prerequisites You Should Be Comfortable With
- Rearranging linear equations while preserving equality.
- Quadratic formula and discriminant interpretation.
- Basic CLI argument patterns and error handling.
- Floating-point tolerance vs exact equality.
5.5 Design Questions
- Parsing strategy: token stream or regex-based extraction?
- Should simplification happen before or after moving all terms to one side?
- How do you represent infinite-solution and no-solution states?
- Should root sorting be numeric ascending or symbolic order?
- What precision policy keeps both readability and stable tests?
5.6 Thinking Exercise (Before Implementation)
Manually solve and classify each:
3x - 7 = 2x + 5x^2 - 4x + 4 = 00x + 9 = 9
Questions:
- Which transformation keeps the invariant explicit?
- Which equation type classification is ambiguous without normalization?
- What should your solver print when there are infinitely many solutions?
5.7 Interview Questions
- Why must algebraic operations be mirrored on both sides?
- How does the discriminant map to root behavior?
- What does it mean for two equations to be equivalent?
- How do you distinguish no solution vs infinite solutions in linear systems?
- Why is deterministic output important for CI pipelines?
5.8 Hints in Layers
- Hint 1: Start with degree-1 equations only and lock output format first.
- Hint 2: Add canonicalization before adding quadratic solving.
- Hint 3: Implement discriminant classification before computing roots.
- Hint 4: Add substitution checks and residual printouts last.
5.9 Implementation Phases
Phase 1 (2-3 hours): Parser + canonicalization for linear equations.
Phase 2 (2-3 hours): Quadratic branch + discriminant classification.
Phase 3 (1-2 hours): Validation, deterministic formatting, and transcripts.
Phase 4 (1-2 hours): Edge-case hardening and acceptance tests.
5.10 Key Implementation Decisions
| Decision | Options | Recommended Choice | Rationale |
|---|---|---|---|
| Internal numeric type | float, Decimal, Fraction | float + tolerance | Simpler for beginner scope |
| Parsing style | Full AST, lightweight tokenizer | lightweight tokenizer | Enough for degree <= 2 |
| Root ordering | discovery order, sorted order | sorted numeric order | Deterministic transcript |
| Output precision | variable, fixed | fixed by --precision |
Predictable testing |
6) Testing Strategy
6.1 Test Categories
| Category | Purpose | Sample |
|---|---|---|
| Unit | Validate parser and coefficient extraction | 2x+3=11 -> (a=0,b=2,c=-8) |
| Integration | Full solve pipeline | Input to final transcript |
| Edge | Degenerate/invalid equations | 0x+5=5, x^3=1, malformed tokens |
| Regression | Prevent output drift | Golden transcript compare |
6.2 Critical Test Cases
- Linear unique solution:
2x+3=11->x=4. - Linear infinite solutions:
0x+5=5. - Linear inconsistent:
0x+5=3. - Quadratic two roots:
x^2-5x+6=0->2,3. - Quadratic repeated root:
x^2-4x+4=0->2. - Quadratic no real roots:
x^2+1=0. - Unsupported degree:
x^3-1=0-> exit 2. - Parse failure:
2x+=1-> exit 2.
6.3 Deterministic Test Data
precision=4
epsilon=1e-9
locale decimal separator='.'
root ordering=ascending
7) Common Pitfalls & Debugging
| Pitfall | Symptom | Debugging Approach | Fix |
|---|---|---|---|
| Incorrect sign when moving terms | Wrong solution for simple linear input | Print normalized equation before solve | Centralize move-to-left routine |
| Parsing implicit multiplication fails | 2x rejected |
Log token stream for each character | Add tokenizer rule for coefficient+variable |
Float comparison with == |
False validation failures | Print residual values | Use epsilon comparison |
| Non-deterministic root order | Flaky transcript tests | Run same case repeatedly | Sort roots before formatting |
8) Extensions & Challenges
Beginner:
- Add support for parentheses in linear equations.
- Add fraction input (
1/2x+3=4).
Intermediate:
- Add optional complex-root mode for
D < 0. - Support two-variable linear systems (
ax+by=c).
Advanced:
- Add symbolic step simplifier with fraction-preserving arithmetic.
- Add proof-style mode that annotates which algebra law each step uses.
9) Real-World Connections
- Education technology: Step-explainer engines in tutoring platforms.
- QA and finance: Constraint solvers for balancing formulas and reconciliation checks.
- Scientific computing: Equation preprocessing before numeric methods.
- Interview relevance: Tests algebra fluency, edge-case design, and deterministic system thinking.
10) Resources
- “Algebra” by I.M. Gelfand - equations and transformations.
- “Elementary Algebra” by Harold Jacobs - strong solving intuition.
- Python documentation (
argparse) - deterministic CLI interface design. - Python documentation (
math) - numeric operations and precision considerations.
11) Self-Assessment Checklist
- I can explain why each transformation preserves or changes the solution set.
- I can normalize any supported equation into canonical form.
- I can classify linear and quadratic outcomes correctly.
- I can explain and justify my epsilon tolerance choice.
- My success and failure transcripts are deterministic and reproducible.
- I can walk through one full solve by hand and match my solver output.
12) Submission/Completion Criteria
Minimum completion:
- Linear and quadratic solving works for provided valid fixtures.
- Parser errors and unsupported degree errors are handled with exit code 2.
- One golden deterministic transcript is documented.
Full completion:
- All listed critical test cases pass.
- Output formatting is stable across repeated runs.
- Residual check is included for every reported solution.
Excellence:
- Includes complex-root extension or fraction-preserving mode.
- Includes concise design notes explaining trade-offs and rejected alternatives.