mc_exam_randomizer/
shuffler.rs

1pub mod exam;
2pub mod question;
3pub mod setting;
4
5pub use exam::*;
6pub use question::*;
7use rand::seq::SliceRandom;
8use rand::thread_rng;
9pub use setting::*;
10
11pub fn shuffle_questions(qs: &Vec<Question>) -> Vec<&Question> {
12    let noq = qs.len() as u32;
13    let mut vec: Vec<u32> = (0..noq).collect();
14    vec.shuffle(&mut thread_rng());
15    let qs2: Vec<&Question> = vec
16        .iter()
17        .enumerate()
18        .map(|(_i, ord)| qs.get(*ord as usize).unwrap())
19        .collect();
20    qs2
21}
22
23pub fn shuffle_exam(ex: &Exam, name: Option<&str>) -> Exam {
24    let name = if let Some(nm) = name { nm } else { &ex.name };
25
26    if let Some(qs) = &ex.questions {
27        let qs_shuffled: Vec<Question> = qs.into_iter().map(|q| shuffle_choices(q)).collect();
28        let noq = qs.len() as u32;
29        let mut ordering: Vec<u32> = (0..noq).collect();
30        ordering.shuffle(&mut thread_rng());
31        Exam {
32            name: name.to_string(),
33            preamble: ex.preamble.to_owned(),
34            questions: Some(qs_shuffled),
35            ordering: Some(ordering),
36        }
37    } else {
38        Exam {
39            name: name.to_string(),
40            preamble: None,
41            questions: None,
42            ordering: None,
43        }
44    }
45}
46
47pub fn shuffle_choices(qs: &Question) -> Question {
48    if let Some(cs) = &qs.choices {
49        let Choices(vcs, CorrectChoice(crrct), _) = cs;
50        let nocs = vcs.len() as u32;
51        let mut ordering: Vec<u32> = (0..nocs).collect();
52        ordering.shuffle(&mut thread_rng());
53        let new_order = (&ordering)
54            .iter()
55            .position(|o| o == crrct)
56            .unwrap_or(*crrct as usize);
57        let choice_ordering = ChoiceOrdering(ordering.to_vec());
58        let new_choices = Choices(
59            vcs.to_vec(),
60            CorrectChoice(new_order as u32),
61            Some(choice_ordering),
62        );
63        Question {
64            text: (qs.text).to_string(),
65            order: qs.order,
66            choices: Some(new_choices),
67            group: qs.group,
68        }
69    } else {
70        qs.to_owned()
71    }
72}