Initial commit to repo.

This commit is contained in:
Olivia Brooks
2025-06-16 07:32:32 -04:00
commit 73faa75086
5 changed files with 295 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

7
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 = "quartile_calculator"
version = "0.1.0"

6
Cargo.toml Normal file
View File

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

40
main.py Normal file
View File

@@ -0,0 +1,40 @@
from dataclasses import dataclass
from sys import float_info
from typing import TypeAlias;
@dataclass
class DatasetCalculator:
data_set: list[float]
def first_quartile(self) -> float:
self.lower_data_set()
def second_quartile(self) -> float:
...
def third_quartile(self) -> float:
...
def interquartile_range(self) -> float:
...
def semi_interquartile_range(self) -> float:
...
def strip_outliers(self) -> DatasetCalculator:
...
def lower_data_set(self) -> DatasetCalculator:
...
def upper_data_set(self) -> DatasetCalculator:
...
def median(self) -> float:
...
def main():
...
if __name__ == '__main__':
main()

241
src/main.rs Normal file
View File

@@ -0,0 +1,241 @@
fn main() {
let arizona_state: Vec<f64> = vec![11.0, 16.0, 16.0, 16.0, 9.0, 15.0];
let colorado: Vec<f64> = vec![10.0, 15.0, 12.0, 12.0, 20.0];
let iowa: Vec<f64> = vec![18.0, 10.0, 13.0, 17.0, 19.0, 16.0, 18.0];
let nebraska: Vec<f64> = vec![15.0, 28.0, 15.0, 20.0, 10.0, 11.0, 12.0];
let south_carolina: Vec<f64> = vec![18.0, 15.0, 10.0, 18.0];
let syracuse: Vec<f64> = vec![14.0, 19.0, 11.0, 15.0, 19.0];
let texas: Vec<f64> = vec![20.0, 17.0, 9.0, 9.0, 27.0];
println!("Arizona Average: {}", average(&arizona_state));
println!("Colorado Average: {}", average(&colorado));
println!("Iowa Average: {}", average(&iowa));
println!("Nebraska Average: {}", average(&nebraska));
println!("SouthCarolina Average: {}", average(&south_carolina));
println!("Syracuse Average: {}", average(&syracuse));
println!("TexasAnM Average: {}", average(&texas));
let mut set: Vec<f64> = vec![];
set.extend(arizona_state);
set.extend(colorado);
set.extend(iowa);
set.extend(nebraska);
set.extend(south_carolina);
set.extend(syracuse);
set.extend(texas);
let mut d = Dataset::from(set);
println!("Pre-outlier Stripping: {:#?}", d.0);
println!("Q1: {}", d.quartile(Quartile::First));
println!("Q2: {}", d.quartile(Quartile::Second));
println!("Q3: {}", d.quartile(Quartile::Third));
d.strip_outliers();
println!("Outliers Stripped: {:#?}", d.0)
}
fn average(values: &Vec<f64>) -> f64 {
values.iter().sum::<f64>() / values.len() as f64
}
#[derive(Debug, Clone, PartialEq)]
struct Dataset(Vec<f64>);
impl From<Vec<f64>> for Dataset {
fn from(mut value: Vec<f64>) -> Self {
Dataset({
value.sort_by(|a, b| a.partial_cmp(b).unwrap());
value
})
}
}
impl Dataset {
fn quartile(&self, quartile: Quartile) -> f64 {
let data_set = match quartile {
Quartile::First => self.half_data_set(Half::Lower),
Quartile::Second => self.clone(),
Quartile::Third => self.half_data_set(Half::Upper),
};
data_set.median()
}
/// Returns a half of the data set.
/// This method may get screwy with very small datasets.
fn half_data_set(&self, half: Half) -> Self {
let mut data = self.0.clone();
let length = data.len();
let middle_idx = length / 2;
if (length % 2) != 0 {
data.remove(middle_idx);
}
let data_set = match half {
Half::Lower => Dataset({
let _ = data.split_off(middle_idx);
data
}),
Half::Upper => Dataset(data.split_off(middle_idx)),
};
data_set
}
fn median(&self) -> f64 {
let data = self.0.clone();
let length = data.len();
let a = data[length / 2];
let median = if (length % 2) == 0 {
let s: [f64; 2] = [a, data[(length / 2) - 1]];
s.iter().sum::<f64>() / 2_f64
} else {
a
};
median
}
fn interquartile_range(&self) -> f64 {
self.quartile(Quartile::Third) - self.quartile(Quartile::First)
}
fn strip_outliers(&mut self) {
let mut data: Vec<f64>;
let first_quartile = self.quartile(Quartile::First);
let third_quartile = self.quartile(Quartile::Third);
let iqr_margin = 1.5 * self.interquartile_range();
// Filter low outliers
data = self
.0
.clone()
.into_iter()
.filter_map(|x| {
if x >= (first_quartile - iqr_margin) {
Some(x)
} else {
None
}
})
.collect::<Vec<f64>>();
// Filter high outliers.
data = data
.into_iter()
.filter_map(|x| {
if x <= (third_quartile + iqr_margin) {
Some(x)
} else {
None
}
})
.collect::<Vec<f64>>();
self.0 = data
}
}
struct Percentile(Vec<f64>);
enum Quartile {
First,
Second,
Third,
}
enum Half {
Upper,
Lower,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn odd_quartiles() {
let d = Dataset::from(vec![
1_f64, 2_f64, 3_f64, 4_f64, 5_f64, 6_f64, 7_f64, 8_f64, 9_f64, 10_f64, 11_f64,
]);
assert_eq!(d.quartile(Quartile::First), 3_f64);
assert_eq!(d.quartile(Quartile::Second), 6_f64);
assert_eq!(d.quartile(Quartile::Third), 9_f64);
}
#[test]
fn even_quartiles() {
let d = Dataset::from(vec![
1_f64, 2_f64, 3_f64, 4_f64, 5_f64, 6_f64, 7_f64, 8_f64, 9_f64, 10_f64, 11_f64, 12_f64,
]);
assert_eq!(d.quartile(Quartile::First), 3.5_f64);
assert_eq!(d.quartile(Quartile::Second), 6.5_f64);
assert_eq!(d.quartile(Quartile::Third), 9.5_f64);
}
#[test]
fn odd_dataset_halves() {
let d = Dataset::from(vec![
1_f64, 2_f64, 3_f64, 4_f64, 5_f64, 6_f64, 7_f64, 8_f64, 9_f64, 10_f64, 11_f64,
]);
assert_eq!(
d.half_data_set(Half::Lower),
Dataset::from(vec![1_f64, 2_f64, 3_f64, 4_f64, 5_f64])
);
assert_eq!(
d.half_data_set(Half::Upper),
Dataset::from(vec![7_f64, 8_f64, 9_f64, 10_f64, 11_f64])
);
}
#[test]
fn even_dataset_halves() {
let d = Dataset::from(vec![
1_f64, 2_f64, 3_f64, 4_f64, 5_f64, 6_f64, 7_f64, 8_f64, 9_f64, 10_f64, 11_f64, 12_f64,
]);
assert_eq!(
d.half_data_set(Half::Lower),
Dataset::from(vec![1_f64, 2_f64, 3_f64, 4_f64, 5_f64, 6_f64])
);
assert_eq!(
d.half_data_set(Half::Upper),
Dataset::from(vec![7_f64, 8_f64, 9_f64, 10_f64, 11_f64, 12_f64])
);
}
#[test]
fn interquartile_range() {
let d = Dataset::from(vec![
1_f64, 2_f64, 3_f64, 4_f64, 5_f64, 6_f64, 7_f64, 8_f64, 9_f64, 10_f64, 11_f64, 12_f64,
]);
assert_eq!(d.interquartile_range(), 6_f64)
}
#[test]
fn strip_outliers() {
let mut d = Dataset::from(vec![
1_f64, 7_f64, 8_f64, 9_f64, 10_f64, 11_f64, 12_f64, 98_f64,
]);
d.strip_outliers();
assert_eq!(d.0, vec![7_f64, 8_f64, 9_f64, 10_f64, 11_f64, 12_f64])
}
}