Capstone Project 2

Calculator Application

Build a powerful scientific calculator application in C++ featuring expression parsing, operator precedence, memory functions, trigonometric operations, and calculation history. Apply OOP principles to create a robust, extensible calculator with both console and GUI interfaces.

8-12 hours
Intermediate
400 Points
What You Will Build
  • Expression parser with precedence
  • Scientific math operations
  • Memory functions (M+, M-, MR, MC)
  • Calculation history system
  • Unit conversion features
Contents
01

Project Overview

This capstone project challenges you to build a fully-functional scientific calculator using C++. You will work with the Kaggle Mathematical Expression Dataset containing 500 test expressions covering basic arithmetic, algebraic operations, trigonometric functions, logarithms, and complex nested expressions with varying operator precedence. The dataset includes expressions with expected results for validation, edge cases for error handling, and performance benchmarks. Your calculator must parse and evaluate these expressions correctly, demonstrating mastery of C++ fundamentals including OOP, data structures (stacks, queues), operator overloading, and exception handling.

Skills Applied: This project tests your proficiency in C++ (classes, inheritance, polymorphism), data structures (stacks for expression evaluation), algorithms (Shunting-yard, recursive descent parsing), and software design patterns (command pattern for history, strategy for operations).
Expression Parser

Parse mathematical expressions with operator precedence

Scientific Ops

Trigonometry, logarithms, powers, and roots

Memory System

Store, recall, add, and clear memory values

History

Track calculations with undo/redo support

Learning Objectives

Technical Skills
  • Implement expression parsing with stacks
  • Apply operator overloading for custom types
  • Use inheritance and polymorphism for operations
  • Handle exceptions for mathematical errors
  • Implement the command pattern for history
Software Design Skills
  • Design modular, extensible architecture
  • Separate concerns (parsing, evaluation, UI)
  • Write comprehensive unit tests
  • Document code with clear comments
  • Apply SOLID principles in class design
Ready to submit? Already completed the project? Submit your work now!
Submit Now
02

Project Scenario

TechCalc Software Inc.

You have been hired as a Software Developer at TechCalc Software, a company specializing in educational and scientific software tools. The company wants to create a flagship calculator application that can be used by students, engineers, and scientists. The calculator must handle complex mathematical expressions and provide a robust, user-friendly experience.

"We need a calculator that goes beyond basic arithmetic. It should handle complex expressions like 'sin(45) + 2^3 * (5 - 2)' correctly, remember previous calculations, and provide helpful error messages. Can you build something that both students and professionals would love to use?"

Dr. Sarah Chen, Chief Product Officer

Functional Requirements

Basic Operations
  • Addition, subtraction, multiplication, division
  • Proper operator precedence (PEMDAS/BODMAS)
  • Parentheses support for grouping
  • Negative numbers and decimal handling
