Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Seaus-tech/Calculator-App/llms.txt

Use this file to discover all available pages before exploring further.

Calculator App is a pure-Python, zero-dependency project, which makes it easy to clone, modify, and test locally. This guide walks through the development setup, the project structure, and the concrete patterns used to extend each layer of the application.
The project is hosted on GitHub at https://github.com/Seaus-tech/Calculator-App. Open issues and pull requests there.

Development Setup

Clone the repository and install the package in editable mode. Editable mode (-e) means changes you make to the source files are reflected immediately without reinstalling.
git clone https://github.com/Seaus-tech/Calculator-App.git
cd Calculator-App
pip install -e .
Once installed, the calc-app entry point is available on your PATH and the calc_app package is importable in any Python script. Requirements:
  • Python ≥ 3.10 (the code uses str | None union syntax in return annotations)
  • No third-party dependencies — the standard library is sufficient

Project Structure

A brief recap of each module’s responsibility. For full detail on the evaluation pipeline, REPL dispatch, and public APIs, see the Architecture page.

core.py

REPL loop and top-level command dispatch. Handles quit, meme toggle, equation detection, variable assignment, and falls back to calc().

evaluator.py

The calc(expr) function. Runs the full transformation pipeline: NL parsing → fraction rewriting → caret conversion → variable substitution → sandboxed eval().

parser.py

parse_natural_language(expr). Converts English phrases (squared, sqrt of, cubed) into valid Python math notation using re.sub.

fractions.py

parse_fractions(expr). Rewrites a/b and mixed-number whole a/b literals to Fraction(numerator, denominator) constructor calls.

solver.py

solve_equation(equation). Handles linear equations with algebraic coefficient extraction and falls back to integer brute-force search (−100,000 to 100,000) for other forms.

meme.py

handle_meme(line, meme_mode). Returns humorous responses for specific expressions when meme mode is active; returns None otherwise.

variables.py

The shared variables dict. Populated at the REPL via name=value; consumed by calc() during variable substitution.

app.py

Package entry point. Imports main from core and calls it under if __name__ == "__main__".

How to Add a New Feature

1

Identify the right module

Decide which layer owns your feature:
  • New English phrase support → parser.py (parse_natural_language)
  • New math function available in expressions → evaluator.py (safe_dict)
  • New equation-solving strategy → solver.py (solve_equation)
  • New easter egg → meme.py (handle_meme)
  • New REPL command → core.py (main)
2

Add the new logic

Make your change inside the identified module. The sections below show concrete patterns for the most common extension points. Keep changes focused — each module has a single responsibility, and cross-cutting changes are usually a sign that two separate modules should each receive a small update.
3

Add test cases in calc_tests.py

Append a (expression, expected_result) tuple to the appropriate test function’s tests list. If your feature doesn’t fit an existing category, add a new test_your_feature() function following the same pattern and call it at the bottom of if __name__ == "__main__".
def test_your_feature():
    print("\n=== Your Feature Tests ===")
    tests = [
        ("your expression", expected_value),
    ]
    for expr, expected in tests:
        result = calc(expr)
        status = "✓" if result == expected else "✗"
        print(f"{status} {expr} = {result} (expected {expected})")
4

Run the test suite

Verify that all existing tests still pass and your new cases produce :
python calc_tests.py
A clean run ends with === Test Complete === and no lines.
5

Update documentation

If your change adds a new public function, a new NL phrase, a new supported equation form, or a new REPL command, update the relevant documentation page so users and future contributors can discover it.

How to Add a New Meme Easter Egg

Open calc_app/meme.py. The handle_meme function checks the stripped input line against a series of if statements. Add a new block following the same pattern:
def handle_meme(line: str, meme_mode: bool):
    if not meme_mode:
        return None

    stripped = line.strip()

    # --- existing easter eggs ---
    if stripped == '9+10':
        return "= 21 😂"
    if stripped == '2+2':
        return "= 5 (quick maths)"
    if stripped == '1+1':
        return "= 11 (big brain)"

    # --- add your new easter egg here ---
    if stripped == 'your_expression':
        return '= your funny response'

    return None
If you want the meme to display the real result alongside the joke (like the 67 and 41 cases do), call calc() and interpolate the result:
if 'your_keyword' in stripped:
    result = calc(line)
    return f"= {result} (your funny annotation 🔥)"
Add a corresponding test in calc_tests.py by temporarily enabling meme mode in a dedicated test function, or test handle_meme() directly by passing meme_mode=True.

How to Add a New Math Function

Math functions are whitelisted in the safe_dict inside calc_app/evaluator.py. Adding a new function means importing it from math and adding an entry to the dict:
import math
from fractions import Fraction

def calc(expr: str):
    # ... pipeline stages ...

    safe_dict = {
        '__builtins__': {},
        'sqrt': math.sqrt,
        'sin':  math.sin,
        'cos':  math.cos,
        'tan':  math.tan,
        'log':  math.log,
        'pi':   math.pi,
        'e':    math.e,
        'Fraction': Fraction,
        # add your new functions below
        'floor': math.floor,
        'ceil':  math.ceil,
    }
After adding the entry, users can call floor(3.7) or ceil(3.2) directly at the REPL and in expressions — no other changes are needed.
Never add __builtins__ back to safe_dict or replace the empty-dict guard with anything else. Doing so would allow arbitrary code execution via eval(). Only add specific, trusted math module functions.

How to Add a New Natural Language Pattern

Open calc_app/parser.py. Each pattern is a re.sub call that matches an English phrase and replaces it with valid Python math syntax. Add your pattern before the return statement:
import re

def parse_natural_language(expr: str) -> str:
    expr = expr.lower()
    expr = re.sub(r'(\d+(?:\.\d+)?)\s*squared',          r'(\1)**2',    expr)
    expr = re.sub(r'(\d+(?:\.\d+)?)\s*cubed',            r'(\1)**3',    expr)
    expr = re.sub(r'sqrt\s*of\s*(\d+(?:\.\d+)?)',        r'sqrt(\1)',   expr)
    expr = re.sub(r'square\s*root\s*of\s*(\d+(?:\.\d+)?)', r'sqrt(\1)', expr)
    expr = re.sub(r'sqrt\s*(\d+(?:\.\d+)?)',             r'sqrt(\1)',   expr)

    # example: "16 to the power of 3" → "(16)**3"
    expr = re.sub(r'(\d+(?:\.\d+)?)\s*to\s*the\s*power\s*of\s*(\d+)', r'(\1)**\2', expr)

    return expr
Add a corresponding tuple to test_natural_language() in calc_tests.py:
("16 to the power of 3", 4096),

Build docs developers (and LLMs) love