0 votes
in SoSci Survey (dt.) by s048351 (165 points)

Liebes SoSci-Team,

ich möchte für eine Studie 14 Seiten ('OP1' bis 'OP14') rotieren, auf denen sich jeweils ein Hörbeispiel und die dazugehörige Frage befinden. Die Schwierigkeit ist, dass einige Kombinationen ausgenommen werden sollen, da sich die Hörbeispiele sehr ähneln und nicht direkt nacheinander abgefragt werden sollen.
Aus den Folgenden Paaren (bzw. Tripeln) an Seiten sollen nicht zwei hintereinander in beliebiger Reihenfolge abgefragt werden:
(1, 2)
(3, 4)
(5, 6)
(7, 8)
(9, 10, 13)
(11, 12, 14).

Aktuell beinhaltet mein Code die etwas "unschöne" Variante, dass ich alle Fälle aufzähle, die ausgeschlossen werden sollen. Also jede der oben genannten Kombinationen an allen möglichen Positionen.
Dieser Code steht auf einer Seite; die kommenden Seiten im Fragebogen sind dann OP1 bis OP14.

"
if (!isset($seiten)) {
$seiten = array('OP1','OP2','OP3','OP4','OP5','OP6','OP7','OP8','OP9','OP10','OP11','OP12','OP13','OP14');
shuffle($seiten);

// Solange eine der nicht erwünschten Reihenfolgen vorliegt, mische noch einmal
// while (Bedingung) {Anweisung}

while (
//OP1 und OP2

    $seiten[1] == 'OP1' && $seiten[2] = 'OP2'
 || $seiten[1] == 'OP2' && $seiten[2] == 'OP1'  
 || $seiten[2] == 'OP1' && $seiten[3] == 'OP2' 
 || $seiten[2] == 'OP2' && $seiten[3] == 'OP1'  
 || $seiten[3] == 'OP1' && $seiten[4] == 'OP2'  
 || $seiten[3] == 'OP2' && $seiten[4] == 'OP1'  
 || $seiten[4] == 'OP1' && $seiten[5] == 'OP2'  
 || $seiten[4] == 'OP2' && $seiten[5] == 'OP1'  
 || $seiten[5] == 'OP1' && $seiten[6] == 'OP2' 
 || $seiten[5] == 'OP2' && $seiten[6] == 'OP1' 
 || $seiten[6] == 'OP1' && $seiten[7] == 'OP2'  
 || $seiten[6] == 'OP2' && $seiten[7] == 'OP1' 
 || $seiten[7] == 'OP1' && $seiten[8] == 'OP2' 
 || $seiten[7] == 'OP2' && $seiten[8] == 'OP1' 
 || $seiten[8] == 'OP1' && $seiten[9] == 'OP2' 
 || $seiten[8] == 'OP2' && $seiten[9] == 'OP1'
 || $seiten[9] == 'OP1' && $seiten[10] == 'OP2'  
 || $seiten[9] == 'OP2' && $seiten[10] == 'OP1' 
 || $seiten[10] == 'OP1' && $seiten[11] == 'OP2'  
 || $seiten[10] == 'OP2' && $seiten[11] == 'OP1'  
 || $seiten[11] == 'OP1' && $seiten[12] == 'OP2'  
 || $seiten[11] == 'OP2' && $seiten[12] == 'OP1'  
 || $seiten[12] == 'OP1' && $seiten[13] == 'OP2'  
 || $seiten[12] == 'OP2' && $seiten[13] == 'OP1' 
 || $seiten[13] == 'OP1' && $seiten[14] == 'OP2' 
 || $seiten[13] == 'OP2' && $seiten[14] == 'OP1'  
// OP3 und OP4

[...] <-- hier habe ich für mehr Übersichtlichkeit für das Forum gekürzt; Die folgenden Blöcke sind aufgebaut wie der erste.

// OP5 und OP6

[...]

// OP7 und OP8

[...]

// OP9 und OP10

[...]

// OP10 und OP13

[...]
// OP9 und OP13
[...]
// OP11 und OP12
[...]
// OP12 und OP14
[...]
// OP11 und OP14

 || $seiten[1] == 'OP11' && $seiten[2] = 'OP14'
 || $seiten[1] == 'OP14' && $seiten[2] == 'OP11'  
 || $seiten[2] == 'OP11' && $seiten[3] == 'OP14' 
 || $seiten[2] == 'OP14' && $seiten[3] == 'OP11'  
 || $seiten[3] == 'OP11' && $seiten[4] == 'OP14'  
 || $seiten[3] == 'OP14' && $seiten[4] == 'OP11'  
 || $seiten[4] == 'OP11' && $seiten[5] == 'OP14'  
 || $seiten[4] == 'OP14' && $seiten[5] == 'OP11'  
 || $seiten[5] == 'OP11' && $seiten[6] == 'OP14' 
 || $seiten[5] == 'OP14' && $seiten[6] == 'OP11' 
 || $seiten[6] == 'OP11' && $seiten[7] == 'OP14'  
 || $seiten[6] == 'OP14' && $seiten[7] == 'OP11' 
 || $seiten[7] == 'OP11' && $seiten[8] == 'OP14' 
 || $seiten[7] == 'OP14' && $seiten[8] == 'OP11' 
 || $seiten[8] == 'OP11' && $seiten[9] == 'OP14' 
 || $seiten[8] == 'OP14' && $seiten[9] == 'OP11'
 || $seiten[9] == 'OP11' && $seiten[10] == 'OP14'  
 || $seiten[9] == 'OP14' && $seiten[10] == 'OP11' 
 || $seiten[10] == 'OP11' && $seiten[11] == 'OP14'  
 || $seiten[10] == 'OP14' && $seiten[11] == 'OP11'  
 || $seiten[11] == 'OP11' && $seiten[12] == 'OP14'  
 || $seiten[11] == 'OP14' && $seiten[12] == 'OP11'  
 || $seiten[12] == 'OP11' && $seiten[13] == 'OP14'  
 || $seiten[12] == 'OP14' && $seiten[13] == 'OP11' 
 || $seiten[13] == 'OP11' && $seiten[14] == 'OP14' 
 || $seiten[13] == 'OP14' && $seiten[14] == 'OP11')

{
html( "Hinweis für Programmierung der Rotation: Unerwünschte Reihenfolgen lagen vor, es wurde neu gemischt. ");
$seiten = array('OP1','OP2','OP3','OP4','OP5','OP6','OP7','OP8','OP9','OP10','OP11','OP12','OP13','OP14');
shuffle($seiten);
}

html("Hinweis für Programmierung der Rotation: Es liegen keine unerwünschten Reihenfolgen vor.");

// Die Seite ergänzen, wo es nachher weiter geht
$seiten[] = 'Entsch';
// Reihenfolge zwischenspeichern, um spätere Änderung zu vermeiden
registerVariable('seiten');
}
setPageOrder($seiten);
"

