import 'dart:io'; // constant tax rate (15%) const double TAX_RATE = 0.15; void main() { // list to store incomes List> incomeList = []; // list to store expenses List> expenseList = []; print('Welcome to the Budget Management App!'); bool running = true; while (running) { // display menu options print('\nChoose an option:'); print('1. Add new income'); print('2. Add new expense'); print('3. Show budget summary'); print('4. Exit'); stdout.write('Enter your choice: '); String? choice = stdin.readLineSync(); if (choice == null) { print('Invalid input, please try again.'); continue; } switch (choice.trim()) { case '1': addEntry(list: incomeList, isIncome: true); break; case '2': addEntry(list: expenseList, isIncome: false); break; case '3': showSummary(incomeList, expenseList); break; case '4': print('Program ended successfully.'); running = false; break; default: print('Unknown choice. Please enter a number from 1 to 4.'); } } } // function to add an income or expense void addEntry({required List> list, required bool isIncome}) { String type = isIncome ? 'income' : 'expense'; stdout.write('Enter $type description: '); String? desc = stdin.readLineSync(); if (desc == null || desc.trim().isEmpty) { print('Description cannot be empty.'); return; } double? amount; // validate numeric input while (amount == null) { stdout.write('Enter amount (positive number): '); String? input = stdin.readLineSync(); if (input == null) { print('Invalid value, please try again.'); continue; } input = input.replaceAll(',', '.'); double? parsed = double.tryParse(input); if (parsed == null) { print('Please enter a valid number.'); } else if (parsed < 0) { print('Amount must be positive.'); } else { amount = parsed; } } // add to the list list.add({desc.trim(): amount}); print('Successfully added $type: "$desc" - ${amount.toStringAsFixed(2)} SAR'); } // function to calculate the total of a list double sumList(List> list) { double sum = 0.0; for (var item in list) { for (var value in item.values) { sum += value; } } return sum; } // function to show the full summary void showSummary(List> incomes, List> expenses) { double totalIncome = sumList(incomes); double totalExpenses = sumList(expenses); double net = totalIncome - totalExpenses; print('\n===== Budget Summary ====='); print('Total Income: ${totalIncome.toStringAsFixed(2)} SAR'); print('Total Expenses: ${totalExpenses.toStringAsFixed(2)} SAR'); if (net >= 0) { print('Net Profit: ${net.toStringAsFixed(2)} SAR'); } else { print('Net Loss: ${(-net).toStringAsFixed(2)} SAR'); } // apply tax only if profit double tax = net > 0 ? net * TAX_RATE : 0.0; String taxMessage = net > 0 ? 'Tax (${(TAX_RATE * 100).toStringAsFixed(0)}%): ${tax.toStringAsFixed(2)} SAR' : 'No tax applied since there is a loss.'; print(taxMessage); // show details if (incomes.isNotEmpty) { print('\nIncome Details:'); for (var item in incomes) { item.forEach((desc, amount) { print('- $desc : ${amount.toStringAsFixed(2)} SAR'); }); } } else { print('\nNo income recorded yet.'); } if (expenses.isNotEmpty) { print('\nExpense Details:'); for (var item in expenses) { item.forEach((desc, amount) { print('- $desc : ${amount.toStringAsFixed(2)} SAR'); }); } } else { print('\nNo expenses recorded yet.'); } print('==========================\n'); }