🧐 close #4 check questions

master
gtitov 3 years ago
parent ab18044ece
commit 73447209ac

@ -41,6 +41,10 @@
<button id="get-quiz" disabled>Получить тест</button>
</p>
<button id="end-quiz">Завершить тест для всех 😇</button>
<br>
<form>
<button formaction="/check_questions">Проверить вопросы 🧐</button>
</form>
</main>
<hr>

@ -9,7 +9,7 @@ import socket
from settings import WAVE, END_TEST_PASSWORD, QUIZ_LENGTH, QUESTIONS_FILE, STUDENTS_FILE
app = FastAPI()
app = FastAPI(debug=True)
origins = [ # CORS
"*",
@ -25,9 +25,9 @@ app.add_middleware( # CORS
# open files once and use variables after
with open(QUESTIONS_FILE, "r", encoding="UTF-8") as f:
content = json.load(f)
questions_json = json.load(f)
# TODO reassign questions id since mistakes are possible and checking is based on id
all_questions = content["questions"]
all_questions = questions_json["questions"]
# if you want to use topics 1) filter all questions with topics 2) use topic questions to construct quiz_questions (when removing service keys from all_questions dict)
# topics = ["теодолит"] # move topics to VARIABLES
# topics_questions = [q for q in all_questions if q.get("topic") in topics]
@ -37,8 +37,8 @@ with open(QUESTIONS_FILE, "r", encoding="UTF-8") as f:
quiz_questions = [{key: value for key, value in q.items() if key not in remove_keys} for q in typed_questions] # all_questions can be replaced with topic_questions
with open(STUDENTS_FILE, "r", encoding="UTF-8") as f:
content = json.load(f)
students = content["students"]
students_json = json.load(f)
students = students_json["students"]
# create folders if they don't exist
Path("answers").mkdir(parents=True, exist_ok=True)
@ -62,6 +62,22 @@ def check_answers(student_answers: dict):
return checked_answers
@app.get("/check_questions")
def check_questions():
unique_ids = []
errors = []
for q in all_questions:
if q["id"] in unique_ids:
errors.append(f'"id": {q["id"]} — идентификатор не уникален')
else:
unique_ids.append(q["id"])
if q.get("options") and not (set(q["answer"]).issubset(set(q["options"])) or q["answer"] in q["options"]):
errors.append(f"В вопросе '{q['question']}' нет корректного варианта ответа")
return errors if errors else "Вопросы в порядке!"
@app.get("/hostip")
def show_host_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

@ -0,0 +1,69 @@
{
"version": 1,
"questions": [
{
"id": 1,
"topic": "теодолит",
"author": "GT",
"question": "Что такое теодолит?",
"picture": "pictures/teodolit.png",
"options": [
"Прибор для измерения земли",
"Прибор для измерения углов",
"Прибор для измерения расстояний",
"Прибор для измерения высот"
],
"answer": "Прибор для измерения"
},
{
"id": 1,
"topic": "геометрия",
"author": "GT",
"question": "Сумма углов выпуклого пятиугольника составляет?",
"answer": "540"
},
{
"id": 3,
"topic": "нивелир",
"author": "GT",
"question": "Как называется прибор для измерения превышений?",
"answer": "нивелир"
},
{
"id": 4,
"topic": "теодолит",
"author": "GT",
"question": "Сколько винтов у теодолита?",
"answer": "520"
},
{
"id": 5,
"topic": "нивелир",
"author": "GT",
"question": "Что такое нивелир?",
"options": [
"Прибор для измерения земли",
"Прибор для измерения углов",
"Прибор для измерения расстояний",
"Прибор для измерения высот"
],
"answer": "Прибор для измерения углов"
},
{
"id": 6,
"topic": "нивелир",
"author": "GT",
"question": "Что такое нивелир 2.0?",
"options": [
"Прибор для измерения земли",
"Прибор для измерения углов",
"Прибор для измерения расстояний",
"Прибор для измерения высот"
],
"answer": [
"Прибор для измерения расстояний",
"Прибор для измерения углов"
]
}
]
}

@ -0,0 +1,23 @@
{
"type": "object",
"properties": {
"version": {"type": "number"},
"questions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {"type": "number"},
"topic": {"type": "string"},
"author": {"type": "string"},
"question": {"type": "string"},
"picture": {"type": "string"},
"options": {"type": "array"},
"answer": {}
},
"required": ["id", "question", "answer"]
}
}
},
"required": ["questions"]
}

@ -78,4 +78,19 @@ PolicyStore : ActiveStore
### Доступ к тесту
Для доступа к тесту с компьютера в локальной сети перейти по URL такого вида `ip-адрес:порт`, например, `123.32.43.54:8000`
Для доступа к тесту с компьютера в локальной сети перейти по URL такого вида `ip-адрес:порт`, например, `123.32.43.54:8000`
## Возможные проблемы 🔧
### Не открывается страница в браузере
В консоли, которая отвечает за запуск приложения, (окно, которое открылось после запуска файла `run.cmd`) должно быть выведено сообщение об ошибке
В случае, если приложение не запустилось из-за ошибки синтаксиса в JSON-файлах `questions.json` или `students.json`, то в последней строке сообщения об ошибке будет указано, что именно в этих файлах не так, например, `json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 18 column 9 (char 523)`
В случае, если приложение не запустилось из-за отсутсвия обязательных полей в JSON-файлах `questions.json` или `students.json`, то в последней строке сообщения об ошибке будет указано, что именно в этих файлах не так, например, `KeyError: 'answer'`
### Проверка корректности вопросов
Корректность вопросов на предмет 1) уникальности идентификаторов, 2) наличия правильного ответа среди вариантов ответа можно проверить
Loading…
Cancel
Save