Listen und Datenbank - der Vokabeltrainer: Unterschied zwischen den Versionen

Aus ComeniusWiki
Wechseln zu: Navigation, Suche
(Erweiterungsaufgaben)
(Lösung:)
Zeile 151: Zeile 151:
 
** Was passiert bei einer Abfrage bei leerer Liste?
 
** Was passiert bei einer Abfrage bei leerer Liste?
  
* Die Abfrage durchläuft immer die ganze gespeicherte Liste und das in derselben Reihenfolge der Vokabeln. Die Vokabeln sollen nun in zufälliger Reihenfolge abgefragt werden. Zusätzlich sollen dabei alle Vokabeln  abgefragt werden.
+
* Die Abfrage durchläuft immer die ganze gespeicherte Liste und das in derselben Reihenfolge der Vokabeln. Die Vokabeln sollen nun in zufälliger Reihenfolge abgefragt werden. Zusätzlich sollen dabei alle Vokabeln  abgefragt werden.Mit Hilfe eines Buttons kann der Benutzer wieder zum ursprünglichem Screen zurück.
  
 
* In der Praxis sollten nicht immer alle Vokabeln abgefragt werden, sondern zuerst die aktuellen Vokabeln. Dazu sollten die Vokabeln der letzten beiden Einheiten wiederholt werden und eventuell eine bestimmte Anzahl von Vokabeln aus früheren Einheiten. Dazu müssen wir in einer Liste der TinyDB auch die Anzahl der Vokabeln pro Einheit abfragen können und die gewünschten Vokabeln über eine Manipulation der Listenlänge erhalten können.
 
* In der Praxis sollten nicht immer alle Vokabeln abgefragt werden, sondern zuerst die aktuellen Vokabeln. Dazu sollten die Vokabeln der letzten beiden Einheiten wiederholt werden und eventuell eine bestimmte Anzahl von Vokabeln aus früheren Einheiten. Dazu müssen wir in einer Liste der TinyDB auch die Anzahl der Vokabeln pro Einheit abfragen können und die gewünschten Vokabeln über eine Manipulation der Listenlänge erhalten können.

Version vom 9. April 2015, 16:56 Uhr

Inhaltsverzeichnis

Die Idee

Wir wollen einen Vokabeltrainer programmieren, bei dem Vokabelpaare (Englisch - Deutsch) in Textboxes eingegeben werden können. Die aktuell eingegebenen Vokabeln werden als Liste angezeigt, die nach dem ersten Einprägen gelöscht werden kann. Die Vokabeln werden in eine Datenbank geschrieben, die beim Start der App zur Verfügung steht. Die englischen Vokabeln werden auf Buttonklick angezeigt und nach einem weiteren Klick das zugehörige deutsche Wort. Insbesondere zu Testzwecken besteht auch die Möglichkeit die gesamte Datenbank zu löschen.

Listen

Mit Array und Arraylist kennen wir aus Java bereits zwei Datentypen, mit denen größere Datenmengen abgespeichert werden können. Der App Inventor bietet zu diesem Zweck Listen. Die Vorgehensweise ist dabei dem Umgang mit Arraylists sehr ähnlich. Wesentliche Unterschiede sind, dass die Items nicht vom selben Datentyp sein müssen und dass die Indizierung der Items nicht mit dem Wert 0 beginnt, sondern mit dem Wert 1 und damit auch der Index des letzten Items in der Liste der Länge der Liste entspricht. Die zur Verfügung stehenden Methoden finden sich im Built-In Block Lists.

Wie bei Arraylists erhält die Liste einen Namen und wird als leere Liste initialisiert.

Voc list 1.JPG

Die Liste kann nun mit beliebig vielen Items gefüllt werden, die anschließend in dieser Reihenfolge über den Index angesprochen werden können. Um einen zusätzlichen Slot für die Items zu erzeugen genügt ein Klick auf das blaue Icon oben links. In dem erscheinenden Kontextmenü wird nun ein Item-Block in den Listenblock gezogen.

Voc list 2.JPG

Will man anschließend zusätzliche Items in die Liste aufnehmen, kann man dies mit dem Block add items to list bewerkstelligt werden.

Voc list 3.JPG

Um nun eines der Listenitems anzusprechen, verwendet man die Methode select list item, bei der der Indexwert als Parameterwert angegeben wird.

Voc list 4.JPG

Mit der Methode length of list lässt sich die Länge und damit die Anzahl der Items in einer Liste bestimmen.

