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 | } |