Leider tut es nicht, was es soll: Beim Ausprobieren kommt es trotzdem immer wieder vor, dass zwei Hörbeispiele=Seiten hintereinander abgefragt werden, die eigentlich ausgenommen werden sollten.

Können Sie mir sagen, wo der Fehler liegt? Oder eine andere Möglichkeit nennen, mit der ich die Ausnahmen umsetzen kann?
Vielen Dank, freundliche Grüße!
Nina Düvel

3 Answers

0 votes
by s048351 (165 points)

Ich sehe gerade, dass jeweils in der ersten Zeile der Blöcke ein Gleichheitszeichen fehlt, es muss ja heißen:
$seiten[1] == 'OP1' && $seiten[2] == 'OP2'

0 votes
by s048351 (165 points)

... nun bekomme ich auch prompt eine Fehlermehldung, die mir jedoch nicht weiterhilft:

Im PHP-Code trat ein Fehler auf.
Fehler im Fragebogen: Undefined offset: 14
Zeile: 89
PHP-Code
086 || $seiten[12] == 'OP5' && $seiten[13] == 'OP6'
087 || $seiten[12] == 'OP6' && $seiten[13] == 'OP5'
088 || $seiten[13] == 'OP5' && $seiten[14] == 'OP6'
089 || $seiten[13] == 'OP6' && $seiten[14] == 'OP5'
090
091 || $seiten[1] == 'OP7' && $seiten[2] == 'OP8'
092 || $seiten[1] == 'OP8' && $seiten[2] == 'OP7'
Fehler im Fragebogen: Undefined offset: 14
Zeile: 116
PHP-Code
113 || $seiten[12] == 'OP7' && $seiten[13] == 'OP8'
114 || $seiten[12] == 'OP8' && $seiten[13] == 'OP7'
115 || $seiten[13] == 'OP7' && $seiten[14] == 'OP8'
116 || $seiten[13] == 'OP8' && $seiten[14] == 'OP7'
117
118 || $seiten[1] == 'OP9' && $seiten[2] == 'OP10'
119 || $seiten[1] == 'OP10' && $seiten[2] == 'OP9'
Fehler im Fragebogen: Undefined offset: 14
Zeile: 34
PHP-Code
031 || $seiten[11] == 'OP2' && $seiten[12] == 'OP1'
032 || $seiten[12] == 'OP1' && $seiten[13] == 'OP2'
033 || $seiten[12] == 'OP2' && $seiten[13] == 'OP1'
034 || $seiten[13] == 'OP1' && $seiten[14] == 'OP2'
035 || $seiten[13] == 'OP2' && $seiten[14] == 'OP1'
036
037 || $seiten[1] == 'OP3' && $seiten[2] == 'OP4'

