Welcome to the LimeSurvey Community Forum

Ask the community, share ideas, and connect with other LimeSurvey users!

3 unterschiedliche Zufallszahlen

  • vklug20
  • vklug20's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
3 years 4 months ago #209699 by vklug20
3 unterschiedliche Zufallszahlen was created by vklug20
Hallo! Für mein Projekt würde ich gerne drei Fragegruppen zufällig aus einem Fragepool von acht Möglichkeiten auswählen. Ich habe hier länger nach Posts gesucht und bin auch auf hilfreiche Infos gestoßen, die allesamt aber geringfügig andere Probleme behandeln oder deren Lösungsweg ich nicht verstehe. Somit bin ich leider noch immer nicht näher ans Ziel gekommen.

Vorgestellt habe ich es mir so: ich lasse mir eine Zufallszahl von 1 bis 8 zunächst ein mal ausgeben mittels {randnum= rand(1,8)}. Nun zu dem Punkt bei dem ich stecke. Wie schaffe ich es, dass die 2. zahl nicht mit der ersten übereinstimmt und die 3. nicht mit der ersten und zweiten. Ich will ja nicht, dass am Ende jemand drei mal die selbe Frage sieht.

Danke vielmals!
The topic has been locked.
  • Joffm
  • Joffm's Avatar
  • Away
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
3 years 4 months ago - 3 years 4 months ago #209700 by Joffm
Replied by Joffm on topic 3 unterschiedliche Zufallszahlen
Hallo,
Du hast den Finger genau in die Wunde gelegt.
So geht es also nicht.
Du musst per javascript zunächst aus den 8 Möglichkeiten 3 aussuchen,
Geht so:
Eine Frage vom Typ "kurzer Text" (Q0). In den Quellcode dies.
Code:
<script type="text/javascript" charset="utf-8">
 
function shuffle(array) {
  var currentIndex = array.length, temporaryValue, randomIndex;
 
  // While there remain elements to shuffle...
  while (0 !== currentIndex) {
 
    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;
 
    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }
 
  return array;
}
 
 
  $(document).on('ready pjax:scriptcomplete',function(){
// Fill the array
      var arr = [];
      for (var i = 1; i < 9; i++) {
         arr.push(i);
      }
 
      arr = shuffle(arr);
      anumbers = arr.slice(0,3).join(',');
      $('#question{QID} input[type="text"]').val("#"+anumbers);
      $('#question{QID}').hide();
   });
</script>

Dann erhälst Du so etwas:
#7,4,5

Und dann hat die Gruppenrelevanzgleichung dieses Aussehen:
1. Gruppe: strpos(Q0,'1') -> Gruppe wird angezeigt, wenn im String eine 1 enthalten ist.
2. Gruppe: strpos(Q0,'2')
3. Gruppe: strpos(Q0,'3')
...

Über die Funktion "strpos" solltest Du im Handbuch nachlesen.

Joffm

Volunteers are not paid.
Not because they are worthless, but because they are priceless
Last edit: 3 years 4 months ago by Joffm.
The topic has been locked.
  • vklug20
  • vklug20's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
3 years 4 months ago #209701 by vklug20
Replied by vklug20 on topic 3 unterschiedliche Zufallszahlen
Wow, da wäre ich vermutlich von selber niemals drauf gekommen. Danke vielmals! Ich werde es mir morgen genauer anschauen!
The topic has been locked.
  • Joffm
  • Joffm's Avatar
  • Away
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
3 years 4 months ago - 3 years 4 months ago #209705 by Joffm
Replied by Joffm on topic 3 unterschiedliche Zufallszahlen
Hallo,

Wow, da wäre ich vermutlich von selber niemals drauf gekommen

Vielleicht schon, denn ich habe dies allein in diesem Jahr schon mehrmals hier im deutschen Teil gezeigt.
31.07. Titel: "Randomisierung"
04.06. Titel: "Urnenmodell mit der Variante Ziehen ohne Zurücklegen"
04.03. Titel: "Vignettendesign"
15.01. Titel: "Zufällige Auswahl von Antwortoptionen und Fragen"

Gut, dieses javascript snippet wird man ohne Kenntnisse dieser Sprache so nicht hinbekommen. Ich übrigens auch nicht, ich bin mit javascript wirklich nicht "auf Du und Du". Es ist eine Lösung, die seit Jahren hier im Forum existiert.


Aber hier sind noch zwei Lösungen, die naheliegend sind, verständlich sind und ohne javascript auskommen, nur eingebaute Funktionen von LimeSurvey benutzen.
Also gedacht für diejenigen Studenten, denen nicht erlaubt ist, javascript einzubauen; und auch als Fingerübung.


1. Das simple "Hau-Ruck-Verfahren".
Bei der Variante "Urne: Ziehen ohne Zurücklegen" gibt es genau
(AnzahlKugeln über AnzahlZiehungen)
verschiedene Ergebnisse.
In Deinem Fall also (8 über 3) = 56

1 123
2 124
3 125
4 126
5 127
6 128
7 134
8 135
9 136
10 137
11 138
12 145
13 146
14 147
15 148
16 156
17 157
18 158
19 167
20 168
21 178
22 234
23 235
24 236
25 237
26 238
27 245
28 246
29 247
30 248
31 256
32 257
33 258
34 267
35 268
36 278
37 345
38 346
39 347
40 348
41 356
42 357
43 358
44 367
45 368
46 378
47 456
48 457
49 458
50 467
51 468
52 478
53 567
54 568
55 578
56 678

