Greg Thompson commited on
Commit
9f30f34
1 Parent(s): cc67cbe

Added Jupyter notebook example

Browse files
docs/transitions_math_quiz_example.ipynb ADDED
@@ -0,0 +1,368 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 19,
6
+ "id": "d3da0422",
7
+ "metadata": {},
8
+ "outputs": [],
9
+ "source": [
10
+ "import random\n",
11
+ "\n",
12
+ "from transitions import State, Machine"
13
+ ]
14
+ },
15
+ {
16
+ "cell_type": "code",
17
+ "execution_count": 20,
18
+ "id": "07cfb740",
19
+ "metadata": {},
20
+ "outputs": [],
21
+ "source": [
22
+ "class MathQuizFSM(object):\n",
23
+ " states = [\n",
24
+ " 'quiz_start', \n",
25
+ " 'quiz_question', \n",
26
+ " 'quiz_end'\n",
27
+ " ]\n",
28
+ "\n",
29
+ " transitions = [\n",
30
+ " ['ask_second_question', 'quiz_start', 'quiz_question'],\n",
31
+ " ['ask_next_question', 'quiz_question', 'quiz_question'],\n",
32
+ " ['exit', 'quiz_start', 'quiz_end'],\n",
33
+ " ['exit', 'quiz_question', 'quiz_end'],\n",
34
+ " ]\n",
35
+ " \n",
36
+ " \n",
37
+ " def __init__(self):\n",
38
+ " # Instantiate the FSM\n",
39
+ " self.machine = Machine(model=self, states=MathQuizFSM.states, transitions=MathQuizFSM.transitions,initial='quiz_start')\n",
40
+ "\n",
41
+ " # Instantiate variables necessary for tracking activity\n",
42
+ " self.question_nums = [2, 3]\n",
43
+ " self.correct_answer = 5\n",
44
+ " self.student_answer = 0\n",
45
+ " self.is_correct_answer = False\n",
46
+ " self.response_text = \"What is 2 + 3?\"\n",
47
+ "\n",
48
+ " # Define transitions\n",
49
+ "# self.machine.add_transition('ask_second_question', 'quiz_start', 'quiz_question')\n",
50
+ "# self.machine.add_transition('ask_next_question', 'quiz_question', 'quiz_question')\n",
51
+ "# self.machine.add_transition('exit', 'quiz_start', 'quiz_end')\n",
52
+ "# self.machine.add_transition('exit', 'quiz_question', 'quiz_end')\n",
53
+ "\n",
54
+ " # Define functions to run on transitions\n",
55
+ " self.machine.on_enter_quiz_question('generate_math_problem')\n",
56
+ " self.machine.on_exit_quiz_question('validate_answer')\n",
57
+ "\n",
58
+ " def validate_answer(self):\n",
59
+ " if self.student_answer == 'exit':\n",
60
+ " self.machine.set_state('quiz_end')\n",
61
+ " return [\"Come back any time!\"]\n",
62
+ " elif self.correct_answer == self.student_answer:\n",
63
+ " self.machine.set_state('quiz_question')\n",
64
+ " self.generate_math_problem()\n",
65
+ " return ['Great job!', self.response_text]\n",
66
+ " else:\n",
67
+ " return [\"That's not quite right. Try again.\",self.response_text]\n",
68
+ " \n",
69
+ " def generate_math_problem(self):\n",
70
+ " self.question_nums = random.sample(range(1,100),2)\n",
71
+ " self.response_text = f\"What is {self.question_nums[0]} + {self.question_nums[1]}\"\n",
72
+ " self.correct_answer = self.question_nums[0] + self.question_nums[1]\n"
73
+ ]
74
+ },
75
+ {
76
+ "cell_type": "code",
77
+ "execution_count": 21,
78
+ "id": "ebdf92ae",
79
+ "metadata": {},
80
+ "outputs": [],
81
+ "source": [
82
+ "test = MathQuizFSM()"
83
+ ]
84
+ },
85
+ {
86
+ "cell_type": "code",
87
+ "execution_count": 22,
88
+ "id": "92024fcc",
89
+ "metadata": {},
90
+ "outputs": [
91
+ {
92
+ "data": {
93
+ "text/plain": [
94
+ "'quiz_start'"
95
+ ]
96
+ },
97
+ "execution_count": 22,
98
+ "metadata": {},
99
+ "output_type": "execute_result"
100
+ }
101
+ ],
102
+ "source": [
103
+ "# Set as `quiz_start` due to the initial setting in Line 10\n",
104
+ "test.state"
105
+ ]
106
+ },
107
+ {
108
+ "cell_type": "code",
109
+ "execution_count": 23,
110
+ "id": "fd1ba433",
111
+ "metadata": {},
112
+ "outputs": [
113
+ {
114
+ "data": {
115
+ "text/plain": [
116
+ "['quiz_start', 'quiz_question', 'quiz_end']"
117
+ ]
118
+ },
119
+ "execution_count": 23,
120
+ "metadata": {},
121
+ "output_type": "execute_result"
122
+ }
123
+ ],
124
+ "source": [
125
+ "# Available states for the quiz module\n",
126
+ "test.states"
127
+ ]
128
+ },
129
+ {
130
+ "cell_type": "code",
131
+ "execution_count": 24,
132
+ "id": "bb190089",
133
+ "metadata": {},
134
+ "outputs": [
135
+ {
136
+ "name": "stdout",
137
+ "output_type": "stream",
138
+ "text": [
139
+ "What is 2 + 3?\n",
140
+ "Initial Correct Answer: 5\n",
141
+ "Initial Student Answer: 0\n"
142
+ ]
143
+ }
144
+ ],
145
+ "source": [
146
+ "# When the FSM is created, it comes with a default question/answer pair loaded\n",
147
+ "print(test.response_text)\n",
148
+ "print(f\"Initial Correct Answer: {test.correct_answer}\")\n",
149
+ "print(f\"Initial Student Answer: {test.student_answer}\")"
150
+ ]
151
+ },
152
+ {
153
+ "cell_type": "code",
154
+ "execution_count": 25,
155
+ "id": "3de7c4e0",
156
+ "metadata": {},
157
+ "outputs": [
158
+ {
159
+ "data": {
160
+ "text/plain": [
161
+ "[\"That's not quite right. Try again.\", 'What is 2 + 3?']"
162
+ ]
163
+ },
164
+ "execution_count": 25,
165
+ "metadata": {},
166
+ "output_type": "execute_result"
167
+ }
168
+ ],
169
+ "source": [
170
+ "# Calling the validation fails because the answer is wrong. The state remains the same.\n",
171
+ "test.validate_answer()"
172
+ ]
173
+ },
174
+ {
175
+ "cell_type": "code",
176
+ "execution_count": 26,
177
+ "id": "4935b470",
178
+ "metadata": {},
179
+ "outputs": [],
180
+ "source": [
181
+ "# The student tries again\n",
182
+ "test.student_answer = 5"
183
+ ]
184
+ },
185
+ {
186
+ "cell_type": "code",
187
+ "execution_count": 27,
188
+ "id": "03722434",
189
+ "metadata": {},
190
+ "outputs": [
191
+ {
192
+ "data": {
193
+ "text/plain": [
194
+ "['Great job!', 'What is 58 + 89']"
195
+ ]
196
+ },
197
+ "execution_count": 27,
198
+ "metadata": {},
199
+ "output_type": "execute_result"
200
+ }
201
+ ],
202
+ "source": [
203
+ "# Since the student answered correctly, MathQuizFSM generates a new math problem\n",
204
+ "test.validate_answer()"
205
+ ]
206
+ },
207
+ {
208
+ "cell_type": "code",
209
+ "execution_count": 28,
210
+ "id": "d98a4d5b",
211
+ "metadata": {},
212
+ "outputs": [
213
+ {
214
+ "data": {
215
+ "text/plain": [
216
+ "'quiz_question'"
217
+ ]
218
+ },
219
+ "execution_count": 28,
220
+ "metadata": {},
221
+ "output_type": "execute_result"
222
+ }
223
+ ],
224
+ "source": [
225
+ "# It will repeatedly re-activate the same state\n",
226
+ "test.state"
227
+ ]
228
+ },
229
+ {
230
+ "cell_type": "code",
231
+ "execution_count": 29,
232
+ "id": "76c8a5b2",
233
+ "metadata": {},
234
+ "outputs": [
235
+ {
236
+ "data": {
237
+ "text/plain": [
238
+ "[\"That's not quite right. Try again.\", 'What is 58 + 89']"
239
+ ]
240
+ },
241
+ "execution_count": 29,
242
+ "metadata": {},
243
+ "output_type": "execute_result"
244
+ }
245
+ ],
246
+ "source": [
247
+ "test.validate_answer()"
248
+ ]
249
+ },
250
+ {
251
+ "cell_type": "code",
252
+ "execution_count": 30,
253
+ "id": "ec0a7e6a",
254
+ "metadata": {},
255
+ "outputs": [],
256
+ "source": [
257
+ "test.student_answer = 128"
258
+ ]
259
+ },
260
+ {
261
+ "cell_type": "code",
262
+ "execution_count": 31,
263
+ "id": "a093ff27",
264
+ "metadata": {},
265
+ "outputs": [
266
+ {
267
+ "data": {
268
+ "text/plain": [
269
+ "[\"That's not quite right. Try again.\", 'What is 58 + 89']"
270
+ ]
271
+ },
272
+ "execution_count": 31,
273
+ "metadata": {},
274
+ "output_type": "execute_result"
275
+ }
276
+ ],
277
+ "source": [
278
+ "test.validate_answer()"
279
+ ]
280
+ },
281
+ {
282
+ "cell_type": "code",
283
+ "execution_count": 32,
284
+ "id": "f992d34d",
285
+ "metadata": {},
286
+ "outputs": [],
287
+ "source": [
288
+ "test.student_answer = 'exit'"
289
+ ]
290
+ },
291
+ {
292
+ "cell_type": "code",
293
+ "execution_count": 33,
294
+ "id": "28800a2b",
295
+ "metadata": {},
296
+ "outputs": [
297
+ {
298
+ "data": {
299
+ "text/plain": [
300
+ "['Come back any time!']"
301
+ ]
302
+ },
303
+ "execution_count": 33,
304
+ "metadata": {},
305
+ "output_type": "execute_result"
306
+ }
307
+ ],
308
+ "source": [
309
+ "test.validate_answer()"
310
+ ]
311
+ },
312
+ {
313
+ "cell_type": "code",
314
+ "execution_count": 34,
315
+ "id": "360ef774",
316
+ "metadata": {},
317
+ "outputs": [
318
+ {
319
+ "data": {
320
+ "text/plain": [
321
+ "'quiz_end'"
322
+ ]
323
+ },
324
+ "execution_count": 34,
325
+ "metadata": {},
326
+ "output_type": "execute_result"
327
+ }
328
+ ],
329
+ "source": [
330
+ "test.state"
331
+ ]
332
+ },
333
+ {
334
+ "cell_type": "code",
335
+ "execution_count": null,
336
+ "id": "3f0392ae",
337
+ "metadata": {},
338
+ "outputs": [],
339
+ "source": []
340
+ }
341
+ ],
342
+ "metadata": {
343
+ "kernelspec": {
344
+ "display_name": "base",
345
+ "language": "python",
346
+ "name": "python3"
347
+ },
348
+ "language_info": {
349
+ "codemirror_mode": {
350
+ "name": "ipython",
351
+ "version": 3
352
+ },
353
+ "file_extension": ".py",
354
+ "mimetype": "text/x-python",
355
+ "name": "python",
356
+ "nbconvert_exporter": "python",
357
+ "pygments_lexer": "ipython3",
358
+ "version": "3.9.7"
359
+ },
360
+ "vscode": {
361
+ "interpreter": {
362
+ "hash": "32cf04bfac80a5e1e74e86fca42ae7f3079b15fa61041a60732bc19e88699268"
363
+ }
364
+ }
365
+ },
366
+ "nbformat": 4,
367
+ "nbformat_minor": 5
368
+ }