|
1 | 1 | /// Module related to the ``create`` command. |
2 | 2 |
|
3 | | -use rand::seq::SliceRandom; |
4 | | -use std::io::{Read, Write}; |
| 3 | +use rand::distributions::Uniform; |
5 | 4 | use std::path::{Path, PathBuf}; |
| 5 | +use std::io::{Read, Write}; |
6 | 6 | use serde_json as sj; |
7 | | -use rand::thread_rng; |
| 7 | +use rand::{thread_rng, Rng}; |
8 | 8 | use clap::ValueEnum; |
9 | 9 | use std::fs::File; |
| 10 | +use std::time; |
10 | 11 | use std::env; |
11 | 12 |
|
12 | 13 | use crate::with_parent_path; |
@@ -101,17 +102,37 @@ pub fn command_create( |
101 | 102 | // Iterate sorted keys from largest grade to lowest, compare each parsed grade to the mean value of CSV grades |
102 | 103 | // and stop when we find the key that is lower or equal than the mean. |
103 | 104 | start_size = output_parts.len(); |
| 105 | + |
| 106 | + let epoch_ns; |
| 107 | + let responses; |
| 108 | + let response_idx; |
| 109 | + let response; |
| 110 | + let response_str; |
104 | 111 | for (sgrade, grade) in grades.iter() { |
105 | 112 | if (grade * 10000.0) as usize <= (mean * 10000.0) as usize { // Prevent influence of numeric error |
106 | 113 | 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)")); |
112 | 133 | 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) |
115 | 136 | ); |
116 | 137 | break; |
117 | 138 | } |
|
0 commit comments