So, hier kommt jetzt das versprochene Beispiel.
Zunächst viel Erklärung.
Dies sind die Gruppen und Fragen, die am Anfang benötigt werden, um alle benötigten Werte zu berechnen
Das alles Entscheidende ist die Frage QErg (Matrix) mit 16 Zeilen (Sätze) und 16 Spalten (Variationen)
Hier wird für jeden Teilnehmer seine benutzte Kombination gespeichert.
Mit der Funktion "statCountIf" wird dann bei jedem folgenden Teilnehmer gescheut, welche Kombinationen nun noch frei sind.
Das Grundgerüst bildet ein "Container" (Matrix(Texte)) um Zwischenergebnisse zu speichern.
16 Zeilen = 16 Sätze, codiert einfach numerisch 1,2,3,4,...15,16
4 Spalten
- min - Hier wird das Minimum der Anzahl aller bisher gezogenen Zahlen des jeweiligen Satzes gespeichert.
- list - Eine Liste derjenigen der 16 Variationen wird erzeugt, die dem Minimum entsprechen. (Hier soll gelten "A=1, B=2, C=3, ... , J=10, K=11,... O=15, P=16)
Damit benötigt man nur ein Zeichen.
- rand - Eine Zufallszahl wird erzeugt von 1 - Länge der Liste
- zahl - Aus der Liste wird die Zahl / das Zeichen genommen, welches an der Position der Zufallszahl steht und in binärer Darstellung gespeichert.
Grund: Man bekommt Darstellungen wie "0000", "0101", "1101", also für die vier zu variierenden Teile eine der zwei Optionen.
Das nur zur ersten Erklärung des "Containers".
Nun beginnen wir diesen zu füllen.
eqMin :
{C_1_min=min(statCountIf(QErg_1.sgqa, "1",0), statCountIf(QErg_1.sgqa, "2",0), statCountIf(QErg_1.sgqa, "3",0), statCountIf(QErg_1.sgqa, "4",0), statCountIf(QErg_1.sgqa, "5",0), statCountIf(QErg_1.sgqa, "6",0), statCountIf(QErg_1.sgqa, "7",0), statCountIf(QErg_1.sgqa, "8",0), statCountIf(QErg_1.sgqa, "9",0), statCountIf(QErg_1.sgqa, "10",0), statCountIf(QErg_1.sgqa, "11",0), statCountIf(QErg_1.sgqa, "12",0), statCountIf(QErg_1.sgqa, "13",0), statCountIf(QErg_1.sgqa, "14",0), statCountIf(QErg_1.sgqa, "15",0), statCountIf(QErg_1.sgqa, "16",0))}
{C_2_min=min(statCountIf(QErg_2.sgqa, "1",0), statCountIf(QErg_2.sgqa, "2",0), statCountIf(QErg_2.sgqa, "3",0), statCountIf(QErg_2.sgqa, "4",0), statCountIf(QErg_2.sgqa, "5",0), statCountIf(QErg_2.sgqa, "6",0), statCountIf(QErg_2.sgqa, "7",0), statCountIf(QErg_2.sgqa, "8",0), statCountIf(QErg_2.sgqa, "9",0), statCountIf(QErg_2.sgqa, "10",0), statCountIf(QErg_2.sgqa, "11",0), statCountIf(QErg_2.sgqa, "12",0), statCountIf(QErg_2.sgqa, "13",0), statCountIf(QErg_2.sgqa, "14",0), statCountIf(QErg_2.sgqa, "15",0), statCountIf(QErg_2.sgqa, "16",0))}
...
für alle QErg_1 bis QErg_16
Nun steht in der 1. Spalte des Containers für jeden Satz das Minimum.
eqList (Wenn die Anzahl dem vorher berechneten Minimum entspricht, wird die Variation in die Liste übernommen)
{C_1_list=join(if(statCountIf(QErg_1.sgqa, "1",0)==C_1_min,"A",""), if(statCountIf(QErg_1.sgqa, "2",0)==C_1_min,"B",""), if(statCountIf(QErg_1.sgqa, "3",0)==C_1_min,"C",""), if(statCountIf(QErg_1.sgqa, "4",0)==C_1_min,"D",""), if(statCountIf(QErg_1.sgqa, "5",0)==C_1_min,"E",""), if(statCountIf(QErg_1.sgqa, "6",0)==C_1_min,"F",""), if(statCountIf(QErg_1.sgqa, "7",0)==C_1_min,"G",""), if(statCountIf(QErg_1.sgqa, "8",0)==C_1_min,"H",""), if(statCountIf(QErg_1.sgqa, "9",0)==C_1_min,"I",""), if(statCountIf(QErg_1.sgqa, "10",0)==C_1_min,"J",""), if(statCountIf(QErg_1.sgqa, "11",0)==C_1_min,"K",""), if(statCountIf(QErg_1.sgqa, "12",0)==C_1_min,"L",""), if(statCountIf(QErg_1.sgqa, "13",0)==C_1_min,"M",""), if(statCountIf(QErg_1.sgqa, "14",0)==C_1_min,"N",""), if(statCountIf(QErg_1.sgqa, "15",0)==C_1_min,"O",""), if(statCountIf(QErg_1.sgqa, "16",0)==C_1_min,"P",""))}
{C_2_list=join(if(statCountIf(QErg_2.sgqa, "1",0)==C_2_min,"A",""), if(statCountIf(QErg_2.sgqa, "2",0)==C_2_min,"B",""), if(statCountIf(QErg_2.sgqa, "3",0)==C_2_min,"C",""), if(statCountIf(QErg_2.sgqa, "4",0)==C_2_min,"D",""), if(statCountIf(QErg_2.sgqa, "5",0)==C_2_min,"E",""), if(statCountIf(QErg_2.sgqa, "6",0)==C_2_min,"F",""), if(statCountIf(QErg_2.sgqa, "7",0)==C_2_min,"G",""), if(statCountIf(QErg_2.sgqa, "8",0)==C_2_min,"H",""), if(statCountIf(QErg_2.sgqa, "9",0)==C_2_min,"I",""), if(statCountIf(QErg_2.sgqa, "10",0)==C_2_min,"J",""), if(statCountIf(QErg_2.sgqa, "11",0)==C_2_min,"K",""), if(statCountIf(QErg_2.sgqa, "12",0)==C_2_min,"L",""), if(statCountIf(QErg_2.sgqa, "13",0)==C_2_min,"M",""), if(statCountIf(QErg_2.sgqa, "14",0)==C_2_min,"N",""), if(statCountIf(QErg_2.sgqa, "15",0)==C_2_min,"O",""), if(statCountIf(QErg_2.sgqa, "16",0)==C_2_min,"P",""))}
...
auch für alle 16
Nebenbemerkung: Um nicht alle 256 Häufigkeiten zwischenspeichern zu müssen, wird hier die Funktion "statCountIf" zum zweiten Mal angewendet, was eigentlich kein guter Stil ist.
Jetzt kommt im Baum der Container. Irgendwie muss er dort liegen, sonst funktioniert es nicht.
In der zweiten Kalkulationsgruppe nun:
eqRand: (Eine Zufallszahl von 1 bis zur Länge der Liste)
{C_1_rand=if(is_empty(C_1_rand),rand(1,strlen(C_1_list)),C_1_rand)}
{C_2_rand=if(is_empty(C_2_rand),rand(1,strlen(C_2_list)),C_2_rand)}
...
eqZahl: (Die binäre Darstellung der Zahl wird gespeichert) Ich habe keine schnelle Funktion gefunden; daher ist es hier "zu Fuß" gelöst.
{C_1_zahl=if(substr(C_1_list,C_1_rand-1,1)=="A","0000", if(substr(C_1_list,C_1_rand-1,1)=="B","0001", if(substr(C_1_list,C_1_rand-1,1)=="C","0010", if(substr(C_1_list,C_1_rand-1,1)=="D","0011", if(substr(C_1_list,C_1_rand-1,1)=="E","0100", if(substr(C_1_list,C_1_rand-1,1)=="F","0101", if(substr(C_1_list,C_1_rand-1,1)=="G","0110", if(substr(C_1_list,C_1_rand-1,1)=="H","0111", if(substr(C_1_list,C_1_rand-1,1)=="I","1000", if(substr(C_1_list,C_1_rand-1,1)=="J","1001", if(substr(C_1_list,C_1_rand-1,1)=="K","1010", if(substr(C_1_list,C_1_rand-1,1)=="L","1011", if(substr(C_1_list,C_1_rand-1,1)=="M","1100", if(substr(C_1_list,C_1_rand-1,1)=="N","1101", if(substr(C_1_list,C_1_rand-1,1)=="O","1110", if(substr(C_1_list,C_1_rand-1,1)=="P","1111"))))))))))))))))}
{C_2_zahl=if(substr(C_2_list,C_2_rand-1,1)=="A","0000", if(substr(C_2_list,C_2_rand-1,1)=="B","0001", if(substr(C_2_list,C_2_rand-1,1)=="C","0010", if(substr(C_2_list,C_2_rand-1,1)=="D","0011", if(substr(C_2_list,C_2_rand-1,1)=="E","0100", if(substr(C_2_list,C_2_rand-1,1)=="F","0101", if(substr(C_2_list,C_2_rand-1,1)=="G","0110", if(substr(C_2_list,C_2_rand-1,1)=="H","0111", if(substr(C_2_list,C_2_rand-1,1)=="I","1000", if(substr(C_2_list,C_2_rand-1,1)=="J","1001", if(substr(C_2_list,C_2_rand-1,1)=="K","1010", if(substr(C_2_list,C_2_rand-1,1)=="L","1011", if(substr(C_2_list,C_2_rand-1,1)=="M","1100", if(substr(C_2_list,C_2_rand-1,1)=="N","1101", if(substr(C_2_list,C_2_rand-1,1)=="O","1110", if(substr(C_2_list,C_2_rand-1,1)=="P","1111"))))))))))))))))}
...
Bitte immer beachten beim Nachvollziehen: Bei der Funktion "substr" hat das erste Zeichen den Index "0", daher auch die Subtraktion von 1.
eqQErg: Hier wir jetzt dasselbe Ergebnis (nicht-binär) in dee Matrix gespeichert
{QErg_1=if(substr(C_1_list,C_1_rand-1,1)=="A",1, if(substr(C_1_list,C_1_rand-1,1)=="B",2, if(substr(C_1_list,C_1_rand-1,1)=="C",3, if(substr(C_1_list,C_1_rand-1,1)=="D",4, if(substr(C_1_list,C_1_rand-1,1)=="E",5, if(substr(C_1_list,C_1_rand-1,1)=="F",6, if(substr(C_1_list,C_1_rand-1,1)=="G",7, if(substr(C_1_list,C_1_rand-1,1)=="H",8, if(substr(C_1_list,C_1_rand-1,1)=="I",9, if(substr(C_1_list,C_1_rand-1,1)=="J",10, if(substr(C_1_list,C_1_rand-1,1)=="K",11, if(substr(C_1_list,C_1_rand-1,1)=="L",12, if(substr(C_1_list,C_1_rand-1,1)=="M",13 ,if(substr(C_1_list,C_1_rand-1,1)=="N",14, if(substr(C_1_list,C_1_rand-1,1)=="O",15 ,if(substr(C_1_list,C_1_rand-1,1)=="P",16))))))))))))))))}
{QErg_2=if(substr(C_2_list,C_2_rand-1,1)=="A",1, if(substr(C_2_list,C_2_rand-1,1)=="B",2, if(substr(C_2_list,C_2_rand-1,1)=="C",3, if(substr(C_2_list,C_2_rand-1,1)=="D",4, if(substr(C_2_list,C_2_rand-1,1)=="E",5, if(substr(C_2_list,C_2_rand-1,1)=="F",6, if(substr(C_2_list,C_2_rand-1,1)=="G",7, if(substr(C_2_list,C_2_rand-1,1)=="H",8, if(substr(C_2_list,C_2_rand-1,1)=="I",9, if(substr(C_2_list,C_2_rand-1,1)=="J",10, if(substr(C_2_list,C_2_rand-1,1)=="K",11, if(substr(C_2_list,C_2_rand-1,1)=="L",12, if(substr(C_2_list,C_2_rand-1,1)=="M",13 ,if(substr(C_2_list,C_2_rand-1,1)=="N",14, if(substr(C_2_list,C_2_rand-1,1)=="O",15, if(substr(C_2_list,C_2_rand-1,1)=="P",16))))))))))))))))}
...
Und als Ergebnis hat man nun für jeden Satz eine der 16 Variationen
Hier einmal das Ergebnis nach 17 Durchläufen (ich hatte damals nur 5 Sätze)
Du siehst, dass in jedem Satz zunächst alle 16 in unterschiedlicher Reihenfolge auftauchen, bevor beim 17. Teilnehmer eine Zahl zum zweiten Mal auftaucht.
Nun zur Anzeige der Sätze.
Wie ich schon öfters schrieb: "tayloring".
Damit sieht zum Beispiel dieser Satz so aus
{if(substr(C_2_zahl,0,1)=="0","Carlo","Charlotte")} Chinchilla spielt gerne {if(substr(C_2_zahl,1,1)=="0","Tennis","Kricket")}. Das letzte Spiel endete mit {if(substr(C_2_zahl,2,1)=="0","einer Niederlage","einem Sieg")}, da {if(substr(C_2_zahl,3,1)=="0","nicht","sehr")} viele Zuschauer anwesend waren.
Dieses ist der Satz der Vignette 2 (daher wird "C_2_zahl" benutzt).
Und es wird nacheinander auf die vier Zeichen der binären Darstellung referiert
(substr(C_2_zahl,0,1), substr(C_2_zahl,1,1), substr(C_2_zahl,2,1), substr(C_2_zahl,3,1)
Je nachdem, ob der Wert 0 oder 1 ist, wird der entsprechende Text angezeigt.
Und als Letztes.
Beim Export der Daten kannst Du getrost auf alles vor QErg verzichten. Erst QErg ist notwendig, damit Du weißt, welche Variation im jeweiligen Satz vorlag.
Und als Allerletztes.
Die Fragen werden mit der GUI versteckt; Einstellung "Diese Frage immer verstecken".
Außerdem basiert LimeSurvey seit der Version 6 auf bootstrap 5. Dort gibt es die Klasse "hidden" nicht mehr. Es heißt jetzt "d-none"
Und endlich die lss.
Viel Erfolg
Joffm
Edit:
Ich schrieb, dass mir keine einfache Funktion zur Umwandlung von "dezimal" zu "dual" wie "dezbin" eingefallen ist.
Aber umgekehrt "bindez" ist es ja kinderleicht.
Damit könnte sich eqQErg ändern zu:
{QErg_1=sum(substr(C_1_zahl,0,1)*8,substr(C_1_zahl,1,1)*4,substr(C_1_zahl,2,1)*2,substr(C_1_zahl,3,1),1)}
{QErg_2=sum(substr(C_2_zahl,0,1)*8,substr(C_2_zahl,1,1)*4,substr(C_2_zahl,2,1)*2,substr(C_2_zahl,3,1),1)}
{QErg_3=sum(substr(C_3_zahl,0,1)*8,substr(C_3_zahl,1,1)*4,substr(C_3_zahl,2,1)*2,substr(C_3_zahl,3,1),1)}
...
Noch ein kleiner Tipp:
Ich schreibe diese ellenlangen Texte natürlich nicht mit der Hand
Entweder benutze ich einen PlainText-Editor wie Notepad++
und schreibe die erste Zeile.
Kopiere sie 15 Mal.
Dann kann man einfach eine Zeile nach der anderen markieren und mit "Suchen&Ersetzen" die "1" in "2", "3", "4",... ändern
Oder ich splitte in Excel die Zeile so auf mehrere Spalten auf, dass die zu ändernden Elemente separat in einer Spalte sind.
Dann in einer weiteren Spalte mit der Funktion "VERKETTEN" wieder zusammenfügen.
Alles 15 Mal nach unten kopieren, die zu ändernden Werte entsprechend nach unten ziehen, dass auch wieder 1,2,3,4... entsteht.
Egal wie; dann kopiert man alles wieder nach LimeSurvey.