Adding a Database ================= We will use sqlite3 as it is readily available and none of the data is particularly valuable. The data can be loaded as one table, check on the two sets of dummy data, the table requires a unique column *id* two columns for *query* and *ans* then a column for *song*. Adding Song Files ----------------- *song* will point to the file. As we are going to store the songs in the static directory in the sub-folder *songs* check how jinja2 retrieves information from static files using *url_for*:: sound = url_for('static', filename=soundfile) Within *quiz.html* audio controls plays the source as src = {{sound}}, therefore the *song* files will all require *songs/* immediately preceding the filename. The bird songs came from `xeno-canto.org `_, which are extraordinaly comprehensive. By now your files should be as follows:: Flask ├──static │ └──songs │ ├──Common Cuckoo.wav │ ├──Common Wood Pigeon.wav │ ├──Eurasian Blue Tit.mp3 │ ├──Eurasian Skylark.mp3 │ └──European Green Woodpecker.mp3 │ ├──templates │ ├──base.html │ ├──home.html │ ├──index.html │ ├──quiz.html │ └──result.html │ ├──bird.py ├──config.py ├──venv └──quizbird.csv Create a Database ----------------- When creating a database the most difficult part is setting up a csv file that can easily be loaded into the database. All spreadsheets have the ability to create a csv file, so choose your spreadsheet and create the named columns. When saving as an csv file ensure that it is saved in UTF-8 format with semi- colons as separators, also create the first column with numbers starting from 1 and incrementing by 1 to 5 call it *id* :: id;question;song;answer 1;Heard by woodland edge and near reed beds, a sure sign of Spring;songs/Common Cuckoo.wav;Cuckoo 2;Seen in woods and farmland, but often heard in gardens. Give the type as well. ;songs/Common Wood Pigeon.wav;Wood Pigeon 3;Found in woodlands, parks and gardens. Give the type as well. ;songs/Eurasian Blue Tit.mp3;Blue Tit 4;Heard over grassland, marshes and heathland;songs/Eurasian Skylark.mp3;Skylark 5;Heard and seen in woodlands, heaths and grassy areas. Give the type as well. ;songs/European Green Woodpecker.mp3;Green Woodpecker Open a sqlite interface on the desktop at your *Flask* directory, in Windows. Use cmd.exe, type in the following to create an sqlite3 database called mydb.db, the table columns are made automagically with the same name as the first row of the table *birdquiz*:: sqlite3 mydb.db sqlite> .mode csv sqlite> .separator ";" sqlite> .import quizbird.csv birdquiz sqlite> SELECT * FROM birdquiz; Make sure that there are no empty lines at the end of the file - that will show up when we ``SELECT * FROM birdquiz;``. .. sidebar:: Stopping Sqlite3 Simply type in (control key and c key together). When retrieving data from the databank we will be doing it line by line, the first line will be 1, no longer 0. *bird.py* needs changing from the dummy data to the database:: .... import sqlite3 ... # Function to establish database connection db_connection = lambda: sqlite3.connect("mydb.db") Remove the dummy data *quizlet*. Within *index* route change the starting value of *session["count"]* from 0 to 1:: ... session.pop("count", None) session["count"] = 1 ... Change the conditional clause *if session["count"] > 1:* to *if session["count"] > 5:* :: @app.route('/quiz', methods=['GET', 'POST']) def quiz(): if session["count"] > 5: Soon after is *user_answer* this is compared to the *correct_answer* from the database:: .... if request.method == 'POST': question_id = request.form.get('question_id') user_answer = request.form.get('user_answer').strip().title() # Fetch the correct answer from the database conn = db_connection() cursor = conn.cursor() cursor.execute("SELECT answer FROM birdquiz WHERE id = ?", (question_id,)) correct_answer = cursor.fetchone()[0].strip().title() cursor.close() conn.close() This replaces:: correct_answer = quizlet[session["count"]]['ans'].strip().title() A little later a single row is retrieved from the database, this replaces:: select = quizlet[session["count"]] soundfile = select['song'] replaced by:: conn = db_connection() cursor = conn.cursor() cursor.execute("SELECT id, question, song FROM birdquiz WHERE id = ?", (session["count"],)) select = cursor.fetchone() conn.close() soundfile = select[2] To play the songs we will need song files. Create a new folder *static*, with a sub-folder *songs*. *static* is at the same level as the folder *templates*. Change *quiz.html* from::

{{ select['query'] }}

.... to::

{{ select[1] }}

.... As this is a demonstration there are only 5 questions remember to increase the limit if you have more questions. At present the application is functional, but has no feedback to the users of how well they did. Database File Updates --------------------- .. image:: ../figures/quiz_05database.png :width: 200 :height: 143 :alt: quiz :align: center Apart from bird.py and quiz.html no files were updated, but the bird songs and quizbird.csv are new. mydb.db is simply formed by copying the instructions above.