{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "d3da0422",
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "\n",
    "from transitions import State, Machine"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "07cfb740",
   "metadata": {},
   "outputs": [],
   "source": [
    "class MathQuizFSM(object):\n",
    "    states = [\n",
    "        'quiz_start', \n",
    "        'quiz_question', \n",
    "        'quiz_end'\n",
    "    ]\n",
    "\n",
    "    transitions = [\n",
    "        ['ask_second_question', 'quiz_start', 'quiz_question'],\n",
    "        ['ask_next_question', 'quiz_question', 'quiz_question'],\n",
    "        ['exit', 'quiz_start', 'quiz_end'],\n",
    "        ['exit', 'quiz_question', 'quiz_end'],\n",
    "    ]\n",
    "    \n",
    "    \n",
    "    def __init__(self):\n",
    "        # Instantiate the FSM\n",
    "        self.machine = Machine(model=self, states=MathQuizFSM.states, transitions=MathQuizFSM.transitions,initial='quiz_start')\n",
    "\n",
    "        # Instantiate variables necessary for tracking activity\n",
    "        self.question_nums = [2, 3]\n",
    "        self.correct_answer = 5\n",
    "        self.student_answer = 0\n",
    "        self.is_correct_answer = False\n",
    "        self.response_text = \"What is 2 + 3?\"\n",
    "\n",
    "        # Define transitions\n",
    "#         self.machine.add_transition('ask_second_question', 'quiz_start', 'quiz_question')\n",
    "#         self.machine.add_transition('ask_next_question', 'quiz_question', 'quiz_question')\n",
    "#         self.machine.add_transition('exit', 'quiz_start', 'quiz_end')\n",
    "#         self.machine.add_transition('exit', 'quiz_question', 'quiz_end')\n",
    "\n",
    "        # Define functions to run on transitions\n",
    "        self.machine.on_enter_quiz_question('generate_math_problem')\n",
    "        self.machine.on_exit_quiz_question('validate_answer')\n",
    "\n",
    "    def validate_answer(self):\n",
    "        if self.student_answer == 'exit':\n",
    "            self.machine.set_state('quiz_end')\n",
    "            return [\"Come back any time!\"]\n",
    "        elif self.correct_answer == self.student_answer:\n",
    "            self.machine.set_state('quiz_question')\n",
    "            self.generate_math_problem()\n",
    "            return ['Great job!', self.response_text]\n",
    "        else:\n",
    "            return [\"That's not quite right.  Try again.\",self.response_text]\n",
    "    \n",
    "    def generate_math_problem(self):\n",
    "        self.question_nums = random.sample(range(1,100),2)\n",
    "        self.response_text = f\"What is {self.question_nums[0]} + {self.question_nums[1]}\"\n",
    "        self.correct_answer = self.question_nums[0] + self.question_nums[1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "ebdf92ae",
   "metadata": {},
   "outputs": [],
   "source": [
    "test = MathQuizFSM()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "92024fcc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'quiz_start'"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Set as `quiz_start` due to the initial setting in Line 10\n",
    "test.state"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "fd1ba433",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['quiz_start', 'quiz_question', 'quiz_end']"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Available states for the quiz module\n",
    "test.states"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "bb190089",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "What is 2 + 3?\n",
      "Initial Correct Answer: 5\n",
      "Initial Student Answer: 0\n"
     ]
    }
   ],
   "source": [
    "# When the FSM is created, it comes with a default question/answer pair loaded\n",
    "print(test.response_text)\n",
    "print(f\"Initial Correct Answer: {test.correct_answer}\")\n",
    "print(f\"Initial Student Answer: {test.student_answer}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "3de7c4e0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[\"That's not quite right.  Try again.\", 'What is 2 + 3?']"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Calling the validation fails because the answer is wrong.  The state remains the same.\n",
    "test.validate_answer()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "4935b470",
   "metadata": {},
   "outputs": [],
   "source": [
    "# The student tries again\n",
    "test.student_answer = 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "03722434",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Great job!', 'What is 58 + 89']"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Since the student answered correctly, MathQuizFSM generates a new math problem\n",
    "test.validate_answer()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "d98a4d5b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'quiz_question'"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# It will repeatedly re-activate the same state\n",
    "test.state"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "76c8a5b2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[\"That's not quite right.  Try again.\", 'What is 58 + 89']"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test.validate_answer()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "ec0a7e6a",
   "metadata": {},
   "outputs": [],
   "source": [
    "test.student_answer = 128"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "a093ff27",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[\"That's not quite right.  Try again.\", 'What is 58 + 89']"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test.validate_answer()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "f992d34d",
   "metadata": {},
   "outputs": [],
   "source": [
    "test.student_answer = 'exit'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "28800a2b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Come back any time!']"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test.validate_answer()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "360ef774",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'quiz_end'"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test.state"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3f0392ae",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  },
  "vscode": {
   "interpreter": {
    "hash": "32cf04bfac80a5e1e74e86fca42ae7f3079b15fa61041a60732bc19e88699268"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}