use crate::domain::hfbi::CampionamentoHFBI;
pub fn calc_bn(campione: &CampionamentoHFBI) -> f32 {
let mut b = 0.0;
let mut n = 0.0;
for specie in campione {
b += specie.peso;
n += specie.numero_individui as f32;
}
let bn = ((b / n) + 1.0).ln();
(1000.0 * bn).round() / 1000.0
}
#[cfg(test)]
mod bn_private_tests {
use super::*;
use crate::domain::hfbi::{
CampionamentoHFBI, GruppoEcoHFBI, GruppoTrofHFBI, RecordHFBI, SpecieHFBI,
};
const EPSILON: f32 = 1e-6;
fn create_dummy_record(peso: f32) -> RecordHFBI {
RecordHFBI {
specie: SpecieHFBI {
nome_comune: "Dummy".to_string(),
codice_specie: "DM".to_string(),
autoctono: true,
gruppo_eco: GruppoEcoHFBI::ResidentiDiEstuario, gruppo_trofico: GruppoTrofHFBI {
microbentivori: 0.0,
macrobentivori: 0.0,
iperbentivori: 0.0,
erbivori: 0.0,
detritivori: 0.0,
planctivori: 0.0,
onnivori: 0.0,
},
},
numero_individui: 1,
peso,
}
}
#[test]
fn test_calc_bn_empty_campionamento() {
let campione = CampionamentoHFBI::new(vec![]);
let result = calc_bn(&campione);
assert!(
result.is_nan(),
"Expected NaN for empty input, but got {}",
result
);
}
#[test]
fn test_calc_bn_single_specie() {
let campione = CampionamentoHFBI::new(vec![create_dummy_record(150.0)]);
let result = calc_bn(&campione);
let expected = (1000.0 * 151.0_f32.ln()).round() / 1000.0;
assert!(
(result - expected).abs() < EPSILON,
"Failed single specie test. Expected: {}, Got: {}",
expected,
result
);
}
#[test]
fn test_calc_bn_multiple_species() {
let campione = CampionamentoHFBI::new(vec![
create_dummy_record(100.0),
create_dummy_record(200.0),
create_dummy_record(50.0),
]);
let result = calc_bn(&campione);
let expected = (1000.0 * (350.0_f32 / 3.0 + 1.0).ln()).round() / 1000.0;
assert!(
(result - expected).abs() < EPSILON,
"Failed multiple species test. Expected: {}, Got: {}",
expected,
result
);
}
}