Skip to content

Commit 7396a9b

Browse files
committed
Improve randomness
1 parent f3d54bc commit 7396a9b

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed

src/create.rs

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
/// Module related to the ``create`` command.
22
3-
use rand::seq::SliceRandom;
4-
use std::io::{Read, Write};
3+
use rand::distributions::Uniform;
54
use std::path::{Path, PathBuf};
5+
use std::io::{Read, Write};
66
use serde_json as sj;
7-
use rand::thread_rng;
7+
use rand::{thread_rng, Rng};
88
use clap::ValueEnum;
99
use std::fs::File;
10+
use std::time;
1011
use std::env;
1112

1213
use crate::with_parent_path;
@@ -101,17 +102,37 @@ pub fn command_create(
101102
// Iterate sorted keys from largest grade to lowest, compare each parsed grade to the mean value of CSV grades
102103
// and stop when we find the key that is lower or equal than the mean.
103104
start_size = output_parts.len();
105+
106+
let epoch_ns;
107+
let responses;
108+
let response_idx;
109+
let response;
110+
let response_str;
104111
for (sgrade, grade) in grades.iter() {
105112
if (grade * 10000.0) as usize <= (mean * 10000.0) as usize { // Prevent influence of numeric error
106113
let v = grades_json.get(*sgrade).unwrap();
107-
let response = v.as_array()
108-
.expect(&format!("value of Category->Grade->Value must be an array of strings. Found {v:?}"))
109-
.choose(&mut rgn)
110-
.expect(&format!("there are no defined responses for grade {sgrade}, category {cat:?}"));
111-
let response = response.as_str().expect(&format!("responses must be strings ({response} is not)"));
114+
115+
// Query elapsed nanoseconds in order to improve randomness.
116+
epoch_ns = time::SystemTime::now()
117+
.duration_since(time::UNIX_EPOCH)
118+
.expect("SystemTime is before EPOCH!")
119+
.as_nanos();
120+
responses = v.as_array()
121+
.expect(&format!("value of Category->Grade->Value must be an array of strings. Found {v:?}"));
122+
123+
if responses.len() == 0 {
124+
panic!("there are no defined responses for grade {sgrade}, category {cat:?}");
125+
}
126+
127+
response_idx = (
128+
(epoch_ns % responses.len() as u128
129+
+ rgn.sample(Uniform::new(0, responses.len())) as u128) % responses.len() as u128
130+
) as usize;
131+
response = &responses[response_idx];
132+
response_str = response.as_str().expect(&format!("responses must be strings ({response} is not)"));
112133
output_parts.push(
113-
response.replace(C_OUTPUT_LATEX_MEAN_KEY, smean)
114-
.replace(C_OUTPUT_LATEX_STD_KEY, sstd)
134+
response_str.replace(C_OUTPUT_LATEX_MEAN_KEY, smean)
135+
.replace(C_OUTPUT_LATEX_STD_KEY, sstd)
115136
);
116137
break;
117138
}

0 commit comments

Comments
 (0)