kda_tools/
lib.rs

1use std::cmp::Ordering;
2pub fn version()->String{
3    return std::format!("{}-Alpha, built with kvc {} and poisson-rate-test {}",
4    env!("CARGO_PKG_VERSION").to_string(),
5    kvc::version(),
6    poisson_rate_test::version()).to_string();
7}
8pub fn about()->String{
9    "Some basic conditional probabilities and bayesian analysis on a KVC log. \n\
10    Copyright (C) 2021 Joshua Vander Hook\n\n\
11    This program comes with ABSOLUTELY NO WARRANTY.\n\
12    This is free software, and you are welcome to redistribute\n\
13    it under certain conditions. See LICENSE for more details or\n\
14    https://github.com/jodavaho/kda-tools for more info. ".to_string()
15}
16
17#[derive(Debug)]
18pub struct ResultRecord{
19    pub metric_name:String,
20    pub variable_groupings:String,
21    pub p_val:f64,
22    pub n_with:usize,
23    pub n_without:usize,
24    pub metric_with:f64,
25    pub metric_without:f64,
26    pub numer_with:usize,
27    pub denom_with:usize,
28    pub numer_without:usize,
29    pub denom_without:usize,
30    pub comment:String,
31}
32pub fn by_pval(a:&ResultRecord,b: &ResultRecord) -> Ordering
33{
34    if a.p_val.is_nan(){
35        return std::cmp::Ordering::Greater;
36    } else if b.p_val.is_nan(){
37        return std::cmp::Ordering::Less;
38    } else {
39        return a.p_val.partial_cmp(&b.p_val).unwrap();
40    }
41}
42
43#[derive(Debug)]
44pub struct ShortRecord{
45    pub metric_name:String,
46    pub variable_groupings:String,
47    pub p_val:f64,
48    pub n_with:usize,
49    pub n_without:usize,
50    pub metric_with:f64,
51    pub metric_without:f64,
52    pub comment:String,
53}
54pub fn by_short_pval(a:&ShortRecord,b: &ShortRecord) -> Ordering
55{
56    if a.p_val.is_nan(){
57        return std::cmp::Ordering::Greater;
58    } else if b.p_val.is_nan(){
59        return std::cmp::Ordering::Less;
60    } else {
61        return a.p_val.partial_cmp(&b.p_val).unwrap();
62    }
63}
64
65pub fn align_output(outs: &Vec<String>,widths:&Vec<usize>,seperator:&str)
66-> String{
67    let len:usize=widths.iter().filter(|x| x < &&usize::MAX ).sum();
68    let final_len = len + outs.len()-1;//<-seperators
69    let mut ret = String::with_capacity(final_len);
70    for i in 0..outs.len(){
71        let wi=widths[i];
72        let s = &outs[i];
73        let slen = s.len().min(wi);
74        ret.push_str(&s[0..slen]);
75        if i<outs.len()-1{
76            ret.push_str(&seperator[..]);
77            for _ in slen..wi{
78                ret.push(' ');
79            }
80        } 
81    }
82    ret
83}
84
85mod test{
86    #[test]
87    fn test_inf_compare(){
88        use claim::{assert_gt,assert_lt};
89        let inf = f64::INFINITY;
90        let x = 0.0;
91        //comparisons succeed w/ inf
92        assert_gt!(inf,x);
93        assert_lt!(x,inf);
94    }
95    #[test]
96    fn test_nan_compare_for_pvals(){
97        
98        let nan = f64::NAN;
99        let x = 0.0;
100        let y  =1.0;
101        let cmpres = nan.partial_cmp(&x);
102        match cmpres{
103            Some(_)=>assert!(false,"Should not reach here, should never work"),
104            None=>assert!(true),
105        }
106        let mut list = vec![nan,x,y];
107        list.sort_by(
108            |a,b| {
109                if a.is_nan(){
110                    return std::cmp::Ordering::Greater;
111                } else if b.is_nan(){
112                    return std::cmp::Ordering::Less;
113                } else {
114                    return a.partial_cmp(b).unwrap();
115                }
116            }
117        );
118        assert_eq!(list[0..2],[x,y]);
119        assert!(list[2].is_nan());
120    }
121}