Project Goal
Build a personal expense tracker that categorizes spending, tracks balances, and generates monthly summaries. Covers enums, sorting, groupBy, date handling, and formatting.
Full Code
import 'dart:io';
enum Category { food, transport, utilities, entertainment, health, other }
class Expense {
final int id;
final String description;
final double amount;
final Category category;
final DateTime date;
Expense({required this.id, required this.description, required this.amount,
required this.category, DateTime? date})
: date = date ?? DateTime.now();
@override String toString() {
var d = '$${date.year}-$${date.month.toString().padLeft(2,'0')}-$${date.day.toString().padLeft(2,'0')}';
return '[$d] $${category.name.toUpperCase().padRight(13)} \$$${amount.toStringAsFixed(2).padLeft(8)} - $description';
}
}
class ExpenseTracker {
final List<Expense> _expenses = [];
int _nextId = 1;
void add(String desc, double amount, Category cat, {DateTime? date}) {
_expenses.add(Expense(id: _nextId++, description: desc, amount: amount, category: cat, date: date));
}
double get total => _expenses.fold(0, (s, e) => s + e.amount);
Map<Category, double> get byCategory {
var result = <Category, double>{};
for (var e in _expenses) {
result[e.category] = (result[e.category] ?? 0) + e.amount;
}
return result;
}
List<Expense> forMonth(int year, int month) =>
_expenses.where((e) => e.date.year == year && e.date.month == month).toList();
void monthlyReport(int year, int month) {
var expenses = forMonth(year, month);
if (expenses.isEmpty) { print('No expenses for $year-$month'); return; }
var monthTotal = expenses.fold(0.0, (s, e) => s + e.amount);
print('\n===== $year-$${month.toString().padLeft(2,'0')} EXPENSE REPORT =====');
expenses.forEach(print);
print('\n--- By Category ---');
var cats = <Category, double>{};
for (var e in expenses) cats[e.category] = (cats[e.category] ?? 0) + e.amount;
cats.entries.toList()
..sort((a, b) => b.value.compareTo(a.value))
..forEach((e) => print('$${e.key.name.padRight(15)} \$$${e.value.toStringAsFixed(2)}'));
print('\nTotal: \$$${monthTotal.toStringAsFixed(2)}');
}
}
void main() {
var tracker = ExpenseTracker();
var now = DateTime.now();
var m = now.month;
var y = now.year;
tracker.add('Grocery shopping', 45.50, Category.food, date: DateTime(y, m, 1));
tracker.add('Bus pass', 30.00, Category.transport, date: DateTime(y, m, 2));
tracker.add('Netflix', 15.99, Category.entertainment, date: DateTime(y, m, 3));
tracker.add('Electricity bill', 80.00, Category.utilities, date: DateTime(y, m, 4));
tracker.add('Doctor visit', 120.00, Category.health, date: DateTime(y, m, 5));
tracker.add('Restaurant lunch', 22.75, Category.food, date: DateTime(y, m, 6));
tracker.add('Movie tickets', 18.00, Category.entertainment, date: DateTime(y, m, 7));
tracker.add('Grab ride', 12.50, Category.transport, date: DateTime(y, m, 8));
tracker.monthlyReport(y, m);
print('\nAll-time total: \$$${tracker.total.toStringAsFixed(2)}');
}
Challenges
- Add a budget per category and warn when exceeded
- Add recurring expenses (subscriptions)
- Export monthly report to CSV
- Build a Flutter app with pie charts by category