diff options
author | Guillermo Ramos | 2025-02-04 00:09:04 +0100 |
---|---|---|
committer | Guillermo Ramos | 2025-02-04 01:02:01 +0100 |
commit | 8907130570df1a67d30a0266c2ba17c27975d713 (patch) | |
tree | 0edfbc66905acb3c27c1fa70034781437582fe92 /src/lib.rs | |
parent | 2a70a5e09e36d00b9b46ded6eda9fbaf0cc5352a (diff) | |
download | hiccup-8907130570df1a67d30a0266c2ba17c27975d713.tar.gz |
Mortgage updates
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 100 |
1 files changed, 74 insertions, 26 deletions
@@ -1,9 +1,10 @@ +use std::collections::HashMap; use std::fmt; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Mortgage { period: u32, - capital: f64, + principal: f64, i12: f64, quota: f64, quotas: u32, @@ -13,65 +14,112 @@ impl fmt::Display for Mortgage { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "{:5} | {:4.2}\t{:.2}\t{:.2}\t{:.2}", + "{:3} | {:5} | {:4.2}\t{:.2}\t{:.2}\t{:.2}", + if self.period % 12 == 0 { + format!("Y{}", (self.period / 12) + 1) + } else { + "".to_string() + }, self.period, self.quota, - self.interests(), - self.amortized(), - self.capital + self.quota_interest(), + self.quota_principal(), + self.principal ) } } impl Mortgage { - pub fn new(capital: f64, i1: f64, years: u32) -> Self { + pub fn new(principal: f64, i1: f64, years: u32) -> Self { let quotas = years * 12; let i12 = i1 / 12.0; Mortgage { period: 0, - capital, + principal, i12, - quota: Self::quota(capital, i12, quotas), + quota: Self::quota(principal, i12, quotas), quotas, } } - pub fn run(&mut self) { - let to_pay = self.quota * self.quotas as f64; - let capital = self.capital; - let interest = to_pay - capital; + pub fn run(&mut self, updates: HashMap<u32, MortgageUpdate>) { + let principal = self.principal; - println!("Cuota | c\tIn\tAn\tCn"); - while self.quotas > 0 { + let topay_total = self.quota * self.quotas as f64; + let topay_interest = topay_total - principal; + + let mut payed_total = 0.; + let mut payed_principal = 0.; + let mut payed_interest = 0.; + let mut payed_amortized = 0.; + + println!("Año | Cuota | c\t\tIn\tAn\tCn"); + while self.quotas > 0 && self.principal > 0. { println!("{self}"); + if let Some(update) = updates.get(&self.period) { + payed_amortized += self.update(update); + } + payed_total += self.quota; + payed_principal += self.quota_principal(); + payed_interest += self.quota_interest(); self.step(); } + + payed_total += payed_amortized; + + println!("\n# A PRIORI"); + println!( + "== Total a pagar: {:.2} ({} cap + {topay_interest:.2} int)", + topay_total, principal + ); + println!( + "== Los intereses suponen un {:.2}% del total", + 100. * topay_interest / topay_total + ); + + println!("\n# A POSTERIORI"); println!( - "\n== Total a pagar: {:.2} ({} cap + {interest:.2} int)", - to_pay, capital + "== Total pagado: {:.2} ({:.2} cap + {:.2} int + {:.2} amortizado)", + payed_total, payed_principal, payed_interest, payed_amortized ); println!( - "== Los intereses suponen un {:.2}% del capital", - 100. * interest / capital + "== Los intereses suponen un {:.2}% del total", + 100. * payed_interest / payed_total ); println!("\n"); } - fn quota(capital: f64, i12: f64, quotas: u32) -> f64 { - capital * i12 / (1.0 - (1.0 + i12).powi(-(quotas as i32))) + fn update(&mut self, update: &MortgageUpdate) -> f64 { + print!(" [MORTGAGE UPDATE: "); + match update { + MortgageUpdate::Amortize(principal) => { + println!("{principal:.2} amortized to reduce quotas]"); + self.principal -= principal; + self.quota = Self::quota(self.principal, self.i12, self.quotas); + *principal + } + } + } + + fn quota(principal: f64, i12: f64, quotas: u32) -> f64 { + principal * i12 / (1.0 - (1.0 + i12).powi(-(quotas as i32))) } fn step(&mut self) { self.period += 1; self.quotas -= 1; - self.capital = (1.0 + self.i12) * self.capital - self.quota; + self.principal = (1.0 + self.i12) * self.principal - self.quota; } - fn interests(&self) -> f64 { - self.i12 * self.capital + fn quota_interest(&self) -> f64 { + self.i12 * self.principal } - fn amortized(&self) -> f64 { - self.quota - self.interests() + fn quota_principal(&self) -> f64 { + self.quota - self.quota_interest() } } + +pub enum MortgageUpdate { + Amortize(f64), +} |