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