Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
Nächste ÜberarbeitungBeide Seiten der Revision
de:create:functions:valuelist [13.10.2018 14:47] adminde:create:functions:valuelist [11.05.2019 13:47] admin
Zeile 40: Zeile 40:
 <code php> <code php>
 $codes = valueList('IV01',  null, 'label'); $codes = valueList('IV01',  null, 'label');
 +</code>
 +
 +
 +===== Die Items mit der höchsten Bewertung =====
 +
 +Ein anderes Anwendungsbeispiel für ''valueList()'' ist die Auswahl von Items ... und zwar nicht mit einem fixen Kriterium wie bei ''[[:de:create:functions:getitems]]'', sondern z.B. die drei Items mit den höchsten Bewertungen.
 +
 +Nehmen wir als Beispiel eine Batterie aus Schiebreglern (Frage vom Typ //Schieberegler//, z.B. "SR01") mit 15 Items. In einer Folgefrage sollen dann nur jene drei Items vertieft werden, welche vom Teilnehmer die höchste Bewertung (z.B. Nutzungsmenge) erhalten haben.
 +
 +Mit ''valueList()'' wird zunächst eine Liste aller Antworten abgerufen. Anschließend wird diese Liste absteigend sortiert -- und zwar mittels ''[[https://www.php.net/manual/de/function.arsort.php|arsort()]]'', damit die Zuordnung von Variablen-Kennung und Wert erhalten bleibt.
 +
 +<code php>
 +$values = valueList('SR01');
 +arsort($values);
 +</code>
 +
 +In der Variable ''$values'' könnte nun z.B. folgendes stehen:
 +
 +^Schlüssel^Wert^
 +|SR01_07|  101|
 +|SR01_02|  63|
 +|SR01_04|  59|
 +|SR01_15|  59|
 +|SR01_10|  42|
 +|SR01_11|  38|
 +|SR01_05|  35|
 +|SR01_14|  32|
 +|...|  ...|
 +
 +**Vorsicht:** Es kann nun passieren, dass das dritte und vierte Item (im Beispiel oben "SR01_04" und "SR01_15") den gleichen Wert bekommen haben. Man muss entscheiden, wie man mit diesem Fall umgeht: Soll das vierte Item in der Folgefrage mit auftauchen? Soll zufällig nur eines der Items verwendet werden?
 +
 +Für dieses Beispiel sollen immer genau drei Items abgefragt werden, es muss also zufällig eines der beiden Items ausgewählt werden. Das ist nicht ganz trivial. Dafür wird die Liste in drei Teile geteilt: Items, die einen höheren Wert als das dritte Item (''SR01_04 => 59'', ''$threshold'') erreichen (''$greater''), Items, die genau diesen Wert erreichen (''$equal'') und Items, die einen geringeren Wert erreichen. Die letzte Liste benötigen wir nicht mehr.
 +
 +<code php>
 +$order = array_keys($values);
 +$threshold = $values[$order[2]];
 +$greater = array();
 +$equal = array();
 +foreach ($values as $varID => $value) {
 +  $itemID = (int)ltrim(substr($varID, 5), "0");
 +  if ($value > $threshold) {
 +    $greater[] = $itemID;
 +  } elseif ($value == $threshold) {
 +    $equal[] = $itemID;
 +  }
 +}
 +</code>
 +
 +Zur Erklärung von ''$threshold'': Die Variable ''$order'' enthält die Schlüssel des Arrays ''$values''. Damit kann man gezielt den Schlüssel des dritten Werts (Index 2) in der sortierten Liste abrufen. ''$order[2]'' wäre hier also "SR01_04" und wenn man diesen Schlüssel aus ''$values'' abruft, bekommt man im Beispiel die ''59''.
 +
 +Zur Erklärung vin ''$itemID'': Wir benötigen ja nicht die komplette Variablen-Kennung (z.B. "SR01_01"), sondern nur die Nummer des Items, also z.B. ''1''. Dafür entnehmen wir zunächst mittels ''substr()'' aus "SR01_01" alles ab der sechsten Position (Index 5), also "01", und dann wird mittels ''ltrim()'' noch die führende "0" entfernt, damit PHP den Text "1" anschließend mittels ''(int)'' in die Zahl ''1''.
 +
 +Das Mischen der Liste ''$equal'' erfolgt mittels ''shuffle()''. Und aus dieser Liste benötigen wir drei minus die Anzahl Elemente aus der Liste ''$greater'', ermittelt via ''count()''.
 +
 +<code php>
 +shuffle($equal);
 +$needed = 3 - count($greater);
 +$items = array_merge($greater, array_slice($equal, 0, $needed));
 +</code>
 +
 +Die Liste $items enthält nun die Nummern der Top 3 Items, also entweder ''7,2,4'' oder ''7,2,15''. Diese können nun in einer Folgefrage, welche die gleichen 15 Items enthält wie die Frage "SR01" mittels ''question()'' abgefragt werden.
 +
 +<code php>
 +question('FF02', $items);
 +</code>
 +
 +Der gesamte PHP-Code sieht dann wie folgt aus.
 +
 +<code php>
 +$values = valueList('SR01');
 +arsort($values);
 +
 +$order = array_keys($values);
 +$threshold = $values[$order[2]];
 +$greater = array();
 +$equal = array();
 +foreach ($values as $varID => $value) {
 +  $itemID = (int)ltrim(substr($varID, 4), "0");
 +  if ($value > $threshold) {
 +    $greater[] = $varID;
 +  } elseif ($value == $threshold) {
 +    $equal[] = $varID;
 +  }
 +}
 +
 +shuffle($equal);
 +$needed = 3 - count($greater);
 +$items = array_merge($greater, array_slice($equal, 0, $needed));
 +
 +question('FF02', $items);
 </code> </code>
de/create/functions/valuelist.txt · Zuletzt geändert: 23.11.2020 09:49 von admin
 
Falls nicht anders bezeichnet, ist der Inhalt dieses Wikis unter der folgenden Lizenz veröffentlicht: CC Attribution-Share Alike 4.0 International
Driven by DokuWiki