// Budget Management Application CLI - Dart // Assignment 1 - Problem 2 // File: NaifAlkanhal_251000447_Budget Management Application2.txt // // How to run (after saving as .dart if needed): // dart run budget_app.dart // // Note: This submission is saved as .txt per instructions, but the content is valid Dart code. import 'dart:io'; class BudgetEntry { final String description; final double amount; BudgetEntry({required this.description, required this.amount}); } String _readLineTrimmed() { return (stdin.readLineSync() ?? '').trim(); } int _readMenuChoice({required int min, required int max}) { while (true) { stdout.write('Enter your choice: '); final input = _readLineTrimmed(); final value = int.tryParse(input); if (value != null && value >= min && value <= max) { return value; } stdout.writeln('Invalid choice. Please enter a number between $min and $max.'); } } double _readNonNegativeAmount({required String prompt}) { while (true) { stdout.write(prompt); final input = _readLineTrimmed(); final value = double.tryParse(input); // Input validation: numeric + non-negative using logical operators if (value != null && value >= 0) { return value; } stdout.writeln('Invalid amount. Please enter a valid non-negative number.'); } } void _addIncome(List incomeList) { stdout.write('Enter income description: '); final desc = _readLineTrimmed(); final amount = _readNonNegativeAmount(prompt: 'Enter income amount: '); incomeList.add(BudgetEntry(description: desc, amount: amount)); stdout.writeln('Income added!'); } void _addExpense(List expenseList) { stdout.write('Enter expense description: '); final desc = _readLineTrimmed(); final amount = _readNonNegativeAmount(prompt: 'Enter expense amount: '); expenseList.add(BudgetEntry(description: desc, amount: amount)); stdout.writeln('Expense added!'); } double _sumAmounts(List list) { double total = 0; for (final e in list) { total += e.amount; // arithmetic operation } return total; } void _viewSummary(List incomeList, List expenseList) { final totalIncome = _sumAmounts(incomeList); final totalExpenses = _sumAmounts(expenseList); final net = totalIncome - totalExpenses; stdout.writeln('\nSummary:'); stdout.writeln('Total income: \$${totalIncome.toStringAsFixed(2)}'); stdout.writeln('Total expenses: \$${totalExpenses.toStringAsFixed(2)}'); if (net >= 0) { stdout.writeln('Your net profit is \$${net.toStringAsFixed(2)}'); } else { stdout.writeln('Your net loss is \$${net.abs().toStringAsFixed(2)}'); } // Optional exercise: Tax calculation (15% of net profit), only if profitable. const double taxRate = 0.15; final double tax = (net > 0) ? (net * taxRate) : 0.0; // ternary operator if (tax > 0) { stdout.writeln('Tax to be paid (15%): \$${tax.toStringAsFixed(2)}'); } stdout.writeln(''); } void main() { // Data storage requirement: lists of entries final List incomeList = []; final List expenseList = []; stdout.writeln('Welcome to the Budget Management Application!'); bool running = true; while (running) { stdout.writeln('\nPlease choose an option:'); stdout.writeln('1. Add income'); stdout.writeln('2. Add expense'); stdout.writeln('3. View summary'); stdout.writeln('4. Exit'); final choice = _readMenuChoice(min: 1, max: 4); // Control flow requirement: if/else statements for menu options if (choice == 1) { _addIncome(incomeList); } else if (choice == 2) { _addExpense(expenseList); } else if (choice == 3) { _viewSummary(incomeList, expenseList); } else { stdout.writeln('Exiting the application. Goodbye!'); running = false; } } }