Scientific Functions
  • Trigonometric: sin, cos, tan, asin, acos, atan
  • Logarithmic: log (base 10), ln (natural log)
  • Exponential: power (^), square root (sqrt)
  • Constants: π (pi), e (Euler's number)
Memory Functions
  • MC (Memory Clear) - Clear stored value
  • MR (Memory Recall) - Retrieve stored value
  • M+ (Memory Add) - Add to stored value
  • M- (Memory Subtract) - Subtract from stored
Additional Features
  • Calculation history with scroll/navigation
  • Undo last operation functionality
  • Expression validation and error messages
  • Unit conversions (degrees/radians)
Pro Tip: Start with basic arithmetic and expression parsing. Once that works correctly, add scientific functions incrementally. Test each feature thoroughly before moving on!
03

Test Cases Dataset

Use the comprehensive test case dataset to validate your calculator implementation. The CSV file contains expressions with expected results for automated testing:

Dataset Download

Download the test cases dataset and sample mathematical constants file. Use these to validate your calculator's accuracy and handle edge cases.

Original Data Source

This project uses test cases inspired by the Mathematical Expression Evaluation Dataset from Kaggle - containing diverse mathematical expressions for testing calculator implementations. The dataset covers 500 expressions across 6 difficulty levels with expected outputs.

Dataset Info: 500 rows × 5 columns | Categories: Basic (100), Intermediate (100), Advanced (100), Scientific (100), Edge Cases (100) | Includes: expression, expected_result, category, difficulty, description
Dataset Schema

ColumnTypeDescription
test_idIntegerUnique test case identifier (1-500)
expressionStringMathematical expression to evaluate
expected_resultFloatExpected output (or "ERROR" for invalid)
categoryStringbasic, intermediate, advanced, scientific, edge_case
difficultyIntegerDifficulty level (1-5)
descriptionStringDescription of what the test validates

ColumnTypeDescription
constant_nameStringName of constant (pi, e, phi, etc.)
symbolStringSymbol used in expressions (π, e, φ)
valueFloatNumeric value (high precision)
descriptionStringMathematical definition

ColumnTypeDescription
from_unitStringSource unit (degrees, radians, etc.)
to_unitStringTarget unit
conversion_factorFloatMultiplication factor
categoryStringangle, length, temperature, etc.
Sample Test Cases Preview

Here are sample test cases from the dataset showing different difficulty levels:

IDExpressionExpectedCategoryDifficulty
12 + 35basic1
453 + 4 * 211intermediate2
150(5 + 3) * 2 - 4 / 214advanced3
320sin(30) + cos(60)1.0scientific4
4501 / 0ERRORedge_case5
Testing Note: Your calculator should pass at least 90% of the basic and intermediate test cases. Scientific and edge case handling is required for full marks.
04

Project Requirements

Your project must include all of the following components. Structure your code with clear separation of concerns and comprehensive documentation.

1
Expression Parser

Parsing Requirements:

  • Tokenize input expressions into operators, numbers, and functions
  • Implement Shunting-yard algorithm OR recursive descent parser
  • Handle operator precedence: () > ^ > * / > + -
  • Support both infix notation and function calls
class ExpressionParser {
    std::vector<Token> tokenize(const std::string& expr);
    double evaluate(const std::string& expr);
    bool validate(const std::string& expr);
    
private:
    std::stack<double> values;
    std::stack<char> operators;
    int getPrecedence(char op);
    double applyOp(double a, double b, char op);
};
Deliverable: Parser class with tokenization, validation, and evaluation methods.
2
Mathematical Operations

Operation Classes:

  • Create an abstract Operation base class
  • Implement concrete classes for each operation type
  • Use polymorphism to handle different operations uniformly
  • Support extensibility for adding new operations

Required Operations:

  • Arithmetic: +, -, *, /, % (modulo), ^ (power)
  • Trigonometric: sin, cos, tan, asin, acos, atan
  • Logarithmic: log, ln, log2
  • Other: sqrt, abs, floor, ceil, round
Deliverable: Operation class hierarchy with polymorphic evaluation.
3
Memory System

Memory Functions:

  • MC - Memory Clear: Reset memory to 0
  • MR - Memory Recall: Return stored value
  • M+ - Memory Add: Add current result to memory
  • M- - Memory Subtract: Subtract from memory
  • MS - Memory Store: Store current result
class MemoryManager {
    double memory = 0.0;
public:
    void clear() { memory = 0.0; }
    double recall() const { return memory; }
    void add(double value) { memory += value; }
    void subtract(double value) { memory -= value; }
    void store(double value) { memory = value; }
};
Deliverable: Memory manager class with all standard calculator memory functions.
4
History System

History Features:

  • Store all calculations with expression and result
  • Navigate through history (up/down arrows)
  • Reuse previous expressions
  • Implement undo functionality
  • Persist history to file (optional)
struct HistoryEntry {
    std::string expression;
    double result;
    std::chrono::time_point<std::chrono::system_clock> timestamp;
};

class HistoryManager {
    std::vector<HistoryEntry> history;
    int currentIndex = -1;
public:
    void add(const std::string& expr, double result);
    HistoryEntry* getPrevious();
    HistoryEntry* getNext();
    void clear();
    void saveToFile(const std::string& filename);
};
Deliverable: History manager with navigation, storage, and persistence.
5
User Interface

Console Interface:

  • Clear, intuitive command prompt
  • Help command showing available operations
  • Error messages with helpful suggestions
  • Mode switching (degrees/radians)

Display Requirements:

  • Show current memory status
  • Display calculation history
  • Format numbers appropriately (precision)
  • Color coding for errors (optional)
Deliverable: Clean console interface with all required user interactions.
05

Feature Specifications

Implement all of the following features. Each feature should be well-tested and handle edge cases appropriately.

Basic Operations
OperatorExampleResult
Addition (+)5 + 38
Subtraction (-)10 - 46
Multiplication (*)6 * 742
Division (/)15 / 35
Modulo (%)17 % 52
Power (^)2 ^ 8256
Scientific Functions
FunctionExampleResult
sin(x)sin(30)0.5
cos(x)cos(60)0.5
tan(x)tan(45)1.0
sqrt(x)sqrt(144)12
log(x)log(100)2
ln(x)ln(e)1
Error Handling
  • Division by zero: Return clear error message
  • Invalid syntax: Identify position of error
  • Mismatched parentheses: Indicate which is missing
  • Unknown function: Suggest similar functions
  • Domain errors: sqrt(-1), log(-5), etc.
  • Overflow/Underflow: Handle large/small numbers
Advanced Features
  • Constants: pi (π), e, phi (φ)
  • Ans: Use previous result in expression
  • Variables: Store named values (bonus)
  • Degree/Radian mode: Toggle for trig functions
  • Precision control: Set decimal places
  • Expression history: Arrow key navigation
Sample Implementation
// Operator precedence handling
int getPrecedence(char op) {
    switch(op) {
        case '+': case '-': return 1;
        case '*': case '/': case '%': return 2;
        case '^': return 3;
        default: return 0;
    }
}

// Right associativity for power operator
bool isRightAssociative(char op) {
    return op == '^';
}
// Scientific function evaluation
double evalFunction(const std::string& func, double arg) {
    if (func == "sin") return std::sin(toRadians(arg));
    if (func == "cos") return std::cos(toRadians(arg));
    if (func == "tan") return std::tan(toRadians(arg));
    if (func == "sqrt") return std::sqrt(arg);
    if (func == "log") return std::log10(arg);
    if (func == "ln") return std::log(arg);
    throw std::runtime_error("Unknown function: " + func);
}
Best Practice: Use the Strategy pattern for operations - this makes it easy to add new operations without modifying existing code.
06

Recommended Code Structure

Organize your code following this modular structure. Each class should have a single responsibility and be well-documented.

calculator-app/
├── include/
│   ├── Calculator.h         # Main calculator class
│   ├── Parser.h             # Expression tokenizer and parser
│   ├── Evaluator.h          # Expression evaluator
│   ├── Operations.h         # Operation base class and implementations
│   ├── MemoryManager.h      # Memory functions (MC, MR, M+, M-)
│   ├── HistoryManager.h     # Calculation history
│   ├── Token.h              # Token structure for parsing
│   └── Exceptions.h         # Custom exception classes
├── src/
│   ├── main.cpp             # Entry point and UI loop
│   ├── Calculator.cpp       # Calculator implementation
│   ├── Parser.cpp           # Parser implementation
│   ├── Evaluator.cpp        # Evaluator implementation
│   ├── Operations.cpp       # Operation implementations
│   ├── MemoryManager.cpp    # Memory implementation
│   └── HistoryManager.cpp   # History implementation
├── tests/
│   ├── test_parser.cpp      # Parser unit tests
│   ├── test_evaluator.cpp   # Evaluator unit tests
│   ├── test_operations.cpp  # Operation unit tests
│   └── test_integration.cpp # Integration tests with CSV data
├── data/
│   └── test_cases.csv       # Test cases from dataset
├── Makefile                 # Build configuration
└── README.md                # Project documentation
Class Diagram
Calculator

Main controller class

Parser

Tokenize & parse

Evaluator

Compute results

Memory

Store values

History

Track calculations

07

Submission Requirements

Create a public GitHub repository with the exact name shown below:

Required Repository Name
cpp-calculator-app
github.com/<your-username>/cpp-calculator-app
Required Project Structure
cpp-calculator-app/
├── include/                    # Header files
│   ├── Calculator.h
│   ├── Parser.h
│   ├── Evaluator.h
│   ├── Operations.h
│   ├── MemoryManager.h
│   └── HistoryManager.h
├── src/                        # Source files
│   ├── main.cpp
│   ├── Calculator.cpp
│   ├── Parser.cpp
│   └── ... (other implementations)
├── tests/                      # Unit tests
│   └── test_*.cpp
├── data/                       # Test data files
│   └── test_cases.csv
├── screenshots/                # Application screenshots
│   ├── basic_operations.png
│   ├── scientific_functions.png
│   └── error_handling.png
├── Makefile                    # Build configuration
└── README.md                   # Project documentation
README.md Required Sections
1. Project Header
  • Project title and description
  • Your full name and submission date
  • Course and project number
2. Features
  • List of all supported operations
  • Scientific functions available
  • Memory and history features
3. Building & Running
  • Compilation instructions
  • Required dependencies
  • How to run the application
4. Usage Examples
  • Sample expressions and outputs
  • Screenshots of the application
  • Command reference
5. Architecture
  • Class diagram or description
  • Design patterns used
  • Key algorithms explained
6. Testing
  • How to run tests
  • Test coverage summary
  • Edge cases handled
Do Include
  • All source and header files
  • Makefile or CMakeLists.txt
  • Unit tests for core functionality
  • Test data CSV file
  • Screenshots of working application
  • Clear code comments and documentation
Do Not Include
  • Compiled binaries or object files
  • IDE-specific project files
  • External library source code
  • Temporary or backup files
  • Personal information in code
Important: Before submitting, compile your code on a clean system to ensure all dependencies are documented and the build works correctly.
Submit Your Project

Enter your GitHub username - we will verify your repository automatically

08

Grading Rubric

Your project will be graded on the following criteria. Total: 400 points.

Criteria Points Description
Expression Parser 80 Correct tokenization, operator precedence, parentheses handling
Basic Operations 60 All arithmetic operations work correctly with proper precision
Scientific Functions 60 Trig, log, power, sqrt functions with degree/radian modes
Memory System 40 MC, MR, M+, M-, MS all work correctly
History System 40 Storage, navigation, undo functionality
Error Handling 40 Graceful handling of all edge cases with clear messages
Code Quality 40 Clean code, OOP principles, documentation, tests
Documentation 40 README quality, code comments, screenshots
Total 400
Grading Levels
Excellent
360-400

All features work perfectly with bonus features

Good
300-359

All required features work correctly

Satisfactory
240-299

Core features work with minor issues

Needs Work
< 240

Missing key features or major bugs

Ready to Submit?

Make sure you have completed all requirements and reviewed the grading rubric above.

Submit Your Project
09

Pre-Submission Checklist

Use this checklist to verify you have completed all requirements before submitting your project.

Parser Requirements
Scientific Functions
Memory & History
Repository Requirements
Final Check: Run the provided test cases CSV through your calculator and verify at least 90% pass rate on basic and intermediate expressions.