0 votes
in SoSci Survey (dt.) by s046155 (210 points)

Hallo lieber Sosci Survey Online Support,

ich versuche gerade Fragen mit shuffle() für meine vier Teilnehmer-Untergruppen zu rotieren.

Aktuell leite ich die 2x2 Untergruppen (die aus 2 Hauptgruppen mittels Urnenziehung gezogen wurden) erfolgreich zur richtigen Fragenkombi der Demoseite am Anfang zu.
Dafür nutze ich die folgenden 4 php-Codes:
....

// Gruppe A sieht A-Videos

if (value('GR07_01') == 'R_02') {
  question('RD03');
  question('RD16');
}

....

// Gruppe A sieht B-Videos

if (value('GR07_01') == 'R_01') {
  question('ES03');
  question('ES16');
}

...

// Gruppe B sieht A-Videos

if (value('GR08_01') == 'S_01') {
  question('ES02');
  question('ES16');
}

...

// Gruppe B sieht B-Videos

if (value('GR08_01') == 'S_02') {
  question('RD02');
  question('RD16');
}

...
Nun würde ich gern die folgenden 6 Fragenkombis pro Untergruppe rotieren lassen.
In einem 1. Schritt habe ich mich an der Rotation von 3 Fragenkombis versucht:

if (!isset($blocks)) {
  // Liste mit Frage-Kennungen und zugehörigen Bildern
  $blocks = [
    ['ES04', 'ES17'],
    ['ES06', 'ES18'],
    ['ES08', 'ES20'],
  ];
 
  // Die Liste mischen
  shuffle($blocks);
  // Die Listen auf allen Seiten verfügbar machen
  registerVariable($blocks);
}
 
// Anzeige der Blöcke
$i = loopPage(count($blocks));
 
// Frage anzeigen
question($blocks[$i]);

Laut Debug-Info werden auch immer jeweils 2 Fragen erstellt, also z.B. ES08 und ES20. Leider ist jedoch nur jeweils die 1. Frage auch sichtbar --> hier ES08
Das mit dem shufflen scheint ansonsten zu funktionieren :)

Daneben frage ich mich noch, wie ich meine Gruppenauswahl, z.B.

if (value('GR07_01') == 'R_02')

und die Rotation

if (!isset($blocks))

verbinden kann.

Für Hilfe bin ich sehr dankbar!

Beste Grüße,
Jule

1 Answer

0 votes
by SoSci Survey (329k points)
selected by s046155
 
Best answer

In Ihrem PHP-Code mischen Sie die Reihenfolge der drei Blöcke innerhalb von $blocks. Dabei könnte z.B. herauskommen:

[
    ['ES08', 'ES20'],
    ['ES06', 'ES18'],
    ['ES04', 'ES17']
];

Oder mit Indizes geschrieben:

[
    0 => ['ES08', 'ES20'],
    1 => ['ES06', 'ES18'],
    2 => ['ES04', 'ES17']
];

Wenn Sie nun $blocks[$i] abrufen, und $i hat in der ersten Runde den Wert 0, dann bekommen Sie zurück:

['ES08', 'ES20']

Wenn Sie das an question() übergeben, wird der Befehl versuchen, eine kombinierte Frage aus den beiden Fragen zu basteln.

question(['ES08', 'ES20']);

Wenn Sie die beiden Fragen separat anzeigen möchten, dann brauchen Sie auch zweimal question(), und müssen in jedem befehl nur auf eine der beiden Kennungen verweisen:

question($blocks[$i][0]);
question($blocks[$i][1]);

Oder etwas allgemeiner geschrieben:

foreach ($blocks[$i] as $frage) {
    question($frage);
}
by s046155 (210 points)
Vielen Dank! Es klappt perfekt.

Zum 2. Teil meiner Frage habe ich mir jetzt überlegt, dass ich die Untergruppen ja jeweils auf separate Seiten leiten könnte und dort dann für jede Untergruppe den entsprechenden !isset - Befehl platzieren könnte.
Ist das schon zu kompliziert? Gibt es einen "sinnvolleren" Weg meine Untergruppen mit der richtigen "Rotationsgruppe" zu verbinden?

