binom calculator component

This commit is contained in:
Felipe 2025-07-31 22:51:09 -04:00
parent 7d343ce2cb
commit 2f7c160165
Signed by: pitbuster
SSH key fingerprint: SHA256:HDYu2Pm4/TmSX8GBwV49UvFWr1Ljg8XlHxKeCpjJpOk
4 changed files with 48 additions and 44 deletions

View file

@ -24,7 +24,7 @@ body {
header { header {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: end; justify-content: space-between;
} }
header > select { header > select {

View file

@ -55,6 +55,23 @@ pub fn hyper_geometric(
} }
} }
#[derive(Default)]
pub struct BinomialProb {
pub exactly: f64,
pub less_than: f64,
pub less_or_equal: f64,
pub greater_than: f64,
pub greater_or_equal: f64,
}
pub fn binomial(
success_probability: f64,
trials_number: u8,
successes_number: u8,
) -> Option<BinomialProb> {
None
}
/// Computes the probability of drawing exactly `sample_successes` in a sample of `sample_size` /// Computes the probability of drawing exactly `sample_successes` in a sample of `sample_size`
/// from a population of size `population_size` and `successes` total successes in the population. /// from a population of size `population_size` and `successes` total successes in the population.
/// ///

View file

@ -6,7 +6,7 @@ use leptos::prelude::{
use leptos::{IntoView, component, view}; use leptos::{IntoView, component, view};
use leptos_fluent::move_tr; use leptos_fluent::move_tr;
use crate::calc::hyper_geometric; use crate::calc::{binomial, hyper_geometric};
#[component] #[component]
pub fn HyperCalculator() -> impl IntoView { pub fn HyperCalculator() -> impl IntoView {
@ -109,74 +109,60 @@ pub fn HyperCalculator() -> impl IntoView {
</span> </span>
<span class="right">{move || display_rounded(result().greater_or_equal)}</span> <span class="right">{move || display_rounded(result().greater_or_equal)}</span>
</div> </div>
<div>{move_tr!("hyper-description")}</div>
} }
} }
#[component] #[component]
pub fn BinomCalculator() -> impl IntoView { pub fn BinomCalculator() -> impl IntoView {
let (population, set_population) = signal(0u8); let (success_probability, set_success_probability) = signal(0f64);
let (successes, set_successes) = signal(0u8); let (trials_number, set_trials_number) = signal(0u8);
let (sample, set_sample) = signal(0u8); let (successes_number, set_successes_number) = signal(0u8);
let (sample_successes, set_sample_successes) = signal(0u8);
let result = move || { let result = move || {
hyper_geometric( binomial(
population.get(), success_probability.get(),
successes.get(), trials_number.get(),
sample.get(), successes_number.get(),
sample_successes.get(),
) )
.unwrap_or_default() .unwrap_or_default()
}; };
view! { view! {
<form> <form>
<p> <p>
<label for="population">{move_tr!("population")}</label> <label for="success_probability">{move_tr!("success-probability")}</label>
<input <input
id="population" id="success_probability"
type="number" type="number"
min=0 min=0
prop:value=population max=1
prop:value=success_probability
on:input:target=move |ev| { on:input:target=move |ev| {
set_population.set(ev.target().value().parse().unwrap_or_default()) set_success_probability.set(ev.target().value().parse().unwrap_or_default())
} }
/> />
</p> </p>
<p> <p>
<label for="successes">{move_tr!("successes")}</label> <label for="trials_number">{move_tr!("trials-number")}</label>
<input <input
id="successes" id="trials_number"
type="number" type="number"
min=0 min=0
prop:max=population prop:value=trials_number
prop:value=successes
on:input:target=move |ev| { on:input:target=move |ev| {
set_successes.set(ev.target().value().parse().unwrap_or_default()) set_trials_number.set(ev.target().value().parse().unwrap_or_default())
} }
/> />
</p> </p>
<p> <p>
<label for="sample">{move_tr!("sample")}</label> <label for="successes_number">{move_tr!("successes-number")}</label>
<input <input
id="sample" id="successes_number"
type="number" type="number"
min=0 min=0
prop:max=population prop:max=trials_number
prop:value=sample prop:value=successes_number
on:input:target=move |ev| { on:input:target=move |ev| {
set_sample.set(ev.target().value().parse().unwrap_or_default()) set_successes_number.set(ev.target().value().parse().unwrap_or_default())
}
/>
</p>
<p>
<label for="sample_successes">{move_tr!("sample-successes")}</label>
<input
id="sample_successes"
type="number"
min=0
prop:max=sample
prop:value=sample_successes
on:input:target=move |ev| {
set_sample_successes.set(ev.target().value().parse().unwrap_or_default())
} }
/> />
</p> </p>
@ -184,35 +170,36 @@ pub fn BinomCalculator() -> impl IntoView {
<div class="results"> <div class="results">
<span class="left"> <span class="left">
<span>"P(X = "</span> <span>"P(X = "</span>
<span>{sample_successes}</span> <span>{successes_number}</span>
<span>"): "</span> <span>"): "</span>
</span> </span>
<span class="right">{move || display_rounded(result().exactly)}</span> <span class="right">{move || display_rounded(result().exactly)}</span>
<span class="left"> <span class="left">
<span>"P(X < "</span> <span>"P(X < "</span>
<span>{sample_successes}</span> <span>{successes_number}</span>
<span>"): "</span> <span>"): "</span>
</span> </span>
<span class="right">{move || display_rounded(result().less_than)}</span> <span class="right">{move || display_rounded(result().less_than)}</span>
<span class="left"> <span class="left">
<span>"P(X ≤ "</span> <span>"P(X ≤ "</span>
<span>{sample_successes}</span> <span>{successes_number}</span>
<span>"): "</span> <span>"): "</span>
</span> </span>
<span class="right">{move || display_rounded(result().less_or_equal)}</span> <span class="right">{move || display_rounded(result().less_or_equal)}</span>
<span class="left"> <span class="left">
<span>"P(X > "</span> <span>"P(X > "</span>
<span>{sample_successes}</span> <span>{successes_number}</span>
<span>"): "</span> <span>"): "</span>
</span> </span>
<span class="right">{move || display_rounded(result().greater_than)}</span> <span class="right">{move || display_rounded(result().greater_than)}</span>
<span class="left"> <span class="left">
<span>"P(X ≥ "</span> <span>"P(X ≥ "</span>
<span>{sample_successes}</span> <span>{successes_number}</span>
<span>"): "</span> <span>"): "</span>
</span> </span>
<span class="right">{move || display_rounded(result().greater_or_equal)}</span> <span class="right">{move || display_rounded(result().greater_or_equal)}</span>
</div> </div>
<div>{move_tr!("binom-description")}</div>
} }
} }

View file

@ -9,7 +9,7 @@ pub fn Common() -> impl IntoView {
view! { view! {
<I18n> <I18n>
<header> <header>
<a href="/">Home</a> <a href="/">"🏡"</a>
<LanguageSelector /> <LanguageSelector />
</header> </header>
<Outlet /> <Outlet />