Okay, die Frage ist doch noch aktuell, im folgenden der editierte Post:
Guten Abend,
ich war etwas fleißig und habe einen funktionierenden Stand.
Theoretisch fehlt nur noch etwas Design und die Anordnung der Buttons. Leider habe ich mit der 'style.css' keinen Erfolg.
Zum Beispiel würde ich gerne den "Weiter"- und "Zurück"-Button nebeneinander haben. Auch wird die Auswahl der Fragen vollständig untereinander angezeigt, das wäre in drei oder vier Spalten vielleicht auch übersichtlicher.
Hier mal meine Ordnerstruktur:
Code: Alles auswählen
questions_trainer) [dennis@dennis Question_Trainer]$ ls -l
insgesamt 8
-rw-r--r--. 1 dennis dennis 2782 4. Feb 22:12 app.py
drwxr-xr-x. 1 dennis dennis 80 3. Feb 22:32 __pycache__
-rw-r--r--. 1 dennis dennis 198 2. Feb 22:16 questions.json
drwxr-xr-x. 1 dennis dennis 6 27. Jan 20:20 static
drwxr-xr-x. 1 dennis dennis 86 3. Feb 22:35 templates
Code: Alles auswählen
(questions_trainer) [dennis@dennis Question_Trainer]$ ls -l templates
insgesamt 16
-rw-r--r--. 1 dennis dennis 1715 3. Feb 22:37 base.html
-rw-r--r--. 1 dennis dennis 137 3. Feb 22:42 finish.html
-rw-r--r--. 1 dennis dennis 386 4. Feb 06:59 index.html
-rw-r--r--. 1 dennis dennis 642 4. Feb 22:05 question.html
Code: Alles auswählen
(questions_trainer) [dennis@dennis Question_Trainer]$ ls -l static/css/
insgesamt 4
-rw-r--r--. 1 dennis dennis 163 4. Feb 22:07 style.css
Und hier mal die Dateien:
app.py
Code: Alles auswählen
from json import loads
from pathlib import Path
from random import sample
from flask import Flask, render_template, request
from werkzeug.exceptions import abort
QUESTIONS_PATH = Path("/home/dennis/Question_Trainer/questions.json")
app = Flask(__name__)
class QuestionTrainer:
def __init__(self):
self.questions = loads(QUESTIONS_PATH.read_bytes())
self.active_question = 0
self.answers_random_order = None
@property
def number_of_questions(self):
return [number for number, _ in enumerate(self.questions)]
def get_question(self, number=None):
if number is not None:
self.active_question = number
return self.questions[self.active_question]["question"]
def get_answers_in_random_order(self):
self.answers_random_order = sample(self.questions[self.active_question]["answers"], 4)
return self.answers_random_order
def get_right_answer(self, answer):
return answer == self.questions[self.active_question]["answers"][0]
@app.route("/question", methods=["GET", "POST"])
def chose_question():
question = int(request.form["answer"]) - 1
question = question_trainer.get_question(question)
question_trainer.get_answers_in_random_order()
return render_template(
"question.html",
question=question,
answers=question_trainer.answers_random_order,
)
@app.route("/answer", methods=["GET", "POST"])
def check_answer():
answer = str(request.form["answer"])
rating = "Richtig!" if question_trainer.get_right_answer(answer) else "Falsch!"
return render_template(
"question.html",
question=question_trainer.get_question(),
answers=question_trainer.answers_random_order,
rating=rating,
)
@app.route("/next", methods=["GET", "POST"])
def next_question():
try:
number = question_trainer.active_question + 1
question = question_trainer.get_question(number)
question_trainer.get_answers_in_random_order()
return render_template(
"question.html", question=question, answers=question_trainer.answers_random_order
)
except IndexError:
return render_template("finish.html")
@app.route("/back", methods=["GET", "POST"])
def previous_question():
number = question_trainer.active_question - 1
if number < 0:
return index()
question = question_trainer.get_question(number)
question_trainer.get_answers_in_random_order()
return render_template(
"question.html", question=question, answers=question_trainer.answers_random_order
)
@app.route("/")
def index():
questions = question_trainer.number_of_questions
return render_template("index.html", questions=questions)
question_trainer = QuestionTrainer()
Ist das jetzt eigentlich eine von den Situationen, in denen ich 'question_trainer' global verfügbar brauche oder geht das auch anders?
questions.json (Beispieldaten)
Code: Alles auswählen
[
{"question": "Wie heißt du?", "answers": ["Hans", "Peter", "Hubert", "Karle"]},
{"question": "Was machst du morgen?", "answers": ["Arbeiten", "Essen", "Sport", "Schlafen"]}
]
base.html (Habe ich von
hier geklaut. So tief konnte ich noch nicht einsteigen. Ist eigentlich nur mit drin, weil mir das Top-Menü gefällt)
Code: Alles auswählen
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<title>{% block title %} {% endblock %}</title>
</head>
<body>
<nav class="navbar navbar-expand-md navbar-light bg-light">
<a class="navbar-brand" href="{{ url_for('index')}}">Fragenübersicht</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
</nav>
<div class="container">
{% block content %} {% endblock %}
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
index.html
Code: Alles auswählen
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="{{ url_for('static', filename= 'css/style.css') }}">
<title>Fragetrainer</title>
</head>
{% extends 'base.html' %}
{% block content %}
<h1>{% block title %} Willkommen zum BZF Prüfungstrainer {% endblock %}</h1>
Wähle die Frage, mit der du beginnen willst:
<form action="/question" method="POST">
{% for question in questions %}
<p><input type="submit" name="answer" value={{ question + 1 }}></p>
{% endfor %}
</form>
{% endblock %}
question.html (Hier versuche ich gerade die "Weiter"- und "Zurück"-Buttons nebeneinander anzuordnen)
Code: Alles auswählen
{% extends 'base.html' %}
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="{{ url_for('static', filename= 'css/style.css') }}">
<title>Fragetrainer</title>
</head>
{% block content %}
<h1>{% block title %} Wähle weise! {% endblock %}</h1>
{{ question }}
<form action="/answer" method="POST">
{% for answer in answers %}
<p><input type="submit" name="answer" value={{ answer }}></p>
{% endfor %}
</form>
{{ rating }}
<div class="button-container">
<form action="/back" methode="POST">
<div>
<p><input type="submit" name="back" value="Zurück"></p>
</div>
</form>
<form action="/next" methode="POST">
<div>
<p><input type="submit" name="next" value="Weiter" formaction="next"></p>
</div>
</form>
</div>
{% endblock %}
finish.html
Code: Alles auswählen
{% extends 'base.html' %}
{% block content %}
<h1>{% block title %} Juhu, ab zur Prüfung! {% endblock %}</h1>
{% endblock %}
style.css
Code: Alles auswählen
h1 {
border: 2px #eee solid;
color: brown;
text-align: left;
padding: 10px;
}
.button-container form,
.button-container form div {
display: inline-block;
}
.button-container button {
display: inline-block;
vertical-align: middle;
}
Sieht das soweit einigermaßen vertretbar aus? Habt ihr eine Idee wie ich die Anordnung der Buttons umsetzen könnte?
Die Stackoverflow-Threads zum Thema "html button side by side" und "html form side by side" haben leider nicht funktioniert.
Danke und viele Grüße
Dennis