Beste Grüße
by SoSci Survey (329k points)
Separate Seiten machen es - meiner Meinung nach - immer komplizierter, machen Ärger mit dem Fortschrittsbalken und führen aufgrund der Komplexität zu Fehlern.

Worin unterscheiden sich die Untergruppen denn? Ich würde nur das mit einem PHP-Filter austauschen.
by s046155 (210 points)
Die Untergruppen unterscheiden sich wie folgt:
Gr. A1 --> Intro A --> sieht A-Videos
Gr. A2 --> Intro A --> sieht B-Videos
Gr. B1 --> Intro B --> sieht A-Videos
Gr. B2 --> Intro B --> sieht B-Videos

Dabei wurden die A- und B-Untergruppen jeweils aus 2 getrennten Urnen gezogen, in denen sie nach einer Filterfrage zur Häufigkeit eines bestimmten Verhaltens gelandet sind.

Wie könnte ich die Befehle kombinieren?

if (value('GR07_01') == 'R_02')

if (!isset($blocks))
by SoSci Survey (329k points)
Ich würde das Array (dessen Variable dann erstmal ander heißen muss als $blocks) in Abhängigkeit von GR07_01 definieren und dann das Mischen und registerVariable() im isset()-IF belassen.
by s046155 (210 points)
Hallo nochmal,

ich habe leider den letzten Kommentar nicht umgesetzt bekommen und daher doch auf die 4 verschiedenen Seiten zurückgegriffen und dort dann den Fortschrittsbalken angepasst.

Nach den Intro+Video-Blöcken sollen den Teilnehmern allerdings noch 2 Video-spezifische Fragen einzeln auf 2 Folgeseiten präsentiert werden.

Für eine der Fragen mit der Kennung "AT" habe ich versucht in Abhängigkeit der Block-Abfolge die entsprechende Frage anzeigen zu lassen.

Mein Code dazu sieht wie folgt aus:
-----------------------------------
if (value('GR08_01') == 'S_01') {

    if (!isset($blocks)) {
  // Liste mit Frage-Kennungen - Intro + Video
  $blocks = [
    ['ES04', 'ES17'],
    ['ES06', 'ES18'],
    ['ES08', 'ES20'],
    ['ES10', 'ES19'],
    ['ES12', 'ES22'],
    ['ES14', 'ES21']
  ];
 
  // Die Liste mischen
  shuffle($blocks);
  // Die Listen auf allen Seiten verfügbar machen
  registerVariable($blocks);
}
 
// Anzeige der Blöcke
$i = loopPage(count($blocks));
 
// Fragen anzeigen
foreach ($blocks[$i] as $frage) {
    question($frage);
}
{
// AT-Fragen anzeigen
$fragekennung = id('AT', $blocks);
question($fragekennung);
}
}
---------------------------------

Leider bekomme ich dazu folgende Debug-Infos:

"Die Funktion id() erwartet als Parameter Nr. 2 einen Wert vom Typ integer. Es wurde ein Wert (Array [Array [ES14, ES21], Array [ES10, ES19], Array [ES08, ES20], ...]) vom Typ array angegeben."

sowie

"Im Befehl question() wurde keine Frage-Kennung angegeben."
(ich vermute, dass sich das aus dem oberen Fehler ergibt)

Ist es richtig, dass mir die 1. Fehlermeldung sagt, dass durch die Arrays jeweils nicht klar ist, ob z.B. ES14 oder ES21 als Bezug gemeint ist? Falls ja, wie kann ich das auflösen und trotzdem beide gemeinsam auf einer Seite anzeigen lassen? Den Bezug den ich gerne für die Folgefragen hätte, wäre jeweils die 2. Frage in den Blöcken (bei mir ein Video, z.B. ES21), sodass die richtigen Anschlussfragen auf den Folgeseiten gezeigt werden --> aber die müssen dann ja auch mit rotieren.

Ich habe auch nochmal die Infos zu arrays gelesen, komme aber einfach nicht weiter.

Leider reichen meine php-Kenntnisse nicht weit, sodass ich noch einmal sehr dankbar für Hilfe wäre!
by SoSci Survey (329k points)
Sie übergeben in dieser Zeile ein komplettes (verschachteltes) Array an die Funktion id():

$fragekennung = id('AT', $blocks);

