Project 2: The Visual Graphing Calculator

Build a deterministic graphing calculator that evaluates a function over a window and reports graph features (roots, intercepts, turning points, domain issues).

Quick Reference

Attribute Value
Difficulty Beginner (Level 1)
Time Estimate 8-12 hours
Main Programming Language Python
Alternative Programming Languages JavaScript, C++
Key Topics Functions, coordinate systems, sampling, numeric feature detection
Input Mode CLI function string + graph window flags
Output Mode Feature report + deterministic transcript + optional saved plot artifact
Deterministic Requirements Fixed x-grid, fixed rounding, stable detection rules

1) Learning Objectives

By the end of this project, you should be able to:

  1. Represent a mathematical function as a safe, evaluable expression over a numeric domain.
  2. Choose sampling strategies that balance graph quality and computational cost.
  3. Detect and report graph features using deterministic numerical rules.
  4. Handle domain errors and discontinuities without crashing.
  5. Communicate graph behavior through precise textual summaries, not only visuals.
  6. Build reproducible output suitable for testing and grading.

2) All Theory Needed (Per-Concept Breakdown)

Concept A: Functions as Input-Output Systems

Fundamentals

A function maps each valid input to exactly one output. In graphing, you are approximating this mapping over a selected x-window. The quality of your understanding depends on domain awareness: a function like 1/(x-2) is undefined at x=2, while sqrt(x) is undefined for negative x in real arithmetic. A graphing calculator is fundamentally a domain-aware evaluator plus a visual summarizer.

Definitions and key terms

  • Domain: Set of x-values where the function is defined.
  • Range: Set of produced y-values.
  • Intercept: Point where graph crosses an axis.
  • Continuity: Behavior without jumps, holes, or asymptotes in a neighborhood.

Mental model diagram (ASCII)

x-values in window --> f(x) evaluator --> y-values
       |                  |
       |                  +--> may fail (domain error)
       v
feature detector (roots, extrema, discontinuities)

How it works (with failure modes)

  1. Select window [x_min, x_max].
  2. Generate deterministic x-samples.
  3. Evaluate f(x) for each sample.
  4. Mark undefined/non-finite values.
  5. Run feature detection on valid segments.

Failure modes:

  • Treating undefined points as zero.
  • Ignoring domain failures and producing fake continuity.
  • Mixing degrees and radians when trigonometric functions are allowed.

Minimal concrete example (pseudocode)

for x in linspace(-5, 5, 21):
  y = safe_eval(f, x)
  if y is invalid:
     record domain break

Common misconceptions

  • A plotted curve is not exact math; it is sampled approximation.
  • “No root found” can mean “not detected in this window/step size,” not always “no root exists.”

Concept B: Sampling and Numerical Approximation

Fundamentals

A computer graph is a finite sampling of a continuous object. If spacing is too coarse, roots or turning points can be missed. If spacing is too fine, performance and noise issues increase. A deterministic graphing tool should define explicit sampling policy: number of points, spacing strategy, and behavior around invalid values.

Definitions and key terms

  • Sampling grid: Ordered set of x-values used for evaluation.
  • Resolution: Density of samples across the x-window.
  • Aliasing: Misleading shape caused by insufficient sampling.
  • Interpolation: Estimating values between sampled points.

Mental model diagram (ASCII)

Continuous curve:  ~~~~~~ smooth function ~~~~~~
Sampled points:    .   .   .   .   .   .   .
Resolution high -> better shape, higher compute
Resolution low  -> faster, risk missing features

How it works

  1. Decide fixed sample count N (for deterministic output).
  2. Compute dx = (x_max - x_min)/(N-1).
  3. Evaluate points in ascending x.
  4. Use adjacent-point analysis for roots/extrema hints.

Failure modes:

  • Off-by-one in N causing wrong endpoint inclusion.
  • Inconsistent N default leading to non-reproducible results.
  • Ignoring NaN/infinity values inside detector loops.

Minimal concrete example (pseudocode)

N = 101
dx = (x_max - x_min)/(N-1)
for i from 0 to N-1:
  x_i = x_min + i*dx

Common misconceptions

  • More points always means better graph. Not true if domain handling is wrong.
  • Interpolation can estimate a root, but it is still an approximation.

Concept C: Feature Detection (Roots, Intercepts, Turning Points)

Fundamentals

Feature detection turns a plot into interpretation. Roots are x-values where f(x)=0; numerically, detect sign changes across adjacent samples. Y-intercept is f(0) if 0 is in domain. Turning points can be approximated by detecting sign changes in discrete slope (delta y / delta x). For beginner scope, deterministic heuristics are better than unstable over-optimization.