0 votes
by SoSci Survey (327k points)

Für Ergänzungen der Frage editieren Sie am besten die Original-Frage. Sonst wird's a bisserl unübersichtlich.

Fehler im Fragebogen: Undefined offset: 14

Sie haben das Array $seiten von OP01 bis OP14 definiert. Der Index des ersten Eintrags ist 0, entsprechend der Index des 14sten Eintrags die 13. Einen Index (offset) 14 gibt es daher nicht, was die Fehlermeldung verursacht.

Aus den Folgenden Paaren (bzw. Tripeln) an Seiten sollen nicht zwei
hintereinander in beliebiger Reihenfolge abgefragt werden: (1, 2) (3,
4) (5, 6) (7, 8) (9, 10, 13) (11, 12, 14).

Nicht ganz trivial... Ich würde hier wohl mit einem Array arbeiten, welches die Kombinatonen prüft, z.B. wie folgt:

$forbidden = array(
  array(1, 2),
  array(3, 4),
  array(5, 6),
  array(7, 8),
  array(9, 10, 13),
  array(11, 12, 14)
);

foreach ($forbidden as $com) {
  // Prüfen, ob die Elemente aus $com nacheinader stehen
  $n = count($com);
  $found = 0;
  for ($i=0; $i<count($seiten) - $n + 1; $i++) {
    $subset = array_slice($seiten, $i, $n);
    // Prüfen, ob in einem konsekutiven Tupel/Triple innerhalb von $Seiten
    // min. zwei der gerade geprüften Werte vorkommen
    $together = array_intersect($com, $subset);
    if (count($together) > 1) {
      $fail = true;
      break 2;
    }
  }
}

// Falls $fail den Wert TRUE hat, muss sich etwas ändern

Die Wahrscheinlichkeit, dass bei zufälliger Mischung eine der verbotenen Kombinationen herauskommt ist relativ hoch - überschlagen ca. 50%. Vermutlich reicht das erneute Mischen, damit nach ein paar Versuchen eine erlaubte Kombination herauskommt. Alternativ könnte man nur dem Element, das den Ärger verursacht, eine neue Position zuweisen. Damit wäre die Wahrscheinlichkeit vermutlich geringer, dass man den Prozess öfter durchlaufen muss. Aber hier zu optimieren dürfte eher akademisch interessant sein, in der Praxis müsste ein paar mal Mischen ausreichen.

by s048351 (165 points)
Vielen Dank für die schnelle Antwort!
Ich habe zunächst die Indizes zu 0 bis 13 korrigiert und jetzt scheint es schon zu funktionieren. Falls sich doch noch Probleme offenbaren, versuche ich es mit Ihrer Lösung.
Vielen Dank!

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

...