Daher kann man eine Zufallszahl von 1-56 generieren und als Gruppenrelevanz alle die Zufallszahlen eingeben, deren Ergebnis diese Gruppe enthält.
Gruppe 1 ist leicht: zufall<22
Gruppe 2: zufall<7 OR (zufall>21 AND zufall<37)
...
Gruppe 8: zufall==6 or zufall==11 or zufall==15 or zufall==18 or zufall==20 or zufall==21 or zufall==26 or zufall==30 or zufall==33 or zufall==35 or zufall==36 or zufall==40 or zufall==43 or zufall==45 or zufall==46 or zufall==49 or zufall==51 or zufall==52 or zufall==54 or zufall==55 or zufall==56

Vorteil des Verfahrens: kurz, nur eine Funktion, die Generierung der Zufallszahl
Nachteil: Bei Gruppe 8 wird die Relevanzgleichung recht lang.

2. Das "Ziehen ohne Zurücklegen" nachgestellt.
Es werden nur 9 Fragen vom Typ "Gleichung" benutzt und die Funktionen
"is_empty(x)": Ist das Argument x leer?
"rand(x,y)": Erzeuge eine Zufallszahl von x bis y
strlen(x): Die Länge des Argumentes x
substr(x,start,länge): Nimm den Teilstring von x, beginnend bei "start", "länge" Zeichen lang
str_replace(von, nach, x): Erstze im Argument x die Zeichen "von" durch "nach"
Hier schematisch:


Am Ende haben wir drei Zahlen "eqZahl1", "eqZahl2", "eqZahl3".
Nun kann die Relevanzgleichung für die Gruppen so aussehen:
1. Gruppe: eqZahl1==1 or eqZahl2==1 or eqZahl3==1
2. Gruppe: eqZahl1==2 or eqZahl2==2 or eqZahl3==2
...

Man kann jetzt einen Schritt weiter gehen und die drei Zahlen mit der Funktion "join" zu einem String zusammenfügen
Hieße dies Frage "eqZahl": {join("#",eqZahl1,eqZahl2,eqZahl3)}
Dann wäre die Relevanzgleichung kürzer, nämlich:
1. Gruppe: strpos(eqZahl,"1")>0
2. Gruppe: strpos(eqZahl,"2")>0
...


Alle diese Funktionen findet man hier:
manual.limesurvey.org/ExpressionScript_-...mplemented_functions

Das erste "dummy"-Zeichen (ich habe "#" genommen) im String ist wichtig.
Die Funktion "strpos" gibt die Position des gefundenen Zeichens zurück; die erste Position hat dabei den Wert 0.
Wäre der String eqZahl="482", so würde strpos(eqZahl,"4") das Ergebnis "0" zurückgeben.
So weit richtig. ABER der Rückgabewert 0 bedeutet auch "nicht gefunden".
Daher erzwingt man mit dem "dummy"-Zeichen, dass das erste "richtige" Zeichen mindestens die Position "1" hat.

Und hier als Beispiel:

File Attachment:

File Name: limesurvey...2913.lss
File Size:30 KB



3. Erklärung des javascript

Es wird ein array erzeugt, und in einer Schleife die Zahlen beginnend bei 1, und solange kleiner als 9 eingefügt (push)
Code:
// Fill the array
      var arr = [];
      for (var i = 1; i < 9; i++) {
         arr.push(i);
      }

Man kann sich die Schleife sparen, indem man das array direkt füllt:
Var arr=[1,2,3,4,5,6,7,8];

Dieses array wird nun durcheinandergewürfelt
Code:
      arr = shuffle(arr);

Mit "slice" nehmen wir nur die ersten 3 Zeichen beginnend bei 0; mit join werden sie zu einem string zusammengesetzt, der mit "," getrennt ist.
Code:
      anumbers = arr.slice(0,3).join(',');

Das Ergebnis wird mit dem zusätzlichen "dummy"-Zeichen in das Textfeld der Frage vom Typ "kurzer Text" geschrieben
Code:
      $('#question{QID} input[type="text"]').val("#"+anumbers);

Die Frage wird versteckt. Man kann nicht mit "Frage immer verstecken" arbeiten, da sie dann gar nicht existiert, und das javascript also nicht arbeiten kann.
Code:
      $('#question{QID}').hide();

Kleine Hürden:
Man erzeugt ein array von 1-15 und erhält am Ende eine string wie "#5,11,3"
Dann werden 4 Gruppen angezeigt, nämlich G1, G3, G5 und G11.
Denn 'strpos(Q1,"1")' liefert den Wert 3; das Zeichen "1" ist schließlich enthalten.
Also anders:
a. Man kann hier ändern in:
$('#question{QID} input[type="text"]').val("#"+anumbers+",");
Dann sieht der obige string so aus: "#5,11,3," und die Relevanzgleichung so:
strpos(Q1,",1,") ; man testet auch auf die zusätzlichen Kommata; so werden ",1," und ",11," unterschieden.

b. Man füllt das array mit zweistelligen Zahlen
Code:
var arr = [];
     for (i = 1; i < 21; i++) {
       w=("00" + i).slice(-2);
       arr.push(w);
     }

Dann sieht der obige string so aus: "#05,11,03" und der Test
strpos(Q1,"01")>0 findet die "11" dann nicht.

c. Man benutzt statt Zahlen Buchstaben (groß/klein) - solange man mit der Anzahl auskommt.
Erzeugt ein array "mit der Hand":
Var arr=["A","B","C","D","E","F","G","H","I","J","K","L","M"];
und testet für die Gruppen:
Gruppe 1:strpos(Q1,"A")>0
Gruppe 2:strpos(Q1,"B")>0

Da kann man also vieles nach eigenem Gusto ändern.

Viele Erfolg

Joffm

Volunteers are not paid.
Not because they are worthless, but because they are priceless
Last edit: 3 years 4 months ago by Joffm.
The topic has been locked.
Moderators: Joffm

Lime-years ahead

Online-surveys for every purse and purpose