ssr_algorithms/super_memory_2/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use level::{Level, Quality};
use s_text_input_f::ParagraphItem;
use serde::{Deserialize, Serialize};
use ssr_core::task::{level::TaskLevel, Task};
use std::time::SystemTime;

mod level;

#[derive(Serialize, Deserialize)]
pub struct WriteAnswer {
    level: Level,
    input_blocks: s_text_input_f::Blocks,
    correct_answer: s_text_input_f::Response,
}

impl WriteAnswer {
    pub fn new(
        input_blocks: s_text_input_f::Blocks,
        correct_answer: s_text_input_f::Response,
    ) -> Self {
        Self {
            level: Default::default(),
            input_blocks,
            correct_answer,
        }
    }

    fn gen_feedback_form(
        &mut self,
        user_answer: Vec<Vec<String>>,
        directive: String,
        qualities_strings: Vec<String>,
    ) -> Vec<s_text_input_f::Block> {
        let mut feedback = s_text_input_f::to_answered(
            self.input_blocks.clone(),
            user_answer,
            self.correct_answer.clone(),
        );
        feedback.push(s_text_input_f::Block::Paragraph(vec![]));
        feedback.push(s_text_input_f::Block::Paragraph(vec![ParagraphItem::Text(
            directive,
        )]));
        feedback.push(s_text_input_f::Block::OneOf(qualities_strings));
        feedback
    }

    fn get_feedback(
        &mut self,
        user_answer: Vec<Vec<String>>,
        directive: String,
        qualities_strings: Vec<String>,
        interaction: &mut impl FnMut(
            Vec<s_text_input_f::Block>,
        ) -> Result<Vec<Vec<String>>, std::io::Error>,
        qualities: [Quality; 3],
    ) -> Result<Quality, std::io::Error> {
        let feedback = self.gen_feedback_form(user_answer, directive, qualities_strings);
        let user_feedback = interaction(feedback)?;
        let i = s_text_input_f::response_as_one_of(user_feedback.last().unwrap().to_owned())
            .unwrap()
            .unwrap();
        let quality = qualities[i];
        Ok(quality)
    }
}

impl Task<'_> for WriteAnswer {
    type SharedState = ();

    fn next_repetition(&self, retrievability_goal: f64) -> SystemTime {
        self.level.next_repetition(retrievability_goal)
    }

    fn complete(
        &mut self,
        _: &mut (),
        interaction: &mut impl FnMut(
            s_text_input_f::Blocks,
        ) -> std::io::Result<s_text_input_f::Response>,
    ) -> std::io::Result<()> {
        let user_answer = interaction(self.input_blocks.clone())?;
        match s_text_input_f::eq_response(&user_answer, &self.correct_answer, true, false) {
            false => {
                const QUALITIES: [Quality; 3] = [
                    Quality::CompleteBlackout,
                    Quality::IncorrectResponseButCorrectRemembered,
                    Quality::IncorrectResponseAndSeemedEasyToRecall,
                ];
                let qualities_strings = vec![
                    "complete blackout".to_string(),
                    "incorrect response, but correct remembered".to_string(),
                    "incorrect response, but seemed easy to recall".to_string(),
                ];
                let directive = "Choose difficulty:".to_string();

                let quality = self.get_feedback(
                    user_answer,
                    directive,
                    qualities_strings,
                    interaction,
                    QUALITIES,
                )?;

                self.level.update(&mut (), (SystemTime::now(), quality));
            }
            true => {
                const QUALITIES: [Quality; 3] = [
                    Quality::CorrectResponseRecalledWithSeriousDifficulty,
                    Quality::CorrectResponseAfterHesitation,
                    Quality::PerfectResponse,
                ];
                let qualities_strings = vec![
                    "recalled with serious difficulty".to_string(),
                    "correct, but after hesitation".to_string(),
                    "perfect response".to_string(),
                ];
                let directive = "All answers correct! Choose difficulty:".to_string();

                let quality = self.get_feedback(
                    user_answer,
                    directive,
                    qualities_strings,
                    interaction,
                    QUALITIES,
                )?;

                self.level.update(&mut (), (SystemTime::now(), quality));
            }
        }
        Ok(())
    }
}