Загрузка данных


import random
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QLabel, QVBoxLayout,
                             QHBoxLayout, QRadioButton, QGroupBox)

# (вопрос, правильный ответ, неправильные ответы)
QUESTIONS = [
    ("В каком году был основан Нижний Новгород?", "1221", ["1147", "1242", "1861"]),
    ("Какой город является столицей Австралии?", "Канберра", ["Сидней", "Мельбурн", "Перт"]),
    ("Сколько планет в Солнечной системе?", "8", ["7", "9", "10"]),
    ("Кто автор романа «Война и мир»?", "Лев Толстой", ["Фёдор Достоевский", "Антон Чехов", "Александр Пушкин"]),
    ("Какой химический символ у золота?", "Au", ["Ag", "Fe", "Go"]),
]

app = QApplication([])
window = QWidget()
window.setWindowTitle("Memory Card")
window.resize(400, 400)

lb_Question = QLabel("")
btn_OK = QPushButton("Ответить")

RadioGroupBox = QGroupBox("Варианты ответов")
buttons = [QRadioButton(), QRadioButton(), QRadioButton(), QRadioButton()]

layout1 = QHBoxLayout()
layout2 = QVBoxLayout()
layout3 = QVBoxLayout()
layout2.addWidget(buttons[0])
layout2.addWidget(buttons[1])
layout3.addWidget(buttons[2])
layout3.addWidget(buttons[3])
layout1.addLayout(layout2)
layout1.addLayout(layout3)
RadioGroupBox.setLayout(layout1)

layout_line1 = QHBoxLayout()
layout_line2 = QHBoxLayout()
layout_line3 = QHBoxLayout()

layout_line1.addWidget(lb_Question, alignment=Qt.AlignHCenter | Qt.AlignVCenter)
layout_line2.addWidget(RadioGroupBox)
layout_line3.addStretch(1)
layout_line3.addWidget(btn_OK, stretch=2)
layout_line3.addStretch(1)

AnsGroupBox = QGroupBox("Результаты теста")
lb_Result = QLabel('')
lb_Correct = QLabel('')
layout_res = QVBoxLayout()
layout_res.addWidget(lb_Result, alignment=Qt.AlignLeft | Qt.AlignTop)
layout_res.addWidget(lb_Correct, alignment=Qt.AlignHCenter, stretch=2)
AnsGroupBox.setLayout(layout_res)
AnsGroupBox.hide()
layout_line2.addWidget(AnsGroupBox)

layout_card = QVBoxLayout()
layout_card.addLayout(layout_line1, stretch=2)
layout_card.addLayout(layout_line2, stretch=8)
layout_card.addLayout(layout_line3, stretch=1)
layout_card.setSpacing(5)

# состояние
order = []
idx = 0
score = 0
correct_text = ""
mode = "answer"  # answer -> next -> (restart)


def clear_choice():
    for b in buttons:
        b.setAutoExclusive(False)
        b.setChecked(False)
        b.setAutoExclusive(True)


def load_question():
    global correct_text
    q_text, right, wrong = order[idx]
    correct_text = right
    answers = [right] + wrong
    random.shuffle(answers)
    lb_Question.setText(f"Вопрос {idx + 1} из {len(order)}\n\n{q_text}")
    clear_choice()
    for b, a in zip(buttons, answers):
        b.setText(a)
    RadioGroupBox.show()
    AnsGroupBox.hide()
    btn_OK.setText("Ответить")


def start_quiz():
    global order, idx, score, mode
    order = random.sample(QUESTIONS, len(QUESTIONS))
    idx = 0
    score = 0
    mode = "answer"
    load_question()


def check_answer():
    global score, mode
    chosen = next((b for b in buttons if b.isChecked()), None)
    if chosen is None:
        return
    if chosen.text() == correct_text:
        score += 1
        lb_Result.setText("Правильно!")
    else:
        lb_Result.setText("Неправильно!")
    lb_Correct.setText("Правильный ответ: " + correct_text)
    RadioGroupBox.hide()
    AnsGroupBox.setTitle("Результат ответа")
    AnsGroupBox.show()
    last = idx == len(order) - 1
    btn_OK.setText("Показать итог" if last else "Следующий вопрос")
    mode = "next"


def show_final():
    global mode
    total = len(order)
    ratio = score / total
    if ratio == 1:
        grade = "Отлично!"
    elif ratio >= 0.6:
        grade = "Хорошо"
    else:
        grade = "Надо повторить"
    lb_Question.setText("Тест завершён")
    RadioGroupBox.hide()
    AnsGroupBox.setTitle("Итоговый результат")
    lb_Result.setText(f"Правильных ответов: {score} из {total}")
    lb_Correct.setText(grade)
    AnsGroupBox.show()
    btn_OK.setText("Начать заново")
    mode = "restart"


def on_btn_ok_click():
    global idx, mode
    if mode == "answer":
        check_answer()
    elif mode == "next":
        idx += 1
        if idx >= len(order):
            show_final()
        else:
            mode = "answer"
            load_question()
    else:
        start_quiz()


btn_OK.clicked.connect(on_btn_ok_click)
window.setLayout(layout_card)
start_quiz()
window.show()
app.exec_()