diff options
author | Yaroslav <contact@yaroslavps.com> | 2020-10-06 14:13:14 +0300 |
---|---|---|
committer | Yaroslav <contact@yaroslavps.com> | 2020-10-06 14:13:14 +0300 |
commit | 742b9fa46d74762f58ae939afd980a532cc4636f (patch) | |
tree | 0cd372442e5518dece1a9ec371ae71dccc5faae4 /budget | |
parent | cc688c4dc73d3b13be5aba1bd292cc31265c5d04 (diff) | |
download | finbudg-370dc39882eebda85fa239a976e2fce19b819dbb.tar.gz finbudg-370dc39882eebda85fa239a976e2fce19b819dbb.zip |
Account for days elapsed based on latest datev0.1.2
Instead of counting the number of days for the averge through
the number of iterations, let it be the difference between the latest
date on entry and the start of the period. Id est:
* 'Missing' dates from the input are implicit.
* The order of the days doesn't affect the output (although it doesn't
make sense to put the days out of order).
Diffstat (limited to 'budget')
-rw-r--r-- | budget/src/lib.rs | 31 | ||||
-rw-r--r-- | budget/tests/budget.rs | 29 | ||||
-rw-r--r-- | budget/tests/test.toml | 6 |
3 files changed, 35 insertions, 31 deletions
diff --git a/budget/src/lib.rs b/budget/src/lib.rs index e8bb8f3..7d7c390 100644 --- a/budget/src/lib.rs +++ b/budget/src/lib.rs @@ -51,6 +51,7 @@ pub struct Calculated { pub balance: f64, pub days_left: f64, pub days_left_essential: f64, + pub last_day: NaiveDate, } #[derive(PartialEq, Eq, Debug)] @@ -96,7 +97,11 @@ pub fn parse_account(path: &str) -> Result<Account, ParseError> { } } -pub fn calculate(account: &Account) -> Calculated { +pub fn calculate(account: &Account) -> Option<Calculated> { + if account.days.len() < 1 { + return None; + } + let mut calculated = Calculated { all_day_average: 0.0, essential_day_average: 0.0, @@ -107,12 +112,13 @@ pub fn calculate(account: &Account) -> Calculated { balance: 0.0, days_left: 0.0, days_left_essential: 0.0, + last_day: account.days.last().unwrap().date, }; - let mut days_calculated = 0; - for day in account.days.iter() { - days_calculated += 1; + if day.date > calculated.last_day { + calculated.last_day = day.date; + } for expense in day.expenses.iter() { calculated.total += expense.price; @@ -135,15 +141,18 @@ pub fn calculate(account: &Account) -> Calculated { } } - calculated.all_day_average = calculated.total / days_calculated as f64; + let days_elapsed = + (calculated.last_day - account.start_date).num_days() + 1; + + calculated.all_day_average = calculated.total / days_elapsed as f64; calculated.essential_day_average = - calculated.essential_subtotal / days_calculated as f64; + calculated.essential_subtotal / days_elapsed as f64; for (category, subtotal) in calculated.categories_subtotal.iter() { calculated.categories_day_average .insert( category.clone(), - subtotal / days_calculated as f64, + subtotal / days_elapsed as f64, ); } @@ -153,11 +162,5 @@ pub fn calculate(account: &Account) -> Calculated { calculated.days_left_essential = calculated.balance / calculated.essential_day_average; - calculated -} - -pub fn get_calculated(path: &str) -> Result<Calculated, ParseError> { - let account = parse_account(path)?; - - Ok(calculate(&account)) + Some(calculated) } diff --git a/budget/tests/budget.rs b/budget/tests/budget.rs index 1cc02e7..feae240 100644 --- a/budget/tests/budget.rs +++ b/budget/tests/budget.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use chrono::prelude::*; +use chrono::NaiveDate; use budget::*; @@ -62,6 +62,10 @@ fn can_parse_account() -> Result<(), ParseError>{ ], }, Day { + date: NaiveDate::from_ymd(2020, 10, 4), + expenses: Vec::<Expense>::new(), + }, + Day { date: NaiveDate::from_ymd(2020, 10, 2), expenses: vec![ Expense { @@ -82,10 +86,6 @@ fn can_parse_account() -> Result<(), ParseError>{ }, ], }, - Day { - date: NaiveDate::from_ymd(2020, 10, 3), - expenses: Vec::<Expense>::new(), - }, ], }; @@ -99,32 +99,33 @@ fn can_parse_account() -> Result<(), ParseError>{ #[test] fn can_calculate() -> Result<(), ParseError> { let mut should_be = Calculated { - all_day_average: 7.57, - essential_day_average: 6.3, + all_day_average: 5.6775, + essential_day_average: 4.725, categories_day_average: HashMap::<String, f64>::new(), essential_subtotal: 18.9, categories_subtotal: HashMap::<String, f64>::new(), total: 22.71, balance: 397.29, - days_left: 52.48216644649934, - days_left_essential: 63.06190476190476, + days_left: 69.9762219286658, + days_left_essential: 84.08253968253969, + last_day: NaiveDate::from_ymd(2020, 10, 04), }; should_be.categories_day_average.insert( "supplies".to_string(), - 1.27, + 0.9525, ); should_be.categories_day_average.insert( "products".to_string(), - 2.3333333333333335, + 1.75, ); should_be.categories_day_average.insert( "transport".to_string(), - 2.3000000000000003, + 1.725, ); should_be.categories_day_average.insert( "utilities".to_string(), - 1.6666666666666667, + 1.25, ); should_be.categories_subtotal.insert( @@ -145,7 +146,7 @@ fn can_calculate() -> Result<(), ParseError> { ); let account = budget::parse_account("tests/test.toml")?; - let actually_is = budget::calculate(&account); + let actually_is = budget::calculate(&account).unwrap(); assert_eq!(actually_is, should_be); diff --git a/budget/tests/test.toml b/budget/tests/test.toml index 1bb1ce7..a29467e 100644 --- a/budget/tests/test.toml +++ b/budget/tests/test.toml @@ -39,6 +39,9 @@ date = 2020-10-01 shared = 2 [[days]] +date = 2020-10-04 + +[[days]] date = 2020-10-02 [[days.expenses]] @@ -52,6 +55,3 @@ date = 2020-10-02 price = 6.9 category = "transport" -[[days]] -date = 2020-10-03 - |