Was bezwecken Sie denn mit dem Teil ab "// AT-Fragen anzeigen"? Dies scheint mir nicht notwendig, weil sich das foreach() darüber ja bereits um die Fragen kümmert.
by s046155 (210 points)
Hallo nochmal und danke für die Rückfrage.

Das Ziel ist, die mit den Blöcken, z.B. ['ES04', 'ES17'] verbundene Folgefrage, z.B. AT01 auf einer Seite nach dem Block anzeigen zu lassen.
Ich dachte, dass mit der Definition der Blöcke diesen auch Nummern von 1-6 zugewiesen werden und anhand dieser BlockID wollte ich gern die richtige Frage auf einer Seite nach einem Block anzeigen.

Viele Grüße
by SoSci Survey (329k points)
Das heißt, Sie haben die Blöcke nur, damit die Reihenfolge erhalten bleibt? Umso besser, dann lösen Sie das verschachtelte Array nach dem Mischen bitte einfach auf und brauchen sich dann um die Blöcke nicht mehr zu kümmern.

...
shuffle($blocks);
$questions = [];
foreach ($blockas as $block) {
  $questions = array_merge($questions, $block);
}
registerVariable($questions);

Das isset() muss dann natürlich $questions prüfen und nicht mehr Blocks und unten dann:

$id = loopPage($questions);
question($id);
by s046155 (210 points)
Ich habe die Blöcke, damit Intro + Video auf einer Seite sind und das ganze habe ich 6 Mal und das ergibt meine Blöcke, die ich gern randomisiert/rotiert präsentieren möchte. Dazu kommt jetzt aber noch das auf jede der 6 Intro+Video-Kombis noch eine block-spezifische Frage auf einer Folgeseite erscheinen soll. Die müsste also entsprechend fest mit dem Block verbunden mit rotiert werden.

Ich versuche die Hinweise morgen erstmal nach bestem Verständnis umzusetzen.
Vielen Dank für die, wie immer, sehr zügige Hilfestellung!
by s046155 (210 points)
Hallo nochmal,

ich habe mich jetzt an folgenden 2 Varianten versucht und unterschiedliche, nicht funktionierende ;) Ergebnisse bekommen.

1. Versuch:

if (!isset($questions)) {

// Liste mit Frage-Kennungen und zugehörigen Bildern als array definieren
  $blocks = [
    ['ES04', 'ES17'],
    ['ES06', 'ES18'],
    ['ES08', 'ES20'],
    ['ES10', 'ES19'],
    ['ES12', 'ES22'],
    ['ES14', 'ES21']
  ];

// Die Liste mischen
  shuffle($blocks);

// Liste mit Folgefragen als array definieren
$questions = ['AT04', 'AT08', 'AT10', 'AT06', 'AT02', 'AT12'];

// Zuordnung der Blöcke zu Folgefragen
foreach ($blocks as $blocks) {
  $questions = array_merge($questions, $blocks);
}

// Die Listen auf allen Seiten verfügbar machen
registerVariable($questions);

// Anzeige der Blöcke und Fragen
$id = loopPage($questions);
question($id);
}
}

Das Ergebnis dabei war, dass mir die Intro+Video-Kombis nicht mehr angezeigt wurden, sondern sofort die erste Folgefrage AT04. Daneben stand in den Debug-Infos, dass die Seite jetzt 18 mal wiederholt würde, obwohl es nur 6 Blöcke sind?
Bei einem Klick auf WEITER wird nichts angezeigt und die Debug-Info sagt 18 mal "Die Seite zeigt keine Inhalte.".

Weil die Blöcke iwie verschwunden schienen, habe ich es im 2. Anlauf dann mit zwei isset() - Befehlen versucht. Aber das war wahrscheinlich nicht so schlau und hat im Ergebnis auch nicht funktioniert.


2. Versuch:

    if (!isset($blocks)) {

// Liste mit Frage-Kennungen und zugehörigen Bildern als array definieren
  $blocks = [
    ['ES04', 'ES17'],
    ['ES06', 'ES18'],
    ['ES08', 'ES20'],
    ['ES10', 'ES19'],
    ['ES12', 'ES22'],
    ['ES14', 'ES21']
  ];

// Die Liste mischen
  shuffle($blocks);

// Die Listen auf allen Seiten verfügbar machen
  registerVariable($blocks);
}
 