Definitions and key terms

  • Root (x-intercept): x where y is zero.
  • Y-intercept: value at x=0.
  • Turning point: local minimum or maximum where slope sign changes.
  • Discrete slope: finite-difference approximation of derivative.

Mental model diagram (ASCII)

x_i ----- x_{i+1}
 y_i       y_{i+1}

if y_i * y_{i+1} < 0  -> root in interval (sign change)
if slope changes + to - -> local max
if slope changes - to + -> local min

How it works

  1. Root detection: scan adjacent valid points for sign change.
  2. Root estimate: linear interpolation between two points.
  3. Y-intercept: evaluate at x=0 if in window and domain-valid.
  4. Turning points: compute discrete slopes; detect sign changes.
  5. Deduplicate nearby detections by tolerance.

Failure modes:

  • False roots near vertical asymptotes.
  • Duplicate extrema due to noisy discrete slopes.
  • Missing root when sample lands exactly on discontinuity and neighbor invalid.

Minimal concrete example (pseudocode)

if y_i * y_{i+1} < 0:
  x_root ~= x_i - y_i*(x_{i+1}-x_i)/(y_{i+1}-y_i)

Common misconceptions

  • Sign change detection proves odd-number root crossings in interval, not exact root count.
  • A turning point in sampled data is approximate unless solved analytically.

Concept D: Windowing and Visual Interpretation

Fundamentals

Graph interpretation depends on window choice. A parabola can look flat or steep depending on scale. A periodic function may appear constant if window is tiny. Your tool should force users to think about x-range and y-range while still offering reasonable defaults.

Definitions and key terms

  • Window: Displayed coordinate bounds.
  • Autoscaling: Deriving y-limits from sampled values.
  • Clipping: Hiding values outside display range.
  • Aspect ratio: Relative scaling of x and y axes.

Mental model diagram (ASCII)

Window A: x in [-2,2], y in [-5,5]   -> detailed local shape
Window B: x in [-100,100], y in [-5,5] -> compressed appearance

How it works

  1. Parse user-specified x-window.
  2. Sample values and compute min/max valid y.
  3. Set y-window policy (auto or fixed).
  4. Annotate detected features inside visible bounds.

Failure modes:

  • Autoscale dominated by outlier spikes near asymptotes.
  • Feature detector reporting points outside visible window.

Minimal concrete example (pseudocode)

if y_scale_mode == auto:
  y_min = percentile(valid_y, 5)
  y_max = percentile(valid_y, 95)

Common misconceptions

  • “Wrong graph” complaints are often window-selection issues, not formula issues.
  • Visual smoothness is not proof of mathematical correctness.

3) Project Specification

3.1 Functional Requirements

  1. Accept function string and x-window via CLI.
  2. Evaluate function safely on deterministic sample grid.
  3. Detect and report:
    • Approximate x-intercepts.
    • Y-intercept (if defined).
    • Approximate local minima/maxima.
    • Domain breaks/discontinuities.
  4. Output summary report in stable format.
  5. Optionally save a plot artifact path in output summary.
  6. Return explicit exit codes.

3.2 Non-Functional Requirements

  • Performance: 1,000 samples should process under 300 ms on typical laptop.
  • Reliability: Domain errors and parse errors produce clear diagnostics, not crashes.
  • Security: Evaluation must be restricted to approved math operators/functions.
  • Determinism: Same flags must produce identical report ordering and rounding.

3.3 Example I/O Contract

Input:

--function "x^2-4"
--x-min -5
--x-max 5
--samples 41
--precision 4

Output (success):

STATUS: OK
WINDOW: x=[-5.0000, 5.0000], samples=41
FUNCTION: x^2-4
X_INTERCEPTS: [-2.0000, 2.0000]
Y_INTERCEPT: -4.0000
LOCAL_MIN: (0.0000, -4.0000)
LOCAL_MAX: none
DOMAIN_BREAKS: none
EXIT_CODE: 0

Output (failure):

STATUS: ERROR
ERROR_CODE: DOMAIN_ERROR
MESSAGE: Function undefined at one or more sampled points.
EXIT_CODE: 2

3.4 Edge Cases and Expected Behavior

  1. 1/(x-2) across [0,4] -> domain break near x=2.
  2. sqrt(x) across [-5,5] -> invalid samples for negative x.
  3. Very small sample count (N=5) -> warning about low-resolution features.
  4. Constant function (f(x)=3) -> no roots, no turning points.
  5. Multiple nearby roots -> deduplication tolerance needed.
  6. Unsupported tokens (import, custom names) -> parse/security error.