Voc list 5.JPG

Wie vom Umgang mit Arrays und Arraylists bekannt, können auch Listen mittels Schleifen manipuliert werden. In folgendem Beispiel werden die Inhalte aller Items der Liste gelöscht (nicht die Items selbst!):

Voc list 6.JPG


Der große Nachteil der Listen ist, dass sie nur während der Laufzeit der App genutzt werden können. Nach Beenden der App werden alle Daten der Liste gelöscht. Um mit den eingegebenen Daten auch zu einem späteren Zeitpunkt arbeiten zu können, müssen diese permanent gespeichert werden. Der App Inventor bietet hierzu die Möglichkeit mittels TinyDB den internen Speicher des Smartphones zu nutzen.

TinyDB

Bei der TinyDB handelt es sich um einen Speicherbereich, den das Betriebssystem Android jeder mit dem App Inventor erstellten App dauerhaft zur Verfügung stellt. Darin können beliebig viele Daten abgelegt und abgerufen werden. Identifiziert werden sie dabei über einen eindeutigen Bezeichner (tag). Die zu speichernden Daten entsprechen den Werten, die während der Programmlaufzeit in den entsprechenden Variablen vorliegen. Dieses bedeutet auch, dass zu speichernde Daten als Werte in einer Variable vorliegen müssen und an die Methode StoreValue übergeben werden. Auch beim Laden wird eine Variable gleichen oder kompatiblen Datentyps benötigt, in die der Wert aus dem Speicher über die Methode GetValue geschrieben werden kann. Mit clear all bzw. clear tag können alle Daten der TinyDB bzw. die mit einem einzelnen tag verbundenen Daten gelöscht werden.

Eine TinyDB ist eine nicht-sichtbare Komponente und wird dem Projekt im Designermodus hinzugefügt. Die Funktionalität kann nur nach der Installation der App auf dem Smartphone vollständig getestet werde, da im Entwicklungsmodus die Daten nach einem Neustart der App immer wieder neu eingelesen werden müssen.

Das Design

Blocks

Speichern der Vokabeln

Um die eingegebenen Vokabelpaare zu speichern, nutzen wir zwei Listen. Diese beiden Listen können wir über den Index der einzelnen Items miteinander verbinden, d.h. Items mit gleichem Index bilden ein Vokabelpaar.

Voc a.JPG

Wir legen also zuerst zwei Listen an. Dazu deklarieren wir zwei Variablen Englisch und Deutsch und initialisieren sie als leere Listen.

Voc 1.JPG

Das Speichern der Vokabelpaare erfolgt durch Anklicken des Buttons Speichern. Wir beginnen also wieder mit dem entsprechenden Event Handler. Nach der oben erläuterten Vorgehensweise fügen wir den Inhalt der TextBoxEnglisch der Liste Englisch hinzu und den Inhalt der TextBoxDeutsch der Liste Deutsch. Anschließend leeren wir die zwei Textboxen wieder um sie für eine neue Eingabe vorzubereiten.

Voc 2.JPG

Auf diese Weise haben wir nach wiederholtem Speichern eine Liste von Vokabelpaaren. Allerdings existiert diese Liste nur während der Laufzeit der App und wird nach Beenden der Anwendung wieder gelöscht, was dem Sinn eines Vokabeltrainers zuwiderläuft. Zudem wollen wir neue Vokabeln den bereits bestehenden Listen hinzufügen. Wir müssen also den Variablen Englisch bzw. Deutsch den Inhalt der in der TinyDB Vokabelspeicher abgespeicherten Listen hinzufügen. In einem ersten Schritt setzen wir den Wert der Variablen auf den aktuellen Speicherinhalt der jeweiligen Listen. Indem wir einen tag Englischliste bzw. Deutschliste verwenden und den Inhalt einer Variable vom Datentyp Liste zuweisen, haben wir automatisch in der TinyDB Vokabelspeicher zwei Listen kreiert, die wir mit dem entsprechenden Namen immer wieder ansprechen können.

Voc 3.JPG

Genau das tun wir nun, indem wir nach dem Hinzufügen eines Items zur entsprechenden Liste diese wieder in der TinyDB abspeichern. Damit wird mit dem Klicken des Speicherbuttons die permanente Vokabelliste immer wieder aktualisiert.

Voc 4.JPG

Anzeigen der aktuellen Vokabelliste

