1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
extern crate plotlib;

use std::io::{self, BufRead};

pub struct HistogramConfig {
    pub nbins: u32,
}

/// Get a single column of data from stdin
///
/// For each line in the input, it tries to convert it to an `f64`.
fn get_single_column() -> Vec<f64> {
    let stdin = io::stdin();
    let mut data: Vec<f64> = vec![];
    for line in stdin.lock().lines() {
        let line_text = match line {
            Ok(line) => line,
            Err(err) => panic!("IO error: {}", err),
        };
        data.push(line_text.parse::<f64>()
            .expect(&format!("ERROR: Could not parse '{}' as an f64", line_text)));
    }
    data
}

fn get_two_columns() -> Vec<(f64, f64)> {
    let stdin = io::stdin();
    let mut data: Vec<(f64, f64)> = vec![];
    for line in stdin.lock().lines() {
        let line_text = match line {
            Ok(line) => line,
            Err(err) => panic!("IO error: {}", err),
        };
        let nums: Vec<_> = line_text.split_whitespace().collect();
        if nums.len() != 2 {
            panic!("Wrong number of args on line");
        }
        let a = nums[0];
        let b = nums[1];

        let a = a.parse::<f64>()
            .expect(&format!("ERROR: Could not parse '{}' as an f64", a));
        let b = b.parse::<f64>()
            .expect(&format!("ERROR: Could not parse '{}' as an f64", b));

        data.push((a, b));
    }
    data
}

pub fn hist(config: HistogramConfig) {
    let data = get_single_column();

    let h = plotlib::histogram::Histogram::from_vec(&data, config.nbins);

    plotlib::text_render::draw_histogram(&h);
}

pub fn scatter() {
    let data = get_two_columns();

    let h = plotlib::scatter::Scatter::from_vec(&data);

    plotlib::text_render::draw_scatter(&h);
}

pub fn average() {
    let stdin = io::stdin();
    let mut total = 0.0;
    let mut length = 0;
    for line in stdin.lock().lines() {
        let line_text = match line {
            Ok(line) => line,
            Err(err) => panic!("IO error: {}", err),
        };
        length += 1;
        total += line_text.parse::<f64>()
            .expect(&format!("ERROR: Could not parse '{}' as an f64", line_text));
    }

    println!("{}", total / length as f64);
}

pub fn stats() {
    let data = get_single_column();

    let max = data.iter().fold(-1. / 0., |a, &b| f64::max(a, b));
    let min = data.iter().fold(1. / 0., |a, &b| f64::min(a, b));
    let total: f64 = data.iter().sum();
    let average = total / data.len() as f64;
    let length = data.len();

    println!("    Max: {}", max);
    println!("    Min: {}", min);
    println!("Average: {}", average);
    println!(" Length: {}", length);
}