add current-calculator challenge

This commit is contained in:
sigil-03 2025-12-11 20:58:05 -07:00
parent 8575c1c887
commit e540ece963
5 changed files with 137 additions and 0 deletions

1
current-calculator/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

7
current-calculator/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "current-calculator"
version = "0.1.0"

View file

@ -0,0 +1,6 @@
[package]
name = "current-calculator"
version = "0.1.0"
edition = "2024"
[dependencies]

View file

@ -0,0 +1 @@

View file

@ -0,0 +1,122 @@
use std::f32;
fn main() {
println!("Hello, world!");
}
// TODO: maybe don't cast all good data as float??
#[derive(Clone, Debug)]
enum EntryValue {
NoneType,
Float(f32),
String(String),
}
// impl Eq for EntryValue {
// fn e
// }
struct DataEntry {
power: EntryValue,
voltage: EntryValue,
}
impl DataEntry {
pub fn new(power: EntryValue, voltage: EntryValue) -> Self {
Self { power, voltage }
}
pub fn compute_current(&self) -> Option<f32> {
// check the data types, only return Some(value) if both data entries are valid
match (&self.power, &self.voltage) {
(EntryValue::Float(power), EntryValue::Float(voltage)) => Some(power / voltage),
_ => None,
}
}
}
struct DataParser {
dataset: Vec<DataEntry>,
}
impl DataParser {
pub fn new(powers: Vec<EntryValue>, voltages: Vec<EntryValue>) -> Self {
// TODO: generate our vec of DataEntry out of EntryValues
let mut dataset = Vec::new();
// TODO: don't use clone here, also just don't create the whole dataset variable (waste memory)
for i in 0..powers.len() {
dataset.push(DataEntry {
power: powers[i].clone(),
voltage: voltages[i].clone(),
})
}
Self { dataset }
}
pub fn get_result(&self) -> Vec<Option<f32>> {
let mut res = Vec::new();
for entry in &self.dataset {
res.push(entry.compute_current());
}
res
}
}
#[cfg(test)]
mod test {
use super::DataEntry;
use super::DataParser;
use super::EntryValue;
#[test]
fn test_current_calc() {
// TODO: maybe have some amount of randomness here
let p = EntryValue::Float(4.0);
let v = EntryValue::Float(2.0);
let exp_i = Some(2.0);
let de = DataEntry::new(p, v);
let i = de.compute_current();
assert_eq!(i, exp_i);
}
#[test]
fn bad_data_test() {
let powers = vec![
EntryValue::Float(37.2),
EntryValue::Float(0.0),
EntryValue::String("X".into()),
EntryValue::Float(-192.0),
EntryValue::NoneType,
];
let voltages = vec![
EntryValue::NoneType,
EntryValue::Float(82.8),
EntryValue::Float(32.0),
EntryValue::Float(-76.0),
EntryValue::String("Y".into()),
];
// one memory opt we could do is to implement a zipped iterator
let data_parser = DataParser::new(powers, voltages);
let res = data_parser.get_result();
let test_result = vec![None, Some(0.0), None, Some(2.5263157), None];
// let test_result = vec![None, Some(0.0), None, Some(2.52631), None];
for i in 0..res.len() {
assert_eq!(res[i], test_result[i])
}
}
}
// TEST CONDITION
// powers = [37.2, 0, "X", -192, None]
// voltages = [None, 82.8, 32, -76, "Y"]
// result = [None, 0.0, None, 2.52631, None]