C#C# · Lesson 8 of 9

Mini Project: Simple Calculator

A console calculator that evaluates expressions and tracks history, using everything we've covered.

C#
using System.Text.RegularExpressions;

class Calculator {
    private readonly List<string> history = new();

    public double Evaluate(string expression) {
        // Match: number operator number (simple two-operand expressions)
        var match = Regex.Match(expression.Trim(),
            @"^(-?d+.?d*)s*([+-*/^%])s*(-?d+.?d*)$");

        if (!match.Success)
            throw new FormatException($"Invalid expression: '{expression}'");

        double a = double.Parse(match.Groups[1].Value);
        char op = match.Groups[2].Value[0];
        double b = double.Parse(match.Groups[3].Value);

        double result = op switch {
            '+' => a + b,
            '-' => a - b,
            '*' => a * b,
            '/' => b == 0 ? throw new DivideByZeroException() : a / b,
            '%' => a % b,
            '^' => Math.Pow(a, b),
            _ => throw new InvalidOperationException($"Unknown operator: {op}")
        };

        string entry = $"{expression} = {result}";
        history.Add(entry);
        return result;
    }

    public void PrintHistory() {
        if (history.Count == 0) { Console.WriteLine("No history."); return; }
        Console.WriteLine("
=== Calculation History ===");
        foreach (var (item, i) in history.Select((x, i) => (x, i + 1))) {
            Console.WriteLine($"  {i}. {item}");
        }
    }
}

var calc = new Calculator();
Console.WriteLine("Calculator — type expressions like '10 + 5', or 'history', or 'quit'");

while (true) {
    Console.Write("> ");
    string? input = Console.ReadLine()?.Trim();
    if (string.IsNullOrEmpty(input)) continue;
    if (input == "quit" || input == "exit") break;
    if (input == "history") { calc.PrintHistory(); continue; }

    try {
        double result = calc.Evaluate(input);
        Console.WriteLine($"= {result}");
    } catch (Exception ex) {
        Console.WriteLine($"Error: {ex.Message}");
    }
}
Bash
dotnet run

# Then type expressions:
# 10 + 5
# 2 ^ 10
# 100 / 4
# history
# quit