3.5 Real World Outcome (Deterministic Transcript)

How to run

$ python3 p02_graphing_calculator.py --function "x^2-4" --x-min -5 --x-max 5 --samples 41 --precision 4

Golden path transcript (success)

$ python3 p02_graphing_calculator.py --function "x^2-4" --x-min -5 --x-max 5 --samples 41 --precision 4
STATUS: OK
WINDOW: x=[-5.0000, 5.0000], samples=41
FUNCTION: x^2-4
X_INTERCEPTS: [-2.0000, 2.0000]
Y_INTERCEPT: -4.0000
LOCAL_MIN: (0.0000, -4.0000)
LOCAL_MAX: none
DOMAIN_BREAKS: none
PLOT_ARTIFACT: ./artifacts/p02_x2_minus_4.png
EXIT_CODE: 0

Failure transcript

$ python3 p02_graphing_calculator.py --function "1/(x-2)" --x-min 0 --x-max 4 --samples 41
STATUS: ERROR
ERROR_CODE: DOMAIN_ERROR
MESSAGE: Function undefined near x=2.0000 within sampled window.
EXIT_CODE: 2

4) Solution Architecture

4.1 High-Level ASCII Diagram

CLI Flags
   |
   v
+----------------------+
| Input Validator      |
+----------------------+
   |
   v
+----------------------+      +----------------------+
| Safe Expression      | ---> | Sampling Engine      |
| Parser/Evaluator     |      +----------------------+
+----------------------+                 |
                                         v
                              +----------------------+
                              | Feature Detector     |
                              | roots/extrema/domain |
                              +----------------------+
                                         |
                                         v
                              +----------------------+
                              | Reporter + Plot Sink |
                              +----------------------+

4.2 Key Components

Component Responsibility Notes
CLI Validator Parse and validate numeric bounds and flags Reject invalid window early
Safe Evaluator Parse approved math expression grammar Block unsafe eval paths
Sampler Generate deterministic x-grid and y-values Tracks invalid points
Feature Detector Estimate roots, intercepts, extrema Uses fixed tolerances
Reporter Stable textual output + exit code Order fields deterministically
Plot Adapter Optional graph artifact generation Keep independent of core math logic

4.3 Algorithm Overview

Conceptual pseudocode:

validate_inputs()
expr = parse_function_string()
grid = build_uniform_grid(x_min, x_max, N)
points = evaluate(expr, grid)  # includes invalid markers
features = detect_features(points)
render_report(features, deterministic_format)

Complexity:

  • Time: O(N) for sampling and single-pass detectors
  • Space: O(N) for point storage

5) Implementation Guide

5.1 Setup

$ cd project_based_ideas/MATH/LEARN_HIGH_SCHOOL_MATH_WITH_PYTHON
$ python3 --version
Python 3.10+ required
$ mkdir -p p02_graphing_calculator/{artifacts,tests,fixtures}

5.2 Suggested Project Structure

p02_graphing_calculator/
  artifacts/
  fixtures/
    golden_cases.txt
    domain_error_cases.txt
  tests/
    sampling_cases.md
    feature_cases.md
  README.md

5.3 Core Question

“How do I turn a symbolic formula into a faithful, testable picture of behavior instead of a deceptive curve?”

5.4 Prerequisites You Should Be Comfortable With

  1. Function notation and domain/range concepts.
  2. Cartesian coordinates and intercept interpretation.
  3. Basic numerical approximation (finite differences, interpolation).
  4. CLI parameter parsing and validation.

5.5 Design Questions

  1. What expression grammar is allowed in beginner scope?
  2. How will you keep evaluator safe while still useful?
  3. What tolerance should define duplicate roots or extrema?
  4. How do you represent discontinuities in both text and plot output?
  5. What defaults for window and samples are informative but fast?

5.6 Thinking Exercise (Before Implementation)

Predict behavior by hand for these in window [-5,5]:

  • x^2-4
  • 1/(x-2)
  • abs(x)-2

Questions:

  1. Which features are exact vs approximate from sampling?
  2. Where can sign-change root detection fail?
  3. How would window changes alter what the user concludes?

5.7 Interview Questions

  1. Why can sampled graphs miss important behavior?
  2. How would you detect roots without symbolic solving?
  3. What makes function evaluation “safe” in a user-facing tool?
  4. How would you identify a discontinuity numerically?
  5. What trade-offs exist between sample density and performance?

