+
+
diff --git a/main.py b/main.py
index 9bf4658..fc442c9 100644
--- a/main.py
+++ b/main.py
@@ -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)
diff --git a/questions_invalid.json b/questions_invalid.json
new file mode 100644
index 0000000..c714d13
--- /dev/null
+++ b/questions_invalid.json
@@ -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": [
+ "Прибор для измерения расстояний",
+ "Прибор для измерения углов"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/questions_schema.json b/questions_schema.json
new file mode 100644
index 0000000..62ba1c2
--- /dev/null
+++ b/questions_schema.json
@@ -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"]
+}
\ No newline at end of file
diff --git a/readme.md b/readme.md
index dbcce3d..f209210 100644
--- a/readme.md
+++ b/readme.md
@@ -78,4 +78,19 @@ PolicyStore : ActiveStore
### Доступ к тесту
-Для доступа к тесту с компьютера в локальной сети перейти по URL такого вида `ip-адрес:порт`, например, `123.32.43.54:8000`
\ No newline at end of file
+Для доступа к тесту с компьютера в локальной сети перейти по 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) наличия правильного ответа среди вариантов ответа можно проверить
\ No newline at end of file