ecalculator.rs
· 4.4 KiB · Rust
Raw
use std::time::Instant;
use rand::prelude::*;
use std::f64::consts;
use console::Term;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
fn main() {
//Handler to terminate on CTRL+C
let running = Arc::new(AtomicBool::new(true));
let r = running.clone();
ctrlc::set_handler(move || {
r.store(false, Ordering::SeqCst);
println!();
}).expect("Error setting Ctrl-C handler");
let term = Term::stdout();
//Parses env 'SHOW_PROGRESS', value must be an int and sets how frequent to log progress
//If has a value, should log progress.
let log_interval: Option<u64> = match std::env::var("SHOW_PROGRESS").ok() {
Some(value) => Some(value.parse::<u64>().expect("not a valid integer")),
None => None
};
//Gets the maximum loops to run or none for infinity
let max_loops: Option<u64> = match std::env::var("LOOPS") {
Ok(val) => Some(val.parse::<u64>().expect("not a valid integer")),
_ => None
};
match max_loops {
Some(max_loops) => {
println!("Running {} iterations. Press CTRL+C to exit at any time.", max_loops);
run_limited(term, running, log_interval, max_loops);
},
None => {
println!("No maximum loops specified, running forever. Press CTRL+C to exit at any time.");
run_unlimited(term, running, log_interval);
}
}
}
//Runs upto X times
fn run_limited(term: Term, running: Arc<AtomicBool>, log_interval: Option<u64>, max_loops: u64) {
let now = Instant::now();
let mut total_count: u64 = 0;
let mut count: u64;
let mut sum: f64;
//Print header only if showing progress
if log_interval.is_some() {
println!("Iteration\tValue \t% Err\tCurrent %\tTime Elapsed");
}
for i in 0..max_loops {
count = 0;
sum = 0.0;
//Run until sum hits 1.0
while sum <= 1.0 {
count += 1;
sum += rand::thread_rng().gen::<f64>();
}
total_count += count;
//Prints progress:
if log_interval.is_some() && i % log_interval.unwrap() == 0 {
let average = total_count as f64 / i as f64;
let pererror = (average - consts::E).abs() / consts::E * 100.0;
let cur_percent = i as f64 / max_loops as f64 * 100.0;
term.write_line(&format!(" {:9.10}\t{:.10}\t{:5.2}%\t{:9.2}%\t{:?}", i, average, pererror, cur_percent, now.elapsed())).ok();
term.move_cursor_up(1).ok();
}
//Checks if CTRL+C was called, end loop here
if !running.load(Ordering::SeqCst) {
break;
}
}
let average = total_count as f64 / max_loops as f64;
let pererror = (average - consts::E).abs() / consts::E * 100.0;
println!("---------------------------");
println!("Iterations: {}", max_loops);
println!("Final Average: {}", average);
println!("Final % Error: {:.4}%", pererror);
println!("Took: {:?}", now.elapsed());
}
fn run_unlimited(term: Term, running: Arc<AtomicBool>, log_interval: Option<u64>) {
let now = Instant::now();
let mut total_count: u64 = 0;
let mut count: u64;
let mut sum: f64;
let mut i: u64 = 0;
if log_interval.is_some() {
println!("Iteration\tValue \t% Err\tTime Elapsed");
}
loop {
count = 0;
sum = 0.0;
//Run until sum hits 1.0
while sum <= 1.0 {
count += 1;
sum += rand::thread_rng().gen::<f64>();
}
total_count += count;
//Prints progress:
if log_interval.is_some() && i % log_interval.unwrap() == 0 {
let average = total_count as f64 / i as f64;
let pererror = (average - consts::E).abs() / consts::E * 100.0;
term.write_line(&format!(" {:9.10}\t{:.10}\t{:5.2}%\t{:?}", i, average, pererror, now.elapsed())).ok();
term.move_cursor_up(1).ok();
}
//Checks if CTRL+C was called, end loop here
if !running.load(Ordering::SeqCst) {
break;
}
i += 1;
}
let average = total_count as f64 / i as f64;
let pererror = (average - consts::E).abs() / consts::E * 100.0;
println!("---------------------------");
println!("Iterations: {}", i);
println!("Final Average: {}", average);
println!("Final % Error: {:.4}%", pererror);
println!("Took: {:?}", now.elapsed());
}
1 | use std::time::Instant; |
2 | use rand::prelude::*; |
3 | use std::f64::consts; |
4 | use console::Term; |
5 | use std::sync::atomic::{AtomicBool, Ordering}; |
6 | use std::sync::Arc; |
7 | |
8 | fn main() { |
9 | //Handler to terminate on CTRL+C |
10 | let running = Arc::new(AtomicBool::new(true)); |
11 | let r = running.clone(); |
12 | ctrlc::set_handler(move || { |
13 | r.store(false, Ordering::SeqCst); |
14 | println!(); |
15 | }).expect("Error setting Ctrl-C handler"); |
16 | |
17 | let term = Term::stdout(); |
18 | |
19 | //Parses env 'SHOW_PROGRESS', value must be an int and sets how frequent to log progress |
20 | //If has a value, should log progress. |
21 | let log_interval: Option<u64> = match std::env::var("SHOW_PROGRESS").ok() { |
22 | Some(value) => Some(value.parse::<u64>().expect("not a valid integer")), |
23 | None => None |
24 | }; |
25 | |
26 | //Gets the maximum loops to run or none for infinity |
27 | let max_loops: Option<u64> = match std::env::var("LOOPS") { |
28 | Ok(val) => Some(val.parse::<u64>().expect("not a valid integer")), |
29 | _ => None |
30 | }; |
31 | |
32 | match max_loops { |
33 | Some(max_loops) => { |
34 | println!("Running {} iterations. Press CTRL+C to exit at any time.", max_loops); |
35 | run_limited(term, running, log_interval, max_loops); |
36 | }, |
37 | None => { |
38 | println!("No maximum loops specified, running forever. Press CTRL+C to exit at any time."); |
39 | run_unlimited(term, running, log_interval); |
40 | } |
41 | } |
42 | } |
43 | |
44 | //Runs upto X times |
45 | fn run_limited(term: Term, running: Arc<AtomicBool>, log_interval: Option<u64>, max_loops: u64) { |
46 | let now = Instant::now(); |
47 | |
48 | let mut total_count: u64 = 0; |
49 | let mut count: u64; |
50 | let mut sum: f64; |
51 | |
52 | //Print header only if showing progress |
53 | if log_interval.is_some() { |
54 | println!("Iteration\tValue \t% Err\tCurrent %\tTime Elapsed"); |
55 | } |
56 | |
57 | for i in 0..max_loops { |
58 | count = 0; |
59 | sum = 0.0; |
60 | //Run until sum hits 1.0 |
61 | while sum <= 1.0 { |
62 | count += 1; |
63 | sum += rand::thread_rng().gen::<f64>(); |
64 | } |
65 | |
66 | total_count += count; |
67 | |
68 | //Prints progress: |
69 | if log_interval.is_some() && i % log_interval.unwrap() == 0 { |
70 | let average = total_count as f64 / i as f64; |
71 | let pererror = (average - consts::E).abs() / consts::E * 100.0; |
72 | let cur_percent = i as f64 / max_loops as f64 * 100.0; |
73 | term.write_line(&format!(" {:9.10}\t{:.10}\t{:5.2}%\t{:9.2}%\t{:?}", i, average, pererror, cur_percent, now.elapsed())).ok(); |
74 | term.move_cursor_up(1).ok(); |
75 | } |
76 | |
77 | //Checks if CTRL+C was called, end loop here |
78 | if !running.load(Ordering::SeqCst) { |
79 | break; |
80 | } |
81 | } |
82 | |
83 | let average = total_count as f64 / max_loops as f64; |
84 | let pererror = (average - consts::E).abs() / consts::E * 100.0; |
85 | println!("---------------------------"); |
86 | println!("Iterations: {}", max_loops); |
87 | println!("Final Average: {}", average); |
88 | println!("Final % Error: {:.4}%", pererror); |
89 | println!("Took: {:?}", now.elapsed()); |
90 | } |
91 | |
92 | fn run_unlimited(term: Term, running: Arc<AtomicBool>, log_interval: Option<u64>) { |
93 | let now = Instant::now(); |
94 | let mut total_count: u64 = 0; |
95 | let mut count: u64; |
96 | let mut sum: f64; |
97 | let mut i: u64 = 0; |
98 | |
99 | if log_interval.is_some() { |
100 | println!("Iteration\tValue \t% Err\tTime Elapsed"); |
101 | } |
102 | |
103 | loop { |
104 | count = 0; |
105 | sum = 0.0; |
106 | //Run until sum hits 1.0 |
107 | while sum <= 1.0 { |
108 | count += 1; |
109 | sum += rand::thread_rng().gen::<f64>(); |
110 | } |
111 | |
112 | total_count += count; |
113 | |
114 | //Prints progress: |
115 | if log_interval.is_some() && i % log_interval.unwrap() == 0 { |
116 | let average = total_count as f64 / i as f64; |
117 | let pererror = (average - consts::E).abs() / consts::E * 100.0; |
118 | term.write_line(&format!(" {:9.10}\t{:.10}\t{:5.2}%\t{:?}", i, average, pererror, now.elapsed())).ok(); |
119 | term.move_cursor_up(1).ok(); |
120 | } |
121 | |
122 | //Checks if CTRL+C was called, end loop here |
123 | if !running.load(Ordering::SeqCst) { |
124 | break; |
125 | } |
126 | |
127 | i += 1; |
128 | } |
129 | |
130 | let average = total_count as f64 / i as f64; |
131 | let pererror = (average - consts::E).abs() / consts::E * 100.0; |
132 | println!("---------------------------"); |
133 | println!("Iterations: {}", i); |
134 | println!("Final Average: {}", average); |
135 | println!("Final % Error: {:.4}%", pererror); |
136 | println!("Took: {:?}", now.elapsed()); |
137 | } |