aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGuillermo Ramos2025-02-04 00:09:04 +0100
committerGuillermo Ramos2025-02-04 01:02:01 +0100
commit8907130570df1a67d30a0266c2ba17c27975d713 (patch)
tree0edfbc66905acb3c27c1fa70034781437582fe92 /src
parent2a70a5e09e36d00b9b46ded6eda9fbaf0cc5352a (diff)
downloadhiccup-8907130570df1a67d30a0266c2ba17c27975d713.tar.gz
Mortgage updates
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs100
-rw-r--r--src/main.rs12
2 files changed, 84 insertions, 28 deletions
diff --git a/src/lib.rs b/src/lib.rs
index fc75ebd..7f8a58a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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),
+}
diff --git a/src/main.rs b/src/main.rs
index 76c7913..bbe01af 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,12 @@
+use hiccup::Mortgage;
+use hiccup::MortgageUpdate::{self, *};
+use std::collections::HashMap;
+
fn main() {
- let mut m = hiccup::Mortgage::new(390_000., 0.028, 30);
- m.run();
+ let mut updates: HashMap<u32, MortgageUpdate> =
+ HashMap::from_iter((1..29).map(|y| (y * 12, Amortize(24_000.))));
+ updates.insert(0, Amortize(15_000.));
+ let m = Mortgage::new(390_000., 0.028, 30);
+ m.clone().run(updates);
+ // m.clone().run(HashMap::new());
}