mc_exam_randomizer/
shuffler.rs1pub 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}