// Anzeige der Blöcke auf einzelnen Seiten
$i = loopPage(count($blocks));

// Blöcke anzeigen
foreach ($blocks[$i] as $frage) {
    question($frage);
}

if (!isset($questions)) {

// Liste mit Folgefragen als array definieren
$questions = [
    'AT04',
    'AT08',
    'AT10',
    'AT06',
    'AT02',
    'AT12'
 ];

// Zuordnung der Blöcke zu Folgefragen
foreach ($blocks as $blocks) {
  $questions = array_merge($questions, $blocks);
}

// Die Listen auf allen Seiten verfügbar machen
registerVariable($questions);

// Anzeige der Blöcke und Fragen
$id = loopPage($questions);
question($id);
}
}

Ergebnis:
Hier wurden mir dann wieder die Blöcke auf einzelnen Seiten richtig angezeigt.
Leider wurde die erste Folgefrage AT04 (die richtig zugeordnet wurde) direkt darunter angezeigt und nicht auf einer Folgeseite. Daneben zeigt die Debug-Info auch hier, dass die Seite nun 18 mal wiederholt wird, obwohl es nur 6 Wiederholungen sein dürften.

Klicke ich dann auf WEITER um den nächsten Block aufzurufen, kriege ich einen Hinweis zu einem Fehler im Fragebogen zu der Zeile
"030 foreach ($blocks[$i] as $frage) {"


Sicher habe ich einen Fehler in der Abfolge der einzelnen Code-Bausteine gemacht?
by SoSci Survey (329k points)
> Dazu kommt jetzt aber noch das auf jede der 6 Intro+Video-Kombis noch eine block-spezifische Frage auf einer Folgeseite erscheinen soll.

Dann sollten Sie alle drei Fragen bzw. Texte direkt in die Blöcke schreiben. Also, wenn diese auf drei unterschiedlichen Seiten erscheinen sollen.

$blocks = [
    ['ES04', 'ES17', 'AT04'],
    ['ES06', 'ES18', 'AT08'],
    u.s.w.

Dann das shuffle und das

foreach ($blocks as $blocks) {
  $questions = array_merge($questions, $blocks);
}
registerVariable($questions);

um die verschachtelte Liste "flach" zu machen. Und unter den Block dann natürlich noch das loopPage() mit question(). Das kommt aber nicht mit im isset()-Filter, sondern darunter.
by s046155 (210 points)
Dabei landen alle Fragen auf separaten Seiten.

Ich möchte aber erreichen, dass nur die ersten beiden Fragen auf einer Seite landen.
Die Anschlussfrage AT soll dann nach dem Klick auf WEITER auf einer nächsten Seite kommen.
Und trotzdem gehören alle Fragen quasi zu einem Block, da die AT-Frage sich jeweils auf die vorherigen (z.B. ES04 und ES17) bezieht.
by SoSci Survey (329k points)
> Die Anschlussfrage AT soll dann nach dem Klick auf WEITER auf einer nächsten Seite kommen.

Gut, dann bildern wir das eben so im Array ab :)

$blocks = [
    [['ES04', 'ES17'], ['AT04']],
    [['ES06', 'ES18'], 'AT08']],
    u.s.w.

Bei der Ausgabe dann entsprechend:

$id = loopPage(count($questions));
$qPack = $questions[$id];
foreach ($qPack as $qID) {
  question($qID);
}
by s046155 (210 points)
edited by s046155
Auch auf die Gefahr hin, dass sich das hier zum längsten Support-Thread überhaupt entwickelt, muss ich noch eine Nachfrage stellen ;) .

Der Code funktioniert fast perfekt, allerdings habe ich noch zwei Probleme:

1. Überlagern sich die ersten beiden Fragen (z.B. ES04, ES17) irgendwie, also beide werden lt. debug erstellt, aber sichtbar ist nur die jeweils erste (hier ES04) der beiden. Irgendwie werden die wohl kombiniert?

