Calculate Total Income in Rust
Mục tiêu: A function to calculate total income from a list of transactions in Rust.
To calculate the total income, we’ll create a function that iterates through all transactions and sums up the amounts for transactions of type Income. Here’s how we’ll implement it:
/// Calculates the total income from a list of transactions
///
/// Args:
/// transactions (Vec<Transaction>): A vector of Transaction structs
///
/// Returns:
/// f64: The total income amount
pub fn calculate_total_income(transactions: &Vec<Transaction>) -> f64 {
let mut total_income = 0.0;
// Iterate through each transaction
for transaction in transactions {
// Check if the transaction type is Income
if transaction.transaction_type == TransactionType::Income {
// Add the amount to total_income
total_income += transaction.amount;
}
}
total_income
}
Explanation
- Function Definition: We define a public function
calculate_total_incomethat takes an immutable reference to a vector ofTransactionstructs. - Variable Initialization: We initialize
total_incometo 0.0 to store the cumulative income. - Iteration: We loop through each
Transactionin the provided vector. - Type Checking: For each transaction, we check if its type is
Incomeusing theTransactionTypeenum. - Summation: If the transaction is an income, we add its amount to
total_income. - Return Value: Finally, we return the total income.
This function is straightforward and efficient, with a time complexity of O(n), where n is the number of transactions.
Example Usage
let income_transaction = Transaction {
date: "2023-01-01".to_string(),
description: "Salary".to_string(),
amount: 5000.0,
transaction_type: TransactionType::Income,
};
let expense_transaction = Transaction {
date: "2023-01-02".to_string(),
description: "Rent".to_string(),
amount: 1500.0,
transaction_type: TransactionType::Expense,
};
let transactions = vec![income_transaction, expense_transaction];
let total_income = calculate_total_income(&transactions);
println!("Total income: ${}", total_income); // Output: Total income: $5000
Next Steps
Now that we’ve implemented the total income calculation, you can proceed to:
- Implement the
calculate_total_expensesfunction following a similar pattern - Create the
calculate_average_expensefunction - Finally, create a function to display these statistics in a formatted way
Further Reading
Calculating Total Expenses in Rust
Mục tiêu: A function to calculate the total expenses from a list of transactions in Rust.
Calculating Total Expenses in Rust for Personal Finance Tracker
Now that we’ve set up our data structures and basic transaction functionality, let’s move on to implementing the financial calculations. Our first task is to create a function to calculate the total expenses from our list of transactions.
Understanding the Requirements
We need to:
- Sum up all the amounts from transactions where the type is
Expense - Return this total as a floating-point number
- Ensure the function is efficient and easy to understand
Approach
- Filter Transactions: We’ll filter our transactions to include only those of type
Expense - Sum Amounts: Using Rust’s iterator methods, we’ll sum up the amounts of these filtered transactions
- Return Total: The total will be returned as an
f64to maintain precision
Solution Code
// Function to calculate total expenses
pub fn calculate_total_expenses(transactions: &[Transaction]) -> f64 {
transactions
.iter()
.filter(|transaction| matches!(transaction.transaction_type, TransactionType::Expense))
.fold(0.0, |acc, transaction| acc + transaction.amount)
}
Explanation
- Filtering Transactions: The
filter()method is used to include only transactions where the type isExpense - Summing Amounts: The
fold()method accumulates the total by adding each transaction’s amount to the accumulator (acc) - Type Matching: Using
matches!macro for clean and readable type checking
Example Usage
fn main() {
// Example transactions
let income1 = Transaction {
date: "2023-01-01".to_string(),
description: "Salary".to_string(),
amount: 2000.0,
transaction_type: TransactionType::Income,
};
let expense1 = Transaction {
date: "2023-01-02".to_string(),
description: "Rent".to_string(),
amount: 1000.0,
transaction_type: TransactionType::Expense,
};
let expense2 = Transaction {
date: "2023-01-03".to_string(),
description: "Groceries".to_string(),
amount: 500.0,
transaction_type: TransactionType::Expense,
};
let transactions = vec![income1, expense1, expense2];
// Calculate total expenses
let total_expenses = calculate_total_expenses(&transactions);
println!("Total expenses: ${:.2}", total_expenses); // Output: 1500.00
}
Next Steps
- Calculate Total Income: Implement a similar function for total income
- Calculate Average Expense: Create a function to find the average expense amount
- Display Statistics: Combine these calculations into a formatted display function
Key Points
- Efficiency: Using iterator methods is both concise and efficient
- Readability: The code is easy to understand and maintain
- Type Safety: Strong typing ensures we only sum expense transactions
Further Reading
Calculate Average Expense in Rust
Mục tiêu: Implementation of a function to compute the average expense from a list of transactions, including handling edge cases and testing.
Calculating Average Expense in Rust
Now that we’ve implemented functions to calculate total income and total expenses, the next logical step is to calculate the average expense. This will give users a better understanding of their spending patterns.
Approach
To calculate the average expense, we’ll follow these steps:
- Filter transactions to include only expenses (since income shouldn’t be included in expense calculations)
- Sum all the expense amounts
- Count the number of expense transactions
- Divide the total expenses by the number of transactions to get the average
- Handle edge cases where there are no expenses to avoid division by zero
Implementation
/// Calculates the average expense from a slice of Transaction
/// Returns 0.0 if there are no expenses
fn calculate_average_expense(transactions: &[Transaction]) -> f64 {
let mut total_expenses = 0.0;
let mut count = 0;
for transaction in transactions {
if let TransactionType::Expense = transaction.transaction_type {
total_expenses += transaction.amount;
count += 1;
}
}
if count == 0 {
0.0
} else {
total_expenses / count as f64
}
}
/// Displays summary statistics in a formatted way
fn display_statistics(transactions: &[Transaction]) {
let total_income = calculate_total_income(transactions);
let total_expenses = calculate_total_expenses(transactions);
let average_expense = calculate_average_expense(transactions);
println!("Financial Statistics:");
println!("---------------------");
println!("Total Income: ${:.2}", total_income);
println!("Total Expenses: ${:.2}", total_expenses);
println!("Average Expense: ${:.2}", average_expense);
println!("Number of Transactions: {}", transactions.len());
}
Explanation
- Filtering Transactions:
- We iterate through each transaction and check if its type is
Expense. This ensures we only consider actual expenses in our calculation. - Summing Expenses:
- For each expense transaction, we add its amount to
total_expenses. - Counting Transactions:
- We maintain a count of how many expense transactions we’ve processed.
- Calculating Average:
- If there are no expenses (
countis 0), we return 0.0 to avoid division by zero. - Otherwise, we divide
total_expensesbycount(cast tof64for floating point division). - Displaying Statistics:
- The
display_statisticsfunction calls our existing functions to get total income and expenses, and the new average expense function. - It then prints these statistics in a formatted way for better readability.
Testing
To ensure our function works correctly, let’s add some test cases:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_calculate_average_expense() {
let transactions = vec![
Transaction {
date: "2023-01-01".to_string(),
description: "Rent".to_string(),
amount: 1000.0,
transaction_type: TransactionType::Expense,
},
Transaction {
date: "2023-01-02".to_string(),
description: "Groceries".to_string(),
amount: 50.0,
transaction_type: TransactionType::Expense,
},
Transaction {
date: "2023-01-03".to_string(),
description: "Salary".to_string(),
amount: 2000.0,
transaction_type: TransactionType::Income,
},
];
let average = calculate_average_expense(&transactions);
assert_eq!(average, (1000.0 + 50.0) / 2.0);
}
#[test]
fn test_no_expenses() {
let transactions = vec![
Transaction {
date: "2023-01-01".to_string(),
description: "Salary".to_string(),
amount: 2000.0,
transaction_type: TransactionType::Income,
},
];
let average = calculate_average_expense(&transactions);
assert_eq!(average, 0.0);
}
}
Next Steps
Now that we’ve implemented the average expense calculation, you can:
- Modify the command-line interface to display these statistics
- Add more statistical functions like median expense or expense categories
- Implement data visualization to show trends over time
Further Reading
Displaying Financial Statistics in Rust
Mục tiêu: A function to format and display financial statistics including total income, expenses, and average expense.
Let’s create a function to display statistics in a formatted way. This function will take the calculated statistics and present them in a user-friendly format.
Implementation
We’ll create a function called display_statistics that will take the total income, total expenses, and average expense as parameters. We’ll format these values using Rust’s format! macro to make them more readable.
/// Displays the financial statistics in a formatted way
///
/// # Arguments
/// * `total_income` - The total income amount
/// * `total_expenses` - The total expenses amount
/// * `average_expense` - The average expense amount
pub fn display_statistics(total_income: f64, total_expenses: f64, average_expense: f64) {
println!("------------------------- Financial Summary -------------------------");
println!(" Total Income: ${:.2f}", total_income);
println!(" Total Expenses: ${:.2f}", total_expenses);
println!(" Average Expense: ${:.2f}", average_expense);
println!("-------------------------------------------------------------------");
}
Explanation
- Function Definition:
- The function
display_statisticsis defined as public (pub) so it can be accessed from other modules if needed. - It takes three parameters:
total_income,total_expenses, andaverage_expense, all of typef64(64-bit floating point numbers). - String Formatting:
- We use Rust’s
format!macro throughprintln!to format the output. - The
:.2fformat specifier ensures that the numbers are displayed with two decimal places. - Readability:
- The output is formatted with a header and separator lines to make it more readable.
- Each statistic is printed on a new line with a clear label.
Example Output
When called with sample data:
display_statistics(1000.0, 750.0, 25.0);
The output will be:
------------------------- Financial Summary -------------------------
Total Income: $1000.00
Total Expenses: $750.00
Average Expense: $25.00
-------------------------------------------------------------------
Next Steps
Now that we have implemented the display function, you can:
- Call this function after calculating the statistics in your main application logic.
- You might want to add more statistics like highest expense category or most frequent expense type.
- Consider adding color formatting using libraries like
ansi-termfor better visual appeal.