Das Lernen einer Liste von Vokabeln beginnt üblicherweise damit, dass wir uns die einzelnen Vokabelpaare einprägen, bevor wir mit dem eigentlichen Abfragen beginnen. Es sollen also die einzelnen Vokabelpaare auf dem Display aufgelistet werden, so dass sie für den ersten Schritt des Vokabellernens zur Verfügung stehen. Zu diesem Zweck deklarieren wir zwei weitere Variablen EnglischDisplay und DeutschDisplay und initialisieren sie wiederum als leere Listen. Diese Listen werden allerdings nur während der Laufzeit der App benötigt, so dass sie nicht in der TinyDB abgespeichert werden müssen.

Voc 5.JPG

Wir fügen nun die Vokabeln beim Speichern gleichzeitig auch den nicht-permanenten Listen EnglischDisplay und DeutschDisplay hinzu.

Voc 6.JPG

Nun kommt die auf den ersten Blick recht einfache Aufgabe, die Vokabelpaare im Label LabelVokabelpaar aufzulisten, was aber etwas aufwändiger ist als es aussieht. Wir erstellen zu diesem Zweck eine eigene Prozedur VocShow, die diese Aufgabe umsetzt. Diese Prozedur macht Folgendes: Sie leert bei jedem Aufruf zuerst das Label. Dann schreibt sie mit Hilfe einer Schleife, die vom Index 1 bis zur aktuellen Länge der Liste läuft die einzelnen Vokabelpaare in das Label. Dazu werden die zusammengehörigen Items jeweils in eine Hilfsvariable geschrieben, indem sie mittels der select list item-Methode aus den nicht-permanenten Listen abgerufen werden und anschließend verbunden werden. Im Label wird dabei der aktuelle Inhalt des Labels mit dem neuen Vokabelpaar verbunden und durch einen Zeilenwechsel (\n) gegliedert.

Wir beginnen also mit der Deklaration und Initialisierung der Hilfsvariablen für die zu verbindenden Items der Vokabellisten.

Voc 7.JPG

Dann setzen wir die oben beschriebene Vorgehensweise um.

Voc 8.JPG


Zum Schluss müssen wir den Aufruf der Prozedur VocShow noch an entsprechender Stelle im Block Speichern einbauen.

Voc 9.JPG

Leeren der aktuellen Vokabelliste

Nachdem wir die Vokabelliste nach dem Einprägen der neuen Vokabeln nicht mehr brauchen, soll sie nach Gebrauch wieder gelöscht werden können. Dazu versehen wir den Button Liste leeren mit dem entsprechenden Event Handler. Das Leeren ist relativ einfach. Wir setzen das Label LabelVokabelpaar auf einen leeren String und belegen die beiden Variablen für die nicht-permanenten Listen mit einer leeren Liste, d.h. es werden alle Items aus den beiden Listen gelöscht.

Voc 13.JPG

Abfragen der Vokabeln

Nun setzen wir die eigentliche Funktion des Vokabeltrainers um - das Abfragen. Zu diesem Zweck durchlaufen wir die Vokabellisten, indem wir bei jedem Klicken des Buttons Abfragen den Index der Listen um eins erhöhen. Zur Anzeige der englischen Vokabel nutzen wir die bereits angelegte Hilfsvariable VocE und weisen ihr aus der permanenten Englischliste der TinyDB das dem Indexwert entsprechende Item zu, das wir dann dem Setter des Labels LabelAsk zuweisen. Gleichzeitig löschen wir die Anzeige des deutschen Wortes im Label LabelShow. Wird der Button Show geklickt, soll dort das zugehörige deutsche Wort angezeigt werden.

Wir beginnen mit der Deklaration der Hilfsvariable für den Listenindex. Diese wird mit dem Wert 0 initialisiert, da damit beim ersten Klick des Buttons Abfragen der Indexwert auf 1 und damit auf den Wert des ersten Items in der Liste gesetzt wird.

Voc 10a.JPG

Wir versehen nun den Button Abfragen mit dem entsprechenden Event Handler und setzen die oben beschriebene Vorgehensweise um.

Voc 10b.JPG

Der nächste Schritt setellt eine kleine Schönheitskorrektur dar. Wir setzten den Text des Buttons Abfragen auf Next. Den Wechsel der beiden Beschriftungen müssen wir im Auge behalten.

Voc 10c.JPG

