Spaces:
Runtime error
Runtime error
Upload 14 files
Browse files- .dockerignore +5 -0
- Dockerfile +17 -0
- app.py +16 -0
- requirements.txt +3 -0
- response.py +215 -0
- routes/_init_.py +0 -0
- routes/chatbot_routes.py +196 -0
- static/tempor.css +109 -0
- templates/tempor.html +164 -0
- utils/__pycache__/openai_utils.cpython-310.pyc +0 -0
- utils/__pycache__/quiz_utils.cpython-310.pyc +0 -0
- utils/_init_.py +0 -0
- utils/openai_utils.py +52 -0
- utils/quiz_utils.py +67 -0
.dockerignore
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
__pycache__
|
| 2 |
+
*.pyc
|
| 3 |
+
*.pyo
|
| 4 |
+
.env
|
| 5 |
+
.git
|
Dockerfile
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Use an official Python runtime as the base image
|
| 2 |
+
FROM python:3.9-slim
|
| 3 |
+
|
| 4 |
+
# Set the working directory in the container
|
| 5 |
+
WORKDIR /app
|
| 6 |
+
|
| 7 |
+
# Copy all project files to the container
|
| 8 |
+
COPY . .
|
| 9 |
+
|
| 10 |
+
# Install Python dependencies
|
| 11 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
| 12 |
+
|
| 13 |
+
# Expose port 5000 for Flask
|
| 14 |
+
EXPOSE 5000
|
| 15 |
+
|
| 16 |
+
# Command to run the Flask app
|
| 17 |
+
CMD ["python", "app.py"]
|
app.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from flask import Flask, render_template
|
| 2 |
+
from routes.chatbot_routes import chatbot_routes
|
| 3 |
+
import os
|
| 4 |
+
|
| 5 |
+
# Explicitly set the templates folder
|
| 6 |
+
app = Flask(__name__, template_folder=os.path.join(os.getcwd(), "templates"))
|
| 7 |
+
|
| 8 |
+
# Register routes
|
| 9 |
+
app.register_blueprint(chatbot_routes)
|
| 10 |
+
|
| 11 |
+
@app.route("/")
|
| 12 |
+
def home():
|
| 13 |
+
return render_template("tempor.html")
|
| 14 |
+
|
| 15 |
+
if __name__ == "__main__":
|
| 16 |
+
app.run(debug=True)
|
requirements.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
open ai version=0.28.0
|
| 2 |
+
python-dotenv
|
| 3 |
+
flask
|
response.py
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Predefined responses
|
| 2 |
+
predefined_responses = {
|
| 3 |
+
"hi": "Hello! How can I assist you with Python today?",
|
| 4 |
+
"what is a variable": "A variable is a named reference to a value. Example:\n```python\nx = 5\nprint(x) # Output: 5\n```",
|
| 5 |
+
"path": (
|
| 6 |
+
"To learn Python step-by-step:\n"
|
| 7 |
+
"1. Install Python.\n"
|
| 8 |
+
"2. Learn basic syntax: variables, data types, and operators.\n"
|
| 9 |
+
"3. Practice control structures: loops and if-else statements.\n"
|
| 10 |
+
"4. Explore Python data structures.\n"
|
| 11 |
+
"5. Learn functions and error handling."
|
| 12 |
+
),
|
| 13 |
+
"indentation error example": (
|
| 14 |
+
"An IndentationError occurs when your code is not properly indented. Example:\n"
|
| 15 |
+
"```python\n"
|
| 16 |
+
"if True:\nprint('Hello') # IndentationError\n```\n"
|
| 17 |
+
"Correct it like this:\n"
|
| 18 |
+
"```python\n"
|
| 19 |
+
"if True:\n print('Hello')\n```"
|
| 20 |
+
),
|
| 21 |
+
"bubble sort example": (
|
| 22 |
+
"Bubble sort is a simple comparison-based sorting algorithm that works by repeatedly stepping through the list, comparing adjacent elements, and swapping them if they are in the wrong order.\n\n"
|
| 23 |
+
"Example:\n"
|
| 24 |
+
"```python\n"
|
| 25 |
+
"def bubble_sort(arr):\n"
|
| 26 |
+
" n = len(arr)\n"
|
| 27 |
+
" for i in range(n):\n"
|
| 28 |
+
" for j in range(0, n-i-1):\n"
|
| 29 |
+
" if arr[j] > arr[j+1]:\n"
|
| 30 |
+
" arr[j], arr[j+1] = arr[j+1], arr[j]\n"
|
| 31 |
+
" return arr\n\n"
|
| 32 |
+
"# Test the function\n"
|
| 33 |
+
"arr = [64, 34, 25, 12, 22, 11, 90]\n"
|
| 34 |
+
"print('Sorted array:', bubble_sort(arr))\n"
|
| 35 |
+
"```\n"
|
| 36 |
+
"This code implements bubble sort and sorts the array."
|
| 37 |
+
),
|
| 38 |
+
"count characters": (
|
| 39 |
+
"To count the characters in a word in Python, you can use the `len()` function. This function returns the length of a string, which is the number of characters it contains.\n\n"
|
| 40 |
+
"Example:\n"
|
| 41 |
+
"```python\n"
|
| 42 |
+
"word = 'Python'\n"
|
| 43 |
+
"char_count = len(word)\n"
|
| 44 |
+
"print(f'The word {word} has {char_count} characters.')\n"
|
| 45 |
+
"```\n"
|
| 46 |
+
"This code counts the characters in the word 'Python' and prints the result."
|
| 47 |
+
),
|
| 48 |
+
"product": (
|
| 49 |
+
"To find the product of two numbers in Python, you can use the multiplication operator (`*`).\n\n"
|
| 50 |
+
"Example:\n"
|
| 51 |
+
"```python\n"
|
| 52 |
+
"a = 5\n"
|
| 53 |
+
"b = 3\n"
|
| 54 |
+
"product = a * b\n"
|
| 55 |
+
"print(f'The product of {a} and {b} is {product}')\n"
|
| 56 |
+
"```\n"
|
| 57 |
+
"This code multiplies two numbers and prints the result."
|
| 58 |
+
),
|
| 59 |
+
"factorial": (
|
| 60 |
+
"To find the factorial of a number in Python, you can use a recursive function or a loop.\n\n"
|
| 61 |
+
"Example:\n"
|
| 62 |
+
"```python\n"
|
| 63 |
+
"def factorial(n):\n"
|
| 64 |
+
" if n == 0 or n == 1:\n"
|
| 65 |
+
" return 1\n"
|
| 66 |
+
" else:\n"
|
| 67 |
+
" return n * factorial(n-1)\n\n"
|
| 68 |
+
"# Test the function\n"
|
| 69 |
+
"num = 5\n"
|
| 70 |
+
"print(f'The factorial of {num} is {factorial(num)}')\n"
|
| 71 |
+
"```\n"
|
| 72 |
+
"This code calculates the factorial of a given number recursively."
|
| 73 |
+
),
|
| 74 |
+
"fibonacci": (
|
| 75 |
+
"To find the Fibonacci series in Python, you can use a loop or recursion.\n\n"
|
| 76 |
+
"Example:\n"
|
| 77 |
+
"```python\n"
|
| 78 |
+
"def fibonacci(n):\n"
|
| 79 |
+
" fib_sequence = [0, 1]\n"
|
| 80 |
+
" for i in range(2, n):\n"
|
| 81 |
+
" fib_sequence.append(fib_sequence[-1] + fib_sequence[-2])\n"
|
| 82 |
+
" return fib_sequence\n\n"
|
| 83 |
+
"# Test the function\n"
|
| 84 |
+
"num = 10\n"
|
| 85 |
+
"print(f'The first {num} Fibonacci numbers are: {fibonacci(num)}')\n"
|
| 86 |
+
"```\n"
|
| 87 |
+
"This code generates the first `n` numbers in the Fibonacci series."
|
| 88 |
+
),
|
| 89 |
+
"if-else": (
|
| 90 |
+
"The if-else statement is used for decision-making in Python. It allows the program to execute one block of code if a condition is true, and another block if it is false.\n\n"
|
| 91 |
+
"Example:\n"
|
| 92 |
+
"```python\n"
|
| 93 |
+
"num = 10\n"
|
| 94 |
+
"if num % 2 == 0:\n"
|
| 95 |
+
" print('Even number')\n"
|
| 96 |
+
"else:\n"
|
| 97 |
+
" print('Odd number')\n"
|
| 98 |
+
"```\n"
|
| 99 |
+
"This code checks if a number is even or odd and prints the result."
|
| 100 |
+
),
|
| 101 |
+
"if else": (
|
| 102 |
+
"The if-else statement is used for decision-making in Python. It allows the program to execute one block of code if a condition is true, and another block if it is false.\n\n"
|
| 103 |
+
"Example:\n"
|
| 104 |
+
"```python\n"
|
| 105 |
+
"num = 10\n"
|
| 106 |
+
"if num % 2 == 0:\n"
|
| 107 |
+
" print('Even number')\n"
|
| 108 |
+
"else:\n"
|
| 109 |
+
" print('Odd number')\n"
|
| 110 |
+
"```\n"
|
| 111 |
+
"This code checks if a number is even or odd and prints the result."
|
| 112 |
+
),
|
| 113 |
+
"what is shallow copy": (
|
| 114 |
+
"A shallow copy creates a new object but references the same nested objects as the original. Changes to nested objects in the copied object will affect the original.\n\n"
|
| 115 |
+
"Example:\n"
|
| 116 |
+
"```python\n"
|
| 117 |
+
"import copy\n"
|
| 118 |
+
"original = [[1, 2, 3], [4, 5, 6]]\n"
|
| 119 |
+
"shallow = copy.copy(original)\n"
|
| 120 |
+
"shallow[0][0] = 100\n"
|
| 121 |
+
"print('Original:', original) # Nested list is affected\n"
|
| 122 |
+
"print('Shallow:', shallow)\n"
|
| 123 |
+
"```\n"
|
| 124 |
+
"This code demonstrates how modifying a shallow copy affects the original object's nested elements."
|
| 125 |
+
),
|
| 126 |
+
"difference between deep and shallow copy": (
|
| 127 |
+
"In Python, a shallow copy creates a new object, but nested objects are shared between the copy and the original. "
|
| 128 |
+
"A deep copy creates a new object and recursively copies all nested objects, ensuring complete independence.\n\n"
|
| 129 |
+
"Example:\n"
|
| 130 |
+
"```python\n"
|
| 131 |
+
"import copy\n"
|
| 132 |
+
"original = [[1, 2], [3, 4]]\n"
|
| 133 |
+
"shallow = copy.copy(original)\n"
|
| 134 |
+
"deep = copy.deepcopy(original)\n"
|
| 135 |
+
"shallow[0][0] = 100 # Affects original\n"
|
| 136 |
+
"deep[0][0] = 200 # Does not affect original\n"
|
| 137 |
+
"```\n"
|
| 138 |
+
),
|
| 139 |
+
"python libraries": (
|
| 140 |
+
"Python libraries are collections of pre-written code that simplify tasks. Popular libraries include NumPy (numerical computing), Pandas (data analysis), "
|
| 141 |
+
"and Matplotlib (data visualization). Example:\n\n"
|
| 142 |
+
"```python\n"
|
| 143 |
+
"import pandas as pd\n"
|
| 144 |
+
"data = {'Name': ['Alice', 'Bob'], 'Age': [25, 30]}\n"
|
| 145 |
+
"df = pd.DataFrame(data)\n"
|
| 146 |
+
"print(df)\n"
|
| 147 |
+
"```\n"
|
| 148 |
+
"This creates and displays a simple data table using Pandas."
|
| 149 |
+
),
|
| 150 |
+
"can you provide a simple python code": (
|
| 151 |
+
"Sure! Here's a simple Python code to calculate the factorial of a number:\n\n"
|
| 152 |
+
"```python\n"
|
| 153 |
+
"def factorial(n):\n"
|
| 154 |
+
" if n == 0 or n == 1:\n"
|
| 155 |
+
" return 1\n"
|
| 156 |
+
" else:\n"
|
| 157 |
+
" return n * factorial(n-1)\n\n"
|
| 158 |
+
"# Test the function\n"
|
| 159 |
+
"num = 5\n"
|
| 160 |
+
"print(f'The factorial of {num} is {factorial(num)}')\n"
|
| 161 |
+
"```\n"
|
| 162 |
+
),
|
| 163 |
+
"explain ai": (
|
| 164 |
+
"Artificial Intelligence (AI) refers to the simulation of human intelligence by machines, allowing them to perform tasks like problem-solving, decision-making, and learning."
|
| 165 |
+
),
|
| 166 |
+
"datatypes examples": (
|
| 167 |
+
"Sure! In Python, data types are known as classes. Here are some common data types with examples:\n\n"
|
| 168 |
+
"- **Integer (`int`)**:\n"
|
| 169 |
+
" ```python\n"
|
| 170 |
+
" num = 10\n"
|
| 171 |
+
" print(type(num)) # Output: <class 'int'>\n"
|
| 172 |
+
" ```\n\n"
|
| 173 |
+
"- **String (`str`)**:\n"
|
| 174 |
+
" ```python\n"
|
| 175 |
+
" text = 'Hello, World!'\n"
|
| 176 |
+
" print(type(text)) # Output: <class 'str'>\n"
|
| 177 |
+
" ```\n\n"
|
| 178 |
+
"- **List (`list`)**:\n"
|
| 179 |
+
" ```python\n"
|
| 180 |
+
" items = [1, 2, 3]\n"
|
| 181 |
+
" print(type(items)) # Output: <class 'list'>\n"
|
| 182 |
+
" ```"
|
| 183 |
+
),
|
| 184 |
+
"for loop": (
|
| 185 |
+
"A `for` loop in Python is used to iterate over a sequence and execute a block of code for each item.\n\n"
|
| 186 |
+
"Example:\n"
|
| 187 |
+
"```python\n"
|
| 188 |
+
"fruits = ['apple', 'banana', 'cherry']\n"
|
| 189 |
+
"for fruit in fruits:\n"
|
| 190 |
+
" print(fruit)\n"
|
| 191 |
+
"```\n"
|
| 192 |
+
"This code prints each fruit from the list."
|
| 193 |
+
),
|
| 194 |
+
"add": (
|
| 195 |
+
"To add two numbers in Python, you can use the `+` operator.\n\n"
|
| 196 |
+
"Example:\n"
|
| 197 |
+
"```python\n"
|
| 198 |
+
"a = 5\n"
|
| 199 |
+
"b = 3\n"
|
| 200 |
+
"result = a + b\n"
|
| 201 |
+
"print(f'The sum of {a} and {b} is {result}')\n"
|
| 202 |
+
"```\n"
|
| 203 |
+
"This code adds two numbers and prints the result."
|
| 204 |
+
),
|
| 205 |
+
"how to read a string": (
|
| 206 |
+
"To read a string in Python, you can use the `input()` function. This function takes user input and returns it as a string.\n\n"
|
| 207 |
+
"Example:\n"
|
| 208 |
+
"```python\n"
|
| 209 |
+
"name = input('Enter your name: ')\n"
|
| 210 |
+
"print(f'Hello, {name}!')\n"
|
| 211 |
+
"```\n"
|
| 212 |
+
"This code asks the user to enter their name and then prints a greeting message."
|
| 213 |
+
)
|
| 214 |
+
|
| 215 |
+
}
|
routes/_init_.py
ADDED
|
File without changes
|
routes/chatbot_routes.py
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from flask import Blueprint, request, jsonify
|
| 2 |
+
import openai
|
| 3 |
+
import os
|
| 4 |
+
from dotenv import load_dotenv
|
| 5 |
+
from utils.quiz_utils import quiz_questions
|
| 6 |
+
from utils.openai_utils import query_dynamic_generation, format_code_block
|
| 7 |
+
from response import predefined_responses
|
| 8 |
+
|
| 9 |
+
# Load environment variables
|
| 10 |
+
load_dotenv()
|
| 11 |
+
|
| 12 |
+
# Initialize OpenAI API
|
| 13 |
+
openai_api_key = os.getenv("OPENAI_API_KEY")
|
| 14 |
+
if not openai_api_key:
|
| 15 |
+
raise ValueError("OPENAI_API_KEY environment variable is not set!")
|
| 16 |
+
|
| 17 |
+
openai.api_key = openai_api_key
|
| 18 |
+
|
| 19 |
+
# Define a Blueprint for chatbot routes
|
| 20 |
+
chatbot_routes = Blueprint("test_hugging_face", __name__)
|
| 21 |
+
|
| 22 |
+
# Maintain a history for context-aware responses
|
| 23 |
+
history = [
|
| 24 |
+
{"role": "system", "content": "You are a Python programming tutor and assistant."}
|
| 25 |
+
]
|
| 26 |
+
|
| 27 |
+
quiz_state = {} # Initialize quiz state
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
def add_to_history(role, content):
|
| 32 |
+
history.append({"role": role, "content": content})
|
| 33 |
+
if len(history) > 5: # Limit to the last 5 exchanges
|
| 34 |
+
history.pop(1)
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
@chatbot_routes.route("/get_response", methods=["POST"])
|
| 38 |
+
def get_response():
|
| 39 |
+
user_input = request.json.get("user_input", "").strip()
|
| 40 |
+
|
| 41 |
+
if not user_input:
|
| 42 |
+
return jsonify({"reply": "Please provide a valid input."})
|
| 43 |
+
|
| 44 |
+
# Normalize user input
|
| 45 |
+
user_input_normalized = user_input.lower()
|
| 46 |
+
|
| 47 |
+
# Check if the input explicitly asks for an explanation or dynamic query
|
| 48 |
+
if "explain" in user_input_normalized or "describe" or "what" in user_input_normalized:
|
| 49 |
+
try:
|
| 50 |
+
# Handle dynamic query generation for explanations
|
| 51 |
+
add_to_history("user", user_input)
|
| 52 |
+
chatbot_reply = query_dynamic_generation(user_input)
|
| 53 |
+
add_to_history("assistant", chatbot_reply)
|
| 54 |
+
chatbot_reply = format_code_block(chatbot_reply)
|
| 55 |
+
return jsonify({"reply": chatbot_reply})
|
| 56 |
+
except Exception as e:
|
| 57 |
+
return jsonify({"reply": f"Error: {str(e)}"})
|
| 58 |
+
|
| 59 |
+
# Check predefined responses for exact match (if no explanation keyword is found)
|
| 60 |
+
if user_input_normalized in predefined_responses:
|
| 61 |
+
chatbot_reply = predefined_responses[user_input_normalized]
|
| 62 |
+
chatbot_reply = format_code_block(chatbot_reply)
|
| 63 |
+
return jsonify({"reply": chatbot_reply})
|
| 64 |
+
|
| 65 |
+
# Extract keywords for predefined responses
|
| 66 |
+
keyword = extract_keywords(user_input_normalized)
|
| 67 |
+
|
| 68 |
+
if keyword and keyword in predefined_responses:
|
| 69 |
+
chatbot_reply = predefined_responses[keyword]
|
| 70 |
+
chatbot_reply = format_code_block(chatbot_reply)
|
| 71 |
+
return jsonify({"reply": chatbot_reply})
|
| 72 |
+
|
| 73 |
+
# Fallback to dynamic query generation if no match is found
|
| 74 |
+
try:
|
| 75 |
+
add_to_history("user", user_input)
|
| 76 |
+
chatbot_reply = query_dynamic_generation(user_input)
|
| 77 |
+
add_to_history("assistant", chatbot_reply)
|
| 78 |
+
chatbot_reply = format_code_block(chatbot_reply)
|
| 79 |
+
return jsonify({"reply": chatbot_reply})
|
| 80 |
+
except Exception as e:
|
| 81 |
+
return jsonify({"reply": f"Error: {str(e)}"})
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
@chatbot_routes.route("/clear_history", methods=["POST"])
|
| 86 |
+
def clear_history():
|
| 87 |
+
"""
|
| 88 |
+
Clears the conversation history and resets quiz state.
|
| 89 |
+
"""
|
| 90 |
+
global history
|
| 91 |
+
history = [
|
| 92 |
+
{"role": "system", "content": "You are a Python programming tutor and assistant."}
|
| 93 |
+
]
|
| 94 |
+
quiz_state.clear() # Clear quiz state if any
|
| 95 |
+
return jsonify({"reply": "Chat history cleared!"})
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
# Route: Start Quiz
|
| 99 |
+
@chatbot_routes.route("/start_quiz", methods=["POST"])
|
| 100 |
+
def start_quiz():
|
| 101 |
+
"""
|
| 102 |
+
Initializes or resets the quiz for the user based on the selected difficulty level.
|
| 103 |
+
"""
|
| 104 |
+
user_id = request.json.get("user_id", "default")
|
| 105 |
+
level = request.json.get("level", "beginner") # Default to beginner level
|
| 106 |
+
|
| 107 |
+
# Reset quiz state if level changes or new quiz is started
|
| 108 |
+
if user_id not in quiz_state or quiz_state[user_id].get("level") != level:
|
| 109 |
+
quiz_state[user_id] = {
|
| 110 |
+
"current": 0,
|
| 111 |
+
"level": level,
|
| 112 |
+
"questions": quiz_questions.get(level, [])
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
state = quiz_state[user_id]
|
| 116 |
+
|
| 117 |
+
# Check if there are more questions available
|
| 118 |
+
if state["current"] < len(state["questions"]):
|
| 119 |
+
current_question = state["questions"][state["current"]]
|
| 120 |
+
return jsonify({"question": current_question["question"], "options": current_question["options"]})
|
| 121 |
+
return jsonify({"reply": "Quiz finished! Great job!"})
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
# Route: Submit Answer
|
| 125 |
+
@chatbot_routes.route("/submit_answer", methods=["POST"])
|
| 126 |
+
def submit_answer():
|
| 127 |
+
"""
|
| 128 |
+
Handles the user's answer and returns the next question or completion message.
|
| 129 |
+
"""
|
| 130 |
+
user_id = request.json.get("user_id", "default")
|
| 131 |
+
answer = request.json.get("answer", "").strip()
|
| 132 |
+
state = quiz_state.get(user_id, {})
|
| 133 |
+
|
| 134 |
+
if not state:
|
| 135 |
+
return jsonify({"reply": "No active quiz found. Start a quiz first."})
|
| 136 |
+
|
| 137 |
+
current_index = state.get("current", 0)
|
| 138 |
+
questions = state.get("questions", [])
|
| 139 |
+
|
| 140 |
+
if current_index >= len(questions):
|
| 141 |
+
return jsonify({"reply": "You have completed the quiz! Great job!"})
|
| 142 |
+
|
| 143 |
+
correct_answer = questions[current_index]["answer"].strip()
|
| 144 |
+
|
| 145 |
+
state["current"] += 1 # Move to the next question
|
| 146 |
+
|
| 147 |
+
if answer.lower() == correct_answer.lower():
|
| 148 |
+
if state["current"] < len(questions):
|
| 149 |
+
next_question = questions[state["current"]]
|
| 150 |
+
return jsonify({
|
| 151 |
+
"reply": f"Correct! Here's your next question: ",
|
| 152 |
+
"next_question": next_question["question"],
|
| 153 |
+
"options": next_question["options"]
|
| 154 |
+
})
|
| 155 |
+
else:
|
| 156 |
+
return jsonify({"reply": "Correct! You have completed the quiz! Great job!"})
|
| 157 |
+
else:
|
| 158 |
+
if state["current"] < len(questions):
|
| 159 |
+
next_question = questions[state["current"]]
|
| 160 |
+
return jsonify({
|
| 161 |
+
"reply": f"Incorrect! The correct answer was: {correct_answer}.",
|
| 162 |
+
"next_question": next_question["question"],
|
| 163 |
+
"options": next_question["options"]
|
| 164 |
+
})
|
| 165 |
+
else:
|
| 166 |
+
return jsonify({"reply": f"Incorrect! The correct answer was: {correct_answer}. You have completed the quiz!"})
|
| 167 |
+
|
| 168 |
+
|
| 169 |
+
@chatbot_routes.route("/debug_quiz_state", methods=["GET"])
|
| 170 |
+
def debug_quiz_state():
|
| 171 |
+
return jsonify(quiz_state)
|
| 172 |
+
|
| 173 |
+
|
| 174 |
+
def normalize_answer(answer):
|
| 175 |
+
"""
|
| 176 |
+
Normalize the answer for case-insensitive and whitespace-insensitive matching.
|
| 177 |
+
"""
|
| 178 |
+
import re
|
| 179 |
+
# Remove extra spaces and make case-insensitive
|
| 180 |
+
return re.sub(r"\s+", " ", answer.strip().lower())
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
def extract_keywords(user_input):
|
| 184 |
+
"""
|
| 185 |
+
Extract keywords from user input to match predefined responses.
|
| 186 |
+
"""
|
| 187 |
+
user_input_normalized = user_input.lower().strip()
|
| 188 |
+
keywords = ["product", "fibonacci", "count characters", "add", "factorial", "if-else", "if else", "bubble sort example", "indentation error example", "path", "quiz"]
|
| 189 |
+
for keyword in keywords:
|
| 190 |
+
if keyword in user_input_normalized:
|
| 191 |
+
return keyword
|
| 192 |
+
return None
|
| 193 |
+
|
| 194 |
+
|
| 195 |
+
|
| 196 |
+
|
static/tempor.css
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* General Styles */
|
| 2 |
+
body {
|
| 3 |
+
font-family: 'Roboto', sans-serif;
|
| 4 |
+
margin: 0;
|
| 5 |
+
padding: 0;
|
| 6 |
+
background-color: #f4f4f9;
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
h1, h2 {
|
| 10 |
+
color: #0056b3;
|
| 11 |
+
text-align: center;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
#main-container {
|
| 15 |
+
max-width: 1200px;
|
| 16 |
+
margin: 20px auto;
|
| 17 |
+
padding: 20px;
|
| 18 |
+
background: #ffffff;
|
| 19 |
+
border-radius: 15px;
|
| 20 |
+
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.2);
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
#content-container {
|
| 24 |
+
display: flex;
|
| 25 |
+
gap: 20px;
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
#chat-section, #quiz-section {
|
| 29 |
+
flex: 1;
|
| 30 |
+
background: #f9f9f9;
|
| 31 |
+
border: 1px solid #ddd;
|
| 32 |
+
border-radius: 10px;
|
| 33 |
+
padding: 20px;
|
| 34 |
+
box-shadow: 0px 3px 10px rgba(0, 0, 0, 0.1);
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
#response-box, #quiz-box {
|
| 38 |
+
margin-top: 15px;
|
| 39 |
+
padding: 15px;
|
| 40 |
+
background: #f1f1f1;
|
| 41 |
+
border-radius: 5px;
|
| 42 |
+
border: 1px solid #ddd;
|
| 43 |
+
height: 300px;
|
| 44 |
+
overflow-y: auto;
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
.quiz-option {
|
| 48 |
+
margin: 10px 0;
|
| 49 |
+
display: flex;
|
| 50 |
+
align-items: center;
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
.quiz-option input {
|
| 54 |
+
margin-right: 10px;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
.quiz-feedback {
|
| 58 |
+
color: green;
|
| 59 |
+
font-weight: bold;
|
| 60 |
+
margin: 10px 0;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
.quiz-end {
|
| 64 |
+
color: #0056b3;
|
| 65 |
+
font-weight: bold;
|
| 66 |
+
margin: 10px 0;
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
button {
|
| 70 |
+
background-color: #0056b3;
|
| 71 |
+
color: white;
|
| 72 |
+
border: none;
|
| 73 |
+
border-radius: 5px;
|
| 74 |
+
padding: 5px 10px;
|
| 75 |
+
font-size:14px
|
| 76 |
+
cursor: pointer;
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
button:hover {
|
| 80 |
+
background-color: #003d80;
|
| 81 |
+
}
|
| 82 |
+
.btn-primary {
|
| 83 |
+
padding: 5px 10px;
|
| 84 |
+
font-size: 14px;
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
.btn-danger {
|
| 88 |
+
padding: 5px 10px;
|
| 89 |
+
font-size: 14px;
|
| 90 |
+
background-color: red;
|
| 91 |
+
}
|
| 92 |
+
input, select {
|
| 93 |
+
padding: 8px;
|
| 94 |
+
margin: 5px 0;
|
| 95 |
+
border: 1px solid #ddd;
|
| 96 |
+
border-radius: 5px;
|
| 97 |
+
width: 100%;
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
#clear-history-btn {
|
| 102 |
+
display: block;
|
| 103 |
+
margin: 10px auto; /* Center align */
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
#chat-form {
|
| 107 |
+
display: flex;
|
| 108 |
+
gap: 10px;
|
| 109 |
+
}
|
templates/tempor.html
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Interactive Python Chatbot</title>
|
| 7 |
+
<link rel="stylesheet" type="text/css" href="/static/temper.css">
|
| 8 |
+
<script>
|
| 9 |
+
async function sendMessage(event) {
|
| 10 |
+
event.preventDefault();
|
| 11 |
+
const userInput = document.getElementById("user_input").value.trim();
|
| 12 |
+
if (!userInput) {
|
| 13 |
+
alert("Please enter a valid message.");
|
| 14 |
+
return;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
const responseBox = document.getElementById("response-box");
|
| 18 |
+
responseBox.innerHTML += `<p><strong>User:</strong> ${userInput}</p>`;
|
| 19 |
+
|
| 20 |
+
try {
|
| 21 |
+
const response = await fetch("/get_response", {
|
| 22 |
+
method: "POST",
|
| 23 |
+
headers: { "Content-Type": "application/json" },
|
| 24 |
+
body: JSON.stringify({ user_input: userInput }),
|
| 25 |
+
});
|
| 26 |
+
|
| 27 |
+
const data = await response.json();
|
| 28 |
+
responseBox.innerHTML += `<p><strong>Chatbot:</strong> ${data.reply}</p>`;
|
| 29 |
+
document.getElementById("user_input").value = "";
|
| 30 |
+
} catch (error) {
|
| 31 |
+
alert("Error: Unable to send the message.");
|
| 32 |
+
}
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
async function startQuiz() {
|
| 36 |
+
const difficulty = document.getElementById("difficulty").value;
|
| 37 |
+
|
| 38 |
+
try {
|
| 39 |
+
const response = await fetch("/start_quiz", {
|
| 40 |
+
method: "POST",
|
| 41 |
+
headers: { "Content-Type": "application/json" },
|
| 42 |
+
body: JSON.stringify({ user_id: "default", level: difficulty }),
|
| 43 |
+
});
|
| 44 |
+
|
| 45 |
+
const data = await response.json();
|
| 46 |
+
const quizBox = document.getElementById("quiz-box");
|
| 47 |
+
|
| 48 |
+
if (data.question && data.options) {
|
| 49 |
+
quizBox.innerHTML = `
|
| 50 |
+
<p class="quiz-question"><strong>Question:</strong> ${data.question}</p>
|
| 51 |
+
<form id="quiz-form">
|
| 52 |
+
${data.options.map((option, index) => `
|
| 53 |
+
<div class="quiz-option">
|
| 54 |
+
<input type="radio" id="option${index}" name="answer" value="${option.split('. ')[0]}">
|
| 55 |
+
<label for="option${index}">${option}</label>
|
| 56 |
+
</div>
|
| 57 |
+
`).join('')}
|
| 58 |
+
|
| 59 |
+
</form>
|
| 60 |
+
|
| 61 |
+
<button type="button" class="btn btn-primary" onclick="submitAnswer()">Submit Answer</button>
|
| 62 |
+
`;
|
| 63 |
+
} else {
|
| 64 |
+
quizBox.innerHTML = `<p class="quiz-end">Quiz finished! Great job!</p>`;
|
| 65 |
+
}
|
| 66 |
+
} catch (error) {
|
| 67 |
+
alert("Error: Unable to start the quiz.");
|
| 68 |
+
}
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
async function submitAnswer() {
|
| 72 |
+
const form = document.getElementById("quiz-form");
|
| 73 |
+
const answer = form.querySelector('input[name="answer"]:checked')?.value;
|
| 74 |
+
|
| 75 |
+
if (!answer) {
|
| 76 |
+
alert("Please select an answer.");
|
| 77 |
+
return;
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
try {
|
| 81 |
+
const response = await fetch("/submit_answer", {
|
| 82 |
+
method: "POST",
|
| 83 |
+
headers: { "Content-Type": "application/json" },
|
| 84 |
+
body: JSON.stringify({ answer, user_id: "default" }),
|
| 85 |
+
});
|
| 86 |
+
|
| 87 |
+
const data = await response.json();
|
| 88 |
+
const quizBox = document.getElementById("quiz-box");
|
| 89 |
+
|
| 90 |
+
// Display feedback for the answer
|
| 91 |
+
quizBox.innerHTML = `<p class="quiz-feedback">${data.reply}</p>`;
|
| 92 |
+
|
| 93 |
+
// Check if there's a next question
|
| 94 |
+
if (data.next_question && data.options) {
|
| 95 |
+
quizBox.innerHTML += `
|
| 96 |
+
<p class="quiz-question"><strong>Next Question:</strong> ${data.next_question}</p>
|
| 97 |
+
<form id="quiz-form">
|
| 98 |
+
${data.options.map((option, index) => `
|
| 99 |
+
<div class="quiz-option">
|
| 100 |
+
<input type="radio" id="option${index}" name="answer" value="${option.split('. ')[0]}">
|
| 101 |
+
<label for="option${index}">${option}</label>
|
| 102 |
+
</div>
|
| 103 |
+
`).join('')}
|
| 104 |
+
<button type="button" class="btn btn-primary" onclick="submitAnswer()">Submit Answer</button>
|
| 105 |
+
</form>
|
| 106 |
+
`;
|
| 107 |
+
} else {
|
| 108 |
+
quizBox.innerHTML += `<p class="quiz-end">Quiz Completed! Great job!</p>`;
|
| 109 |
+
}
|
| 110 |
+
} catch (error) {
|
| 111 |
+
alert("Error: Unable to submit the answer.");
|
| 112 |
+
}
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
async function clearHistory() {
|
| 116 |
+
try {
|
| 117 |
+
const response = await fetch("/clear_history", { method: "POST" });
|
| 118 |
+
const data = await response.json();
|
| 119 |
+
document.getElementById("response-box").innerHTML = "";
|
| 120 |
+
document.getElementById("quiz-box").innerHTML = "";
|
| 121 |
+
alert(data.reply || "Chat history cleared!");
|
| 122 |
+
} catch (error) {
|
| 123 |
+
alert("Error: Unable to clear history.");
|
| 124 |
+
}
|
| 125 |
+
}
|
| 126 |
+
</script>
|
| 127 |
+
</head>
|
| 128 |
+
<body>
|
| 129 |
+
<div id="main-container">
|
| 130 |
+
<div id="header">
|
| 131 |
+
<h1>Interactive Python Chatbot</h1>
|
| 132 |
+
</div>
|
| 133 |
+
<div id="content-container">
|
| 134 |
+
<!-- Chatbot Section -->
|
| 135 |
+
<div id="chat-section">
|
| 136 |
+
<h2>Chatbot</h2>
|
| 137 |
+
<div id="response-box"></div>
|
| 138 |
+
<form id="chat-form" onsubmit="sendMessage(event)">
|
| 139 |
+
<input type="text" id="user_input" placeholder="Type your message..." required>
|
| 140 |
+
<button type="submit">Send</button>
|
| 141 |
+
</form>
|
| 142 |
+
<button class="clear-history-btn" onclick="clearHistory()">Clear History</button>
|
| 143 |
+
|
| 144 |
+
</div>
|
| 145 |
+
|
| 146 |
+
<!-- Quiz Section -->
|
| 147 |
+
<div id="quiz-section">
|
| 148 |
+
<h2>Quiz</h2>
|
| 149 |
+
<div>
|
| 150 |
+
<label for="difficulty">Select Difficulty:</label>
|
| 151 |
+
<select id="difficulty">
|
| 152 |
+
<option value="beginner">Beginner</option>
|
| 153 |
+
<option value="intermediate">Intermediate</option>
|
| 154 |
+
<option value="advanced">Advanced</option>
|
| 155 |
+
</select>
|
| 156 |
+
<button class="btn btn-primary" onclick="startQuiz()">Start Quiz</button>
|
| 157 |
+
</div>
|
| 158 |
+
<div id="quiz-box"></div>
|
| 159 |
+
</div>
|
| 160 |
+
</div>
|
| 161 |
+
</div>
|
| 162 |
+
</body>
|
| 163 |
+
</html>
|
| 164 |
+
|
utils/__pycache__/openai_utils.cpython-310.pyc
ADDED
|
Binary file (1.91 kB). View file
|
|
|
utils/__pycache__/quiz_utils.cpython-310.pyc
ADDED
|
Binary file (2.8 kB). View file
|
|
|
utils/_init_.py
ADDED
|
File without changes
|
utils/openai_utils.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import openai
|
| 2 |
+
history = [
|
| 3 |
+
{"role": "system", "content": "You are a Python programming tutor and assistant."}
|
| 4 |
+
]
|
| 5 |
+
|
| 6 |
+
def query_dynamic_generation(user_input):
|
| 7 |
+
"""
|
| 8 |
+
Adjusts response verbosity based on query type.
|
| 9 |
+
"""
|
| 10 |
+
# Check for keywords to determine verbosity
|
| 11 |
+
if "explain" in user_input.lower() or "describe" in user_input.lower():
|
| 12 |
+
prompt = f"""
|
| 13 |
+
You are a Python tutor.Only answer questions related to Python programming and its libraries. Provide a concise explanation for the query, avoiding unnecessary details.
|
| 14 |
+
Focus on delivering the main point clearly and briefly.
|
| 15 |
+
|
| 16 |
+
Query: {user_input}
|
| 17 |
+
Response:
|
| 18 |
+
"""
|
| 19 |
+
elif "example" in user_input.lower() or "code" in user_input.lower():
|
| 20 |
+
prompt = f"""
|
| 21 |
+
You are a Python tutor.Only answer questions related to Python programming and its libraries. Provide a detailed code example for the query, formatted properly for readability with simple explanation.
|
| 22 |
+
Avoid lengthy explanations; focus on the code.
|
| 23 |
+
|
| 24 |
+
Query: {user_input}
|
| 25 |
+
Response:
|
| 26 |
+
"""
|
| 27 |
+
else:
|
| 28 |
+
prompt = f"""
|
| 29 |
+
You are a Python tutor.Only answer questions related to Python programming and its libraries. Provide a brief response that directly addresses the user's query.
|
| 30 |
+
|
| 31 |
+
Query: {user_input}
|
| 32 |
+
Response:
|
| 33 |
+
"""
|
| 34 |
+
|
| 35 |
+
# Generate response using OpenAI API
|
| 36 |
+
response = openai.ChatCompletion.create(
|
| 37 |
+
model="gpt-4o-mini",
|
| 38 |
+
messages=history + [{"role": "user", "content": prompt}], # Add the prompt to the message history
|
| 39 |
+
temperature=0.5,
|
| 40 |
+
max_tokens=500 # Ensure sufficient length for detailed code examples
|
| 41 |
+
)
|
| 42 |
+
return response.choices[0].message["content"].strip()
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def format_code_block(response):
|
| 46 |
+
"""
|
| 47 |
+
Formats code blocks for proper HTML rendering.
|
| 48 |
+
"""
|
| 49 |
+
response = response.replace("```python", "<pre><code>").replace("```", "</code></pre>")
|
| 50 |
+
response = response.replace("\n", "<br>")
|
| 51 |
+
return response
|
| 52 |
+
|
utils/quiz_utils.py
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Initialize quiz state
|
| 2 |
+
|
| 3 |
+
quiz_questions = {
|
| 4 |
+
"beginner": [
|
| 5 |
+
{"question": "What is the correct syntax to print a message in Python?",
|
| 6 |
+
"options": ["A. echo 'Hello'", "B. printf('Hello')", "C. print('Hello')", "D. write('Hello')"],
|
| 7 |
+
"answer": "C. print('Hello')"},
|
| 8 |
+
{"question": "What is a correct variable name in Python?",
|
| 9 |
+
"options": ["A. 1variable", "B. variable1", "C. variable-1", "D. variable@1"],
|
| 10 |
+
"answer": "B. variable1"},
|
| 11 |
+
{"question": "Which of the following is a Python data type?",
|
| 12 |
+
"options": ["A. list", "B. array", "C. stack", "D. queue"],
|
| 13 |
+
"answer": "A. list"},
|
| 14 |
+
{"question": "What does `len()` do in Python?",
|
| 15 |
+
"options": ["A. Calculates length of a string or list", "B. Slices a list", "C. Joins strings", "D. Sorts a list"],
|
| 16 |
+
"answer": "A. Calculates length of a string or list"},
|
| 17 |
+
{"question": "What is the output of `print(type(10))`?",
|
| 18 |
+
"options": ["A. int", "B. float", "C. str", "D. None"],
|
| 19 |
+
"answer": "A. int"}
|
| 20 |
+
],
|
| 21 |
+
"intermediate": [
|
| 22 |
+
{"question": "Which keyword is used to handle exceptions in Python?",
|
| 23 |
+
"options": ["A. catch", "B. handle", "C. try", "D. except"],
|
| 24 |
+
"answer": "C. try"},
|
| 25 |
+
{"question": "What is the result of `3 == 3.0` in Python?",
|
| 26 |
+
"options": ["A. True", "B. False", "C. Error", "D. None"],
|
| 27 |
+
"answer": "A. True"},
|
| 28 |
+
{"question": "Which of the following is an immutable data type?",
|
| 29 |
+
"options": ["A. List", "B. Tuple", "C. Dictionary", "D. Set"],
|
| 30 |
+
"answer": "B. Tuple"},
|
| 31 |
+
{"question": "What does the `join()` method do?",
|
| 32 |
+
"options": ["A. Joins lists", "B. Joins elements of a list into a string", "C. Combines dictionaries", "D. Concatenates two strings"],
|
| 33 |
+
"answer": "B. Joins elements of a list into a string"},
|
| 34 |
+
{"question": "What does `list.pop()` do?",
|
| 35 |
+
"options": ["A. Removes and returns the last element of the list", "B. Removes a random element", "C. Sorts the list", "D. Reverses the list"],
|
| 36 |
+
"answer": "A. Removes and returns the last element of the list"}
|
| 37 |
+
],
|
| 38 |
+
"advanced": [
|
| 39 |
+
{"question": "What is the purpose of the `@staticmethod` decorator in Python?",
|
| 40 |
+
"options": ["A. To define a method that doesn't require an instance",
|
| 41 |
+
"B. To define a method that can modify a class attribute",
|
| 42 |
+
"C. To define a method that requires an instance",
|
| 43 |
+
"D. To define a private method"],
|
| 44 |
+
"answer": "A. To define a method that doesn't require an instance"},
|
| 45 |
+
{"question": "What is the time complexity of searching for an element in a dictionary?",
|
| 46 |
+
"options": ["A. O(1)", "B. O(n)", "C. O(log n)", "D. O(n^2)"],
|
| 47 |
+
"answer": "A. O(1)"},
|
| 48 |
+
{"question": "What does the `zip()` function do in Python?",
|
| 49 |
+
"options": ["A. Combines multiple iterables element-wise",
|
| 50 |
+
"B. Compresses a list",
|
| 51 |
+
"C. Converts a tuple into a dictionary",
|
| 52 |
+
"D. Creates a list of pairs from two dictionaries"],
|
| 53 |
+
"answer": "A. Combines multiple iterables element-wise"},
|
| 54 |
+
{"question": "What is the difference between `deepcopy()` and `copy()`?",
|
| 55 |
+
"options": ["A. `copy()` creates a shallow copy, `deepcopy()` creates a deep copy",
|
| 56 |
+
"B. `copy()` is faster than `deepcopy()`",
|
| 57 |
+
"C. `deepcopy()` is for strings only",
|
| 58 |
+
"D. There is no difference"],
|
| 59 |
+
"answer": "A. `copy()` creates a shallow copy, `deepcopy()` creates a deep copy"},
|
| 60 |
+
{"question": "What does the `yield` keyword do?",
|
| 61 |
+
"options": ["A. Returns multiple values from a function",
|
| 62 |
+
"B. Converts a function into a generator",
|
| 63 |
+
"C. Pauses a function and resumes it later",
|
| 64 |
+
"D. Both B and C"],
|
| 65 |
+
"answer": "D. Both B and C"}
|
| 66 |
+
]
|
| 67 |
+
}
|