2. Wenn nach Klick auf WEITER die AT-Frage auf der Folgeseite erscheint, werden darüber auch die beiden Fragen, z.B. ES04 und ES17 angezeigt (auch wieder überlagert) --> Frage AT wird 1a dargestellt. Falls Problem 2 nicht so einfach lösbar ist, könnte ich damit aber zur Not auch leben.

Der Vollständigkeit halber noch der Code zum Ergebnis:


    if (!isset($blocks)) {
// Liste mit Frage-Kennungen und zugehörigen Bildern
  $blocks = [
    [['ES05', 'ES17'], ['AT04']],
    [['ES07', 'ES18'], ['AT08']],
    [['ES09', 'ES20'], ['AT10']],
    [['ES11', 'ES19'], ['AT06']],
    [['ES13', 'ES22'], ['AT02']],
    [['ES15', 'ES21'], ['AT12']]
  ];
 
// Die Liste mischen
  shuffle($blocks);

// Die Listen auf allen Seiten verfügbar machen
  registerVariable($blocks);
}
 
// Fragen anzeigen
$id = loopPage(count($blocks));
$qPack = $blocks[$id];
foreach ($qPack as $qID) {
  question($qID);
}

Danke nochmal für den besten Support, den ich je erlebt habe und entspannte Ostern!
by SoSci Survey (329k points)
> Irgendwie werden die wohl kombiniert?

Ja, Sie haben in Ihrem Code den Teil mit dem array_merge() vergessen. Oben brauchen Sie ein

if (!isset($questions)) {

und vor der schließenden Klammer dann statt

  registerVariable($blocks);

ein

  foreach ($blocks as $blocks) {
    $questions = array_merge($questions, $blocks);
  }
  registerVariable($questions);

Sonst haben Sie die Blöcke wieder nicht auf 2 Seiten.
by s046155 (210 points)
Nachdem ich die Fehlermeldung bekommen habe, dass $questions noch nicht definiert wurde und daher ein Fehler in der Zeile

$questions = array_merge($questions, $blocks);

angezeigt wurde, habe ich dem Code nochmal separat das Array für questions zugefügt. (Obwohl ich dachte, dass das in den Blocks schon drin steckt)

Daraufhin wird die Seite leider wieder 18 mal wiederholt und eine neue Fehlermeldung "Invalid argument supplied for foreach()" taucht auf für die folgende Zeile:

foreach ($qPack as $qID) {


Mein Code insgesamt:

if (!isset($questions)) {

// Liste mit Frage-Kennungen und zugehörigen Bildern
  $blocks = [
    [['ES05', 'ES17'], ['AT04']],
    [['ES07', 'ES18'], ['AT08']],
    [['ES09', 'ES20'], ['AT10']],
    [['ES11', 'ES19'], ['AT06']],
    [['ES13', 'ES22'], ['AT02']],
    [['ES15', 'ES21'], ['AT12']]
  ];

// Liste mit Folgefragen als array definieren
$questions = [
    'AT04',
    'AT08',
    'AT10',
    'AT06',
    'AT02',
    'AT12'
 ];
 
// Die Liste mischen
  shuffle($blocks);

// Arrays verbinden
foreach ($blocks as $blocks) {
    $questions = array_merge($questions, $blocks);
  }
  registerVariable($questions);
}

// Fragen anzeigen
$id = loopPage(count($questions));
$qPack = $questions[$id];
foreach ($qPack as $qID) {
  question($qID);
}
}
by SoSci Survey (329k points)
Stimmt, da fehlt noch eine Zeile:

// Arrays verbinden
$questions = [];   // diese Zeile fehlte
foreach ($blocks as $blocks) {
    $questions = array_merge($questions, $blocks);
}
registerVariable($questions);

Das obere $questions = [...] sollten Sie aber wieder rauswerfen.
by s046155 (210 points)
Ich kann es kaum glauben, aber jetzt funktioniert die Befragung tatsächlich wie geplant :)

Tausend Dank!

VG

Willkommen im Online-Support von SoSci Survey.

Hier bekommen Sie schnelle und fundierte Antworten von anderen Projektleitern und direkt von SoSci Survey.

→ Eine Frage stellen


Welcome to the SoSci Survey online support.

Simply ask a question to quickly get answers from other professionals, and directly from SoSci Survey.

→ Ask a Question

...