5.8 Hints in Layers

  • Hint 1: Build evaluator and print a table of (x, y) before any plotting.
  • Hint 2: Implement sign-change root detection first.
  • Hint 3: Add discrete-slope turning-point detection with deduplication.
  • Hint 4: Add domain-break tracking and deterministic output formatting.

5.9 Implementation Phases

Phase 1 (2-3 hours): Input validation + safe expression evaluation.

Phase 2 (2-3 hours): Deterministic sampling and point table generation.

Phase 3 (2-3 hours): Feature detection and reporting.

Phase 4 (1-3 hours): Plot artifact integration and edge-case hardening.

5.10 Key Implementation Decisions

Decision Options Recommended Choice Rationale
Sampling strategy adaptive, uniform uniform grid Simpler and deterministic
Root detection symbolic solve, sign-change numeric sign-change numeric Works for broader function classes
Evaluator safety native eval, restricted parser restricted parser Avoids code execution risks
Turning points derivative symbolic, finite difference finite difference Beginner-friendly and consistent

6) Testing Strategy

6.1 Test Categories

Category Purpose Sample
Unit Validate parser, grid builder, detectors Grid endpoints and spacing checks
Integration End-to-end function report Full CLI invocation snapshots
Edge Domain breaks and low sample artifacts 1/(x-2), sqrt(x) with negative inputs
Regression Prevent output formatting drift Golden transcript compare

6.2 Critical Test Cases

  1. x^2-4 in [-5,5] with N=41 -> roots near -2, 2; min at (0,-4).
  2. x^3 in [-2,2] -> root at 0; inflection-like behavior, no local max/min.
  3. 1/(x-2) in [0,4] -> domain break reported.
  4. sqrt(x) in [-5,5] -> domain errors for negative x.
  5. Constant function 3 -> empty root and extrema lists.

6.3 Deterministic Test Data

precision=4
samples fixed per case
root dedupe tolerance=1e-3
extrema dedupe tolerance=1e-3
report field order fixed

7) Common Pitfalls & Debugging

Pitfall Symptom Debugging Approach Fix
Unsafe expression execution Unexpected runtime/security issues Log parsed tokens and allowed symbols Use strict whitelist parser
Coarse sampling misses roots Known root not reported Print sampled sign table around expected region Increase sample density or adaptive refinement
False extrema from noisy slopes Many tiny max/min detections Plot slope sign sequence Add smoothing or tolerance filters
Discontinuity mistaken as root Root reported near asymptote Inspect neighbor validity and magnitude jump Reject sign-change pairs across invalid gap

8) Extensions & Challenges

Beginner:

  • Add support for piecewise functions.
  • Add ASCII-only plotting mode for terminal output.

Intermediate:

  • Add zoom and pan commands with session state.
  • Add tangent-line estimate at chosen x.

Advanced:

  • Add adaptive sampling that refines near high curvature.
  • Add parametric and polar plotting modes.

9) Real-World Connections

  • STEM education tools: Interactive graphing experiences in classrooms.
  • Data science dashboards: Trend and anomaly visualization pipelines.
  • Engineering UX: Quick equation checks in CAD/simulation pre-tools.
  • Interview relevance: Demonstrates numeric reasoning, robustness, and data visualization foundations.

10) Resources

  • “Precalculus” by James Stewart - functions, transformations, and graph interpretation.
  • “Numerical Analysis” by Burden and Faires - interpolation and approximation ideas.
  • Python documentation (math) - standard real-valued math functions.
  • Matplotlib documentation - plotting fundamentals and annotations.

11) Self-Assessment Checklist

  • I can explain why sampling density affects feature detection quality.
  • I can distinguish domain errors from numerical detector mistakes.
  • I can justify each detection heuristic and tolerance.
  • My output is deterministic for fixed inputs.
  • I can explain at least one case where graph window changes the interpretation.
  • I can manually verify one full report from first principles.

12) Submission/Completion Criteria

Minimum completion:

  • Function evaluation works on approved grammar and valid window.
  • Root/intercept reporting works for basic polynomial cases.
  • Domain failures return clear error and exit code 2.

Full completion:

  • Turning-point detection and discontinuity reporting are implemented.
  • Golden success transcript and one failure transcript are reproducible.
  • Critical test matrix passes.

Excellence:

  • Includes adaptive sampling extension or tangent-line analysis.
  • Includes short design note comparing alternative detection strategies.