Nun stehen wir vor einem kleinen Problem: Ist das Ende der Liste erreicht, bekommen wir mit dem nächsten Klick eine Fehlermeldung. Wir müssen dafür sorgen, dass bei Erreichen des Listenendes der Listenindex wieder auf 0 gesetzt wird, der Text des Buttons Next wieder auf Abfragen geändert wird und die beiden Labels LabelAsk und LabelShow einen leeren String erhalten. Damit kann das Abfragen wieder von vorne beginnen. Programmiertechnisch setzen wir das mit einer zweiseitigen bedingten Anweisung (if ... else) um.

Voc 10d.JPG

Die Anzeige des zugehörigen deutschen Wortes erfolgt analog zur Anzeige des englischen Wortes. Abhängig vom aktuellen Listenindex wird das entsprechende Item aus der Deutschliste in der TinyDB im Label LabelShow angezeigt.

Voc 12.JPG

Löschen des Datenspeichers

Insbesondere zu Testzwecken ist es günstig, wenn man die benutzte Datenbank löschen kann. Dazu wird mit der Methode ClearAll der Inhalt der TinyDB gelöscht, die Labels werden auf einen leeren String gesetzt und die Hilfsvariablen werden auf den Anfangswert zurückgesetzt. Für die endgültige App sollte vor dem endgültigen Löschen noch eine Sicherheitsabfrage an den User erfolgen, da das versehentliche Löschen einer Datenbank ärgerlich sein kann.

Voc 14.JPG

Initialisierung der Screen

Nun müssen wir uns noch Gedanken über die Initialisierung der Screen machen. Auf jeden Fall sollten wir den Text des Buttons ButtonAbfragen auf den Text Abfragen setzen. Zudem ist es günstiger das Laden der Daten gleich bei der Initialisierung der Screen vorzunehmen. Wir verlagern die entsprechenden Blöcke aus dem Block für das Speichern in die Initialisierung der Screen.

Voc 16.JPG

Beenden der Anwendung

Zum Schluss müssen wir nur noch, wie gewohnt, das Beenden der Applikation umsetzen.

Voc 15.JPG

Erweiterungsaufgaben

  • Die App funktioniert nun bei der vorgesehenen Verwendung ohne Probleme. Allerdings wird ein Beta-Test einige Probleme aufwerfen, die noch zu lösen sind. Beispiele:
    • Was tun bei einer fehlerhaften Eingabe?
    • Was passiert beim Speichern ohne vorherige Eingabe?

Lösung:

Um das Problem zu lösen bauen wir eine Gleichstellung der TextBoxEnglish mit einem leeren Textfeld in den Block "Speicher" ein und leiten dann den Benutzer, wenn das Textfeld leer ist, noch bevor die Vokabel gespeichert wird zu einen anderen Screen. Dort erhält er die Nachricht erst etwas einzugeben bevor er abspeichert. Beschreibung

    • Was passiert bei einer Abfrage bei leerer Liste?
  • Die Abfrage durchläuft immer die ganze gespeicherte Liste und das in derselben Reihenfolge der Vokabeln. Die Vokabeln sollen nun in zufälliger Reihenfolge abgefragt werden. Zusätzlich sollen dabei alle Vokabeln abgefragt werden.Mit Hilfe eines Buttons kann der Benutzer wieder zum ursprünglichem Screen zurück.
  • In der Praxis sollten nicht immer alle Vokabeln abgefragt werden, sondern zuerst die aktuellen Vokabeln. Dazu sollten die Vokabeln der letzten beiden Einheiten wiederholt werden und eventuell eine bestimmte Anzahl von Vokabeln aus früheren Einheiten. Dazu müssen wir in einer Liste der TinyDB auch die Anzahl der Vokabeln pro Einheit abfragen können und die gewünschten Vokabeln über eine Manipulation der Listenlänge erhalten können.
  • Es sollte auch möglich sein, die Abfragerichtung E-D/D-E festzulegen.
  • Der User sollte richtige und falsche Antworten kennzeichnen und seine Ergebnisse speichern können. Eine direkte Bewertung mit Eingabe der Lösung dürfte höchstens bei sehr einfachen Vokabeln Sinn machen. Vielleicht gibt es auch einen Weg, Vokabeln die nicht gewusst wurden, häufiger abzufragen.
  • Aus Designsicht wäre es wünschenswert, wenn nur jeweils die Bestandteile des Moduls zu sehen wären, das gerade verwendet wird (Eingabe, Abfrage und eventuell Einstellungen).