====== Komplexe Rotationen ======
Diese Anleitung befasst sich mit Designs, in welchen die Rotation bestimmten Regeln folgen soll.
In diese Fällen kommt man um ein wenig Programmierung nicht umhin, in welcher die Regeln in Programmcode gegossen werden. Und ja, zugegeben, das ist nicht immer ganz trivial. Aber hier gibt es einige Tipps zum Einstieg.
===== Grundlagen =====
==== isset() ====
Zunächst sollte man mit der Kombination aus ''isset()'' und ''registerVariable()'' vertraut sein. Die PHP-Funktion ''isset()'' prüft, ob eine [[:de:create:variables|PHP-Variable]] bereits definiert wurde. Da PHP-Variablen normalerweise nur innerhalb eines PHP-Code-Blocks gültig sind, wird das erst in Verbindung mit ''[[:de:create:functions:registervariable]]'' interessant. Diese Funktion sorgt nämlich dafür, dass die PHP-Variable in allen künftigen PHP-Blöcken auf allen Seiten verfügbar ist.
Wir prüfen also mit ''isset()'', ob es eine Variable -- unsere Rotationsabfolge -- bereits gibt. Und wenn nicht, dann definieren wir sie (die eigentlich Arbeit) und halten Sie mittels ''registerVariable()'' vor, sodass sie bei der nächsten Wiederholung der Seite vorliegt.
Hier einmal das Grundgerüst. Das Ausrufezeichen (''!'') ist eine Verneinung, ''!isset()'' prüft also, ob eine Variable //noch nicht// definiert wurde.
if (!isset($abfolge)) {
// Hier kommt dann die eigentliche Arbeit,
// die gewünschte Rotation zu definieren
$abfolge = [];
// ...
// ...
// Und zuletzt macht man die Variable für weitere
// PHP-Durchläufe oder für weitere Seiten verfügbar
registerVariable($abfolge);
}
Warum //Wiederholung der Seite//? Weil die Stimuli in aller Regel auf separaten Seite präsentiert werden sollen, und dafür kommt häufig ''loopPage()'' zum Einsatz, welches die Seite immer und immer wieder anzeigt (siehe unten).
==== Arrays und shuffle() ====
Für die Organisation der Abfolge benötigt man in aller Regel eine oder mehrere Listen. Listen werden in PHP als Arrays bezeichnet. Bitte lesen Sie das folgende Kapitel, damit Sie wissen, was es mit den eckigen Klammern in unterschiedlichen Variationen auf sich hat: [[:de:create:array]]
Die Funktion ''shuffle()'' übernimmt dann die eigentliche Rotation, also das zufällige Mischen der Liste. Als Parameter erwartet sie ein Array. Dieses wird dann einfach gemischt.
Hier erneut das Grundgerüst von Definition und Mischen eines Arrays.
$stimuli = [1,2,3,4,5,6,7,8,9,10];
shuffle($stimuli);
// In der Liste könnte nun z.B. stehen
// [2,9,3,4,10,7,8,1,6,5]
Je nachdem, was Sie für die Auswertung planen, kann es sinnvoll sein, diese Abfolge auch im Datensatz zu hinterlegen. Dafür kommt die Funktion ''[[:de:create:functions:putlist]]'' zum Einsatz. Sie speichert ein Array in die entsprechende Anzahl [[:de:create:questions:internal|interner Variablen]].
putList('IV01', $stimuli);
==== loopPage() ====
Die Funktion ''[[:de:create:functions:looppage]]'' wiederholt eine Seite so oft, wie Sie möchten. Und natürlich möchten Sie in aller Regel bei jedem Durchlauf etwas anders anzeigen. Was das ist, das hängt von Ihrem Stimulus ab.
Nehmen wir einmal an, Sie möchten unterschiedliche Bilder präsentieren und jeweils eine Frage dazu stellen. Dann definieren Sie die Bild-Namen als weiteres Array und legen Sie eine entsprechende Anzahl Fragen im Fragenkatalog an ("FR01" bis "FR10"). Und dann zeigen Sie in jedem Durchlauf eines der Bilder und eine der Fragen. Die Funktion ''[[:de:create:functions:id]]'' vereinfacht das Erstellen der Frage-Kennung.
// Liste der Bilder definieren
$bilder = [
1 => 'stimulus01P.jpg',
2 => 'stimulus01N.jpg',
3 => 'stimulus02P.jpg',
// ...
10 => 'stimulus05N.jpg'
];
// In jedem Durchlauf einen anderen Eintrag aus $stimuli verwenden
$bildID = loopPage($stimuli);
// Bild anzeigen
$dateiname = $bilder[$bildID];
html('
');
// Frage anzeigen
$fragenkennung = id('FR', $bildID);
question($fragekennung);
**Warnung:** ''loopPage()'' verträgt sich nicht mit ''[[:de:create:functions:setpageorder]]'', ''loopToPage()'' oder ''setNextPage()''. Verschachteln Sie diese Befehle nicht, nutzen Sie ''loopPage()'' also z.B. nicht in einer vorher per ''setPageorder()'' definierten Seitenabfolge.
==== FOR-Schleifen ====
In der Programmierung meint man mit dem Begriff "Schleife", dass derselbe Code mehrfach wiederholt wird. So ähnlich wie bei ''loopPage()'', nur dass das auf derselben Seite im selben PHP-Code erfolgt. Und wie bei ''loopPage()'' wird das erst interessant, wenn man bei jeder Wiederholung etwas ändert.
Eine Möglichkeit ist die FOR-Schleife, bei welcher eine Zahl hochgezählt und als Variable definiert wird. Die folgende FOR-Schleife zählt die Variable ''$i'' von 0 bis 9 durch. Also 10 Wiederholungen. Warum beginnt man bei 0? Weil es sich oftmals leichter rechnet und die Array-Indizes in PHP (wie auch in vielen anderen Programmiersprachen) bei 0 beginnen.
for ($i=0; $i<10; $i++) {
// ...
}
Das ''$i++'' besagt, dass ''$i'' in jedem Durchgang um eins hochgezählt wird. Zwischen den geschweiften Klammern (''{...}'')) steht dann, was in jedem Durchlauf passieren soll.
Nur als Beispiel: Wir könnten so eine Schleife verwenden, um das Array ''$stimuli'' Element-für-Element in ein neues Array ''$abfolge'' zu kopieren. Das ist nicht effizient, demonstriert aber die Grundidee.
$abfolge = [];
for ($i=0; $i<10; $i++) {
$abfolge[] = $stimuli[$i];
}
Wie Sie in der [[:de:create:array]] gelesen haben, schreibt ''$abfolge[] = ...'' ein neues Element ans Ende des Array ''$abfolge''.
==== Logik ====
Mit diesen Bausteinen lassen sich nun auch komplexe Rotationen bauen und im Fragebogen präsentieren.
Nun kommt allerdings der anspruchsvolle Teil: Man muss das Schema zu Papier bringen. Und dann auf den Bildschirm. Zu Papier bringen heißt, man skizziert tatsächlich einmal, was woher kommt und wohin muss.
Nehmen wir einmal das folgende Beispiel: Es gibt für die Studie insgesamt 32 Bilder, diese sind 3 Kategorien zugeordnet:
* 16 Bilder sind neutral,
* 8 Bilder sind positiv und
* 8 Bilder sind negativ.
Nun soll im Fragebogen jeweils ein positives Bild präsentiert werden, dann ein neutrales, dann ein negatives und dann nochmal ein neutrales, und das solange, bis alle Bilder durch sind. Und abgesehen davon soll die Abfolge natürlich rotiert werden. Auf ein Blatt Papier skizziert könnte das wie folgt aussehen:
{{:de:create:fig.rotation-complicated.logic.jpg?nolink|Skizze der Ablauf-Logik}}
Wir brauchen also 3 Urnen (ja, dafür könnte man anstatt ''shuffle()'' auch einen [[:de:create:questions:random|Zufallsgenerator]] verwenden), aus welchen wir die Bilder ziehen. In der Skizze als Kreise dargestellt. In der Programmierung sind das dann natürlich Arrays. An die Pfeile ist jeweils geschrieben, welchen Array-Index das Bild jeweils hat.
An erster Stelle steht ein positives Bild, das erste aus der Positivliste, es hat also den Index 0. Dann kommt ein neutrales Bild. Das ist ebenfalls das erste aus der Neutralliste, hat also auch den Index 0. Dann ein negatives Bild und dann wird es interessant: Das letzte Bild im ersten Block ist nochmal neutral. Da müssen wir natürlich ein anderes nehmen, also brauchen wir hier den Index 1.
Im zweiten Block sind die Indizes dann positiv:1, neutral:2, negativ:1 und neutral:3. Wie das dann in der Programmierung umgesetzt wird, das zeigt das erste Beispiel unten.
Wichtig ist noch zu wissen, dass wir diesen 4er-Block 8-mal wiederholen, um alle 32 Bilder zu präsentieren.
===== Schema wiederholen =====
Das erste Beispiel wurde oben beim Abschnitt [[#logik|Logik]] bereits erklärt: Wir möchten 32 Bilder (neutral, positiv, negativ) nach einem festen Schema -- aber rotiert -- präsentieren.
Wir wissen auch schon, dass wir 3 Arrays benötigen und daraus 8 Blöcke à 4 Bilder zusammenbauen müssen.
==== Schritt 1 ====
Im ersten Schritt abstrahieren wir erstmal von den Dateinamen und vergeben den Bildern Nummern. Der Übersichtlichkeit halber sind das sie Nummern 1 bis 16 für die neutralen Bilder, 21 bis 28 für die positiven Bilder und 31 bis 38 für die negativen Bilder.
Warum machen wir das? Weil wir dann nur noch Nummern mischen müssen. Das hat zwei Vorteile:
* Nummern kann man einfacher im Datensatz speichern und
* Wir können passend zu den Nummern Fragen anlegen, die dann fix einem Bild zugeordnet sind. Die Frage "BE22" würde also fix zum zweiten positiven Bild gehören.
$bilder = [
// neutrale Bilder
1 => 'bild.N1.jpg',
2 => 'bild.N2.jpg',
3 => 'bild.N3.jpg',
// ...
16 => 'bild.N16.jpg',
// positive Bilder
21 => 'bild.P1.jpg',
// ...
28 => 'bild.P8.jpg',
// negative Bilder
31 => 'bild.N1.jpg',
// ...
38 => 'bild.N8.jpg'
];
Die Punkte (''...'') sind natürlich mit Bildnamen zu füllen.
==== Schritt 2 ====
Im zweiten Schritt definieren wir die drei Listen und mischen diese mittels ''shuffle()''. Hier legen wir nur noch die Nummern der Bilder in die Arrays.
$neutral = [1,2,3, ... 16];
$positiv = [21,22,23, ... 28];
$negativ = [31,32,33, ... 38];
shuffle($neutral);
shuffle($positiv);
shuffle($negativ);
==== Schritt 3 ====
Anschließend wird die Gesamtliste mit 32 Bilder-Codes, bestehend aus 8 Blöcken à 4 Bildern zusammengebaut. Hier kommt eine FOR-Schleife zum Einsatz. Ein Durchlauf für jeden (gleichartigen) Block.
Oben hatten wir erklärt, dass wir im ersten Durchlauf folgende Indizes (Zählung beginnt bei 0) aus den drei Listen benötigen:
* positiv:0, neutral:0, negativ:0 und neutral:1
Im zweiten und dritten Durchlauf benötigen wir dann folgende Indizes (s. Skizze oben):
* positiv:1, neutral:2, negativ:1 und neutral:3
* positiv:2, neutral:4, negativ:2 und neutral:5
Wie kommen wir von einer Zählvariable ''$i'' der FOR-Schleife ''[0,1,2,...,7]'' auf diese Werte? Für die positiven und negativen Einträge ist es trivial, da können wir die Variable direkt verwenden. Für die neutralen Einträge müssen wir rechnen. Spoiler: Wir müssen am Ende nicht von 1 bis 8 zählen sondern von 1 bis 16, also multiplizieren wir mit 2. Und für den jeweils zweiten Wert im Block addieren wir dann einfach noch 1.
* für ''$i=0'' bekommen wir dann also 0 (2-mal 0) und 1
* für ''$i=1'' bekommen wir 2 (2-mal 1) und 3
* für ''$i=2'' bekommen wir 4 (2-mal 2) und 5
* und so weiter, also genau das was wir benötigen
Wie sieht das mit der FOR-Schleife und dem Zählen und dem Zusammenbauen in PHP-Code aus?
// Zunächst brauchen wir eine leere Liste, wo die neuen Einträge hinein kommen
$abfolge = [];
for ($i=0; $i<8; $i++) {
$abfolge[] = $positiv[$i];
$abfolge[] = $neutral[2 * $i];
$abfolge[] = $negativ[$i];
$abfolge[] = $neutral[2 * $i + 1];
}
In jedem Durchlauf werden dem Array ''$ablauf'' also 4 Werte hinzugefügt. Und zwar immer die, welche wir laut Skizze oben haben wollten.
==== Schritt 4 ====
Zuletzt möchten wir die Bilder und zugehörige Fragen ("BE01" bis "BE38") natürlich noch im Fragebogen anzeigen. Und zwar auf einzelnen Seiten. Hierfür kommt nun ''loopPage()'' zum Einsatz. Es verwendet die vorher definierte Liste und arbeitet diese Eintrag für Eintrag ab.
$bildID = loopPage($abfolge);
// Bild anzeigen
$dateiname = $bilder[$bildID];
html('
');
// Frage anzeigen
$fragenkennung = id('BE', $bildID);
question($fragekennung);
Natürlich könnte man in der Abfolge auch Seitennamen speichern und diese an ''setPageOrder()'' übergeben, wenn man Seiten in einer bestimmten Reihenfolge präsentieren möchte. Aber mit ''loopPage()'' muss man nur eine Seite anlegen statt 32 Seiten. Das ist deutlich schneller, übersichtlicher und weniger fehleranfällig.
Der HTML-Code zur Anzeige der Bilder wird hier erklärt: [[:de:create:images]] und [[:de:create:randomization-einfaktoriell]]
==== Alles zusammenbauen ====
Im letzten Schritt muss alles zusammengebaut werden. Und wir benötigen ''isset()'' und ''registerVariable()'', damit die Abfolge nicht bei jeder Wiederholung erneut gemischt wird.
Außerdem erstellen wir noch eine interne Variable ''IV01'' mit 32 Variablen, um die Abfolge auch zu speichern. Für den Fall, dass wir in der Auswertung Reihenstellungseffekte kontrollieren möchten. Die Bilderliste (''$bilder'') wird besser jedesmal neu definiert, dann brauchen wir die Bildnamen nicht in jedem Interview zu speichern, das würde nur Speicherplatz verschwenden.
$bilder = [
// neutrale Bilder
1 => 'bild.N1.jpg',
2 => 'bild.N2.jpg',
3 => 'bild.N3.jpg',
// ...
16 => 'bild.N16.jpg',
// positive Bilder
21 => 'bild.P1.jpg',
// ...
28 => 'bild.P8.jpg',
// negative Bilder
31 => 'bild.N1.jpg',
// ...
38 => 'bild.N8.jpg'
];
if (!isset($abfolge)) {
$neutral = [1,2,3, ... 16];
$positiv = [21,22,23, ... 28];
$negativ = [31,32,33, ... 38];
shuffle($neutral);
shuffle($positiv);
shuffle($negativ);
$abfolge = [];
for ($i=0; $i<8; $i++) {
$abfolge[] = $positiv[$i];
$abfolge[] = $neutral[2 * $i];
$abfolge[] = $negativ[$i];
$abfolge[] = $neutral[2 * $i + 1];
}
// Abfolge auch im Datensatz ablegen
putList('IV01', $abfolge);
registerVariable($abfolge);
}
// Einträge jeweils auf einer eigenen Seite präsentieren
$bildID = loopPage($abfolge);
// Bild anzeigen
$dateiname = $bilder[$bildID];
html('
');
// Frage anzeigen
$fragenkennung = id('BE', $bildID);
question($fragekennung);