Spaces:
Sleeping
Sleeping
File size: 8,846 Bytes
83ec974 d7ad4b8 83ec974 d7ad4b8 83ec974 d7ad4b8 83ec974 16a7e13 d7ad4b8 83ec974 d7ad4b8 16a7e13 d7ad4b8 16a7e13 d7ad4b8 16a7e13 d7ad4b8 16a7e13 d7ad4b8 16a7e13 d7ad4b8 16a7e13 d7ad4b8 16a7e13 d7ad4b8 16a7e13 d7ad4b8 16a7e13 d7ad4b8 83ec974 d7ad4b8 16a7e13 d7ad4b8 16a7e13 d7ad4b8 16a7e13 d7ad4b8 16a7e13 d7ad4b8 16a7e13 d7ad4b8 16a7e13 d7ad4b8 16a7e13 d7ad4b8 16a7e13 d7ad4b8 16a7e13 |
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 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
import streamlit as st
from io import StringIO
import json
# Set the page configuration
st.set_page_config(page_title="π Multiple Choice Test Creator", layout="wide")
# Initialize session state for storing tests
if 'tests' not in st.session_state:
st.session_state['tests'] = []
# Initialize session state for current questions being added
if 'current_questions' not in st.session_state:
st.session_state['current_questions'] = []
# Function to add a new question
def add_question():
if len(st.session_state['current_questions']) < 10:
st.session_state['current_questions'].append({
'question': '',
'options': {'A': '', 'B': '', 'C': '', 'D': ''},
'correct': 'A'
})
else:
st.warning("You can only add up to 10 questions.")
# Function to remove a question
def remove_question(index):
st.session_state['current_questions'].pop(index)
# Function to generate HTML content for the test
def generate_html(test_title, questions):
html_content = f"""<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{test_title}</title>
<style>
body {{
font-family: Arial, sans-serif;
margin: 40px;
background-color: #f9f9f9;
}}
.test-title {{
text-align: center;
font-size: 2em;
margin-bottom: 50px;
}}
.question {{
margin-bottom: 30px;
}}
.options label {{
display: block;
margin: 5px 0;
}}
</style>
</head>
<body>
<div class="test-title">{test_title}</div>
"""
for idx, q in enumerate(questions, 1):
html_content += f"""
<div class="question">
<div class="question-text"><strong>Question {idx}:</strong> {q['question']}</div>
<div class="options">
<label><input type="radio" name="q{idx}" value="A"> A. {q['options']['A']}</label>
<label><input type="radio" name="q{idx}" value="B"> B. {q['options']['B']}</label>
<label><input type="radio" name="q{idx}" value="C"> C. {q['options']['C']}</label>
<label><input type="radio" name="q{idx}" value="D"> D. {q['options']['D']}</label>
</div>
</div>
"""
html_content += """
</body>
</html>
"""
return html_content
# Tabs for navigation
tabs = st.tabs(["π Create Test", "π Take Test"])
# -------------------- Create Test Tab -------------------- #
with tabs[0]:
st.header("Create a New Multiple-Choice Test")
# Input for Test Title
test_title = st.text_input("Enter Test Title", "")
# Button to add a new question
st.button("β Add a Question", on_click=add_question)
# Display existing questions
for idx, q in enumerate(st.session_state['current_questions']):
with st.expander(f"Question {idx + 1}", expanded=True):
# Question Text
question_key = f"question_{idx}"
question_text = st.text_input("Question Text", value=q['question'], key=question_key)
st.session_state['current_questions'][idx]['question'] = question_text
# Answer Options
for option in ['A', 'B', 'C', 'D']:
option_key = f"question_{idx}_option_{option}"
option_text = st.text_input(f"Answer {option}", value=q['options'][option], key=option_key)
st.session_state['current_questions'][idx]['options'][option] = option_text
# Correct Answer Selector
correct_option_key = f"question_{idx}_correct"
correct_option = st.selectbox("Select Correct Answer", options=['A', 'B', 'C', 'D'],
index=['A','B','C','D'].index(q['correct']),
key=correct_option_key)
st.session_state['current_questions'][idx]['correct'] = correct_option
# Remove Question Button
if st.button("ποΈ Remove", key=f"remove_{idx}"):
remove_question(idx)
st.experimental_rerun()
# Button to create the test
if st.button("β
Create Test"):
if not test_title:
st.error("Please enter a test title.")
elif len(st.session_state['current_questions']) == 0:
st.error("Please add at least one question.")
else:
# Validate that all questions have all fields filled
incomplete = False
for idx, q in enumerate(st.session_state['current_questions'], 1):
if not q['question'] or not all(q['options'][opt] for opt in ['A','B','C','D']):
st.error(f"Question {idx} is incomplete. Please fill in all fields.")
incomplete = True
break
if not incomplete:
# Add the test to the session state
test = {
'title': test_title,
'questions': st.session_state['current_questions'].copy()
}
st.session_state['tests'].append(test)
st.success(f"Test '{test_title}' created successfully!")
# Clear current questions after creation
st.session_state['current_questions'] = []
# Provide download button
html_content = generate_html(test_title, test['questions'])
st.download_button(
label="π Download Test as HTML",
data=html_content,
file_name=f"{test_title.replace(' ', '_')}.html",
mime="text/html"
)
# Optionally, display the test
st.markdown("---")
st.header("π Your Test")
st.markdown(html_content, unsafe_allow_html=True)
# -------------------- Take Test Tab -------------------- #
with tabs[1]:
st.header("Take a Multiple-Choice Test")
if len(st.session_state['tests']) == 0:
st.info("No tests available. Please create a test first.")
else:
# Select a test to take
test_titles = [test['title'] for test in st.session_state['tests']]
selected_test_title = st.selectbox("Select a Test to Take", options=test_titles)
# Retrieve the selected test
selected_test = next((test for test in st.session_state['tests'] if test['title'] == selected_test_title), None)
if selected_test:
# Initialize session state for user answers if not present
if 'user_answers' not in st.session_state:
st.session_state['user_answers'] = {}
with st.form("take_test_form"):
for idx, q in enumerate(selected_test['questions'], start=1):
st.markdown(f"**{idx}. {q['question']}**")
# Prepare options with letters and text
option_list = [
f"A. {q['options']['A']}",
f"B. {q['options']['B']}",
f"C. {q['options']['C']}",
f"D. {q['options']['D']}"
]
# Create radio buttons with the full option text
answer = st.radio(
f"Select an answer for Question {idx}",
options=option_list,
key=f"test_{selected_test_title}_q{idx}"
)
# Store the selected answer's letter
st.session_state['user_answers'][idx] = answer.split(".")[0].strip()
st.markdown("---")
# Submit button
submit = st.form_submit_button("Submit Test")
if submit:
# Grade the test
score = 0
total = len(selected_test['questions'])
feedback = []
for idx, q in enumerate(selected_test['questions'], start=1):
user_ans = st.session_state['user_answers'].get(idx, None)
correct_ans = q['correct']
is_correct = user_ans == correct_ans
if is_correct:
score += 1
feedback.append(f"**Question {idx}**: Correct β
")
else:
feedback.append(f"**Question {idx}**: Incorrect β (Correct Answer: {correct_ans})")
# Display the result
st.success(f"You scored {score} out of {total}.")
# Display feedback
with st.expander("View Feedback"):
for fb in feedback:
st.markdown(fb)
# Optionally, clear answers for next test
st.session_state['user_answers'] = {}
|