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

0 votes

der PHP Code funktioniert nun, nachdem wir gestern den kleinen Fehler gefunden haben.

Hintergrundinfo:
Die "Top 3" Items sollen 2x abgefragt werden. 1x die höchsten Top 3, einmal die niedrigsten Top 3 - aber aus der selben Item Liste
--> hier werde ich gewarnt, dass das nicht geht, weil es sonst ja doppel abgefragt werden könnte (- logisch). Soweit so gut.

Jetzt gibt es von mir allerdings noch ein paar Vertiefungsfragen:

  1. Eigentlich möchte ich, da ich ja mit einem Schieberegler arbeite, der Werte von -100 bis +100 anzeigt (im System 1-202), bei den Top 3 nur die 3 Werte haben, die auch im positiven Bereich liegen. Dh, wenn es beispielsweise nur 2 Items über 0 gibt, dann gibt es nur 2. Derzeit wird dann der nächst-höhere Wert genommen. Da müsste noch eine if-Bedingung rein, dass nur Items berücksichtigt werden, die vom System aus zwischen 102 und 202 liegen, oder?
    1.1.:Wie baue ich diese Bedingung ein?
    1.2: Wenn nur beispielsweise 1 Item aufgrund der If-Bedingungen auftaucht, kann ich steuern, was stattdessen angezeigt wird. Beispielsweise eine Phrase wie: "keine weiteren Daten"

  2. Ich wollte ganz eigenständig auch die negativen Top 3 als PHP Code formulieren - hat auch geklappt. Allerdings gibt es ein weiteres Problem. In der Frage, aus der die Itemliste bezogen wird, können die Teilnehmer eine Ausweichoption wählen. Die wird vom System ja mit -9 gewertet. Mein Schieberegler geht vom System her ja von 1 - 202... Das heißt alle Items, die mit der Ausweichoption beantwortet werden, kommen dann in die Top 3. Das ist inhaltlich nicht sinnvoll.
    Vermutlich brauche ich hier also eine if Bedingung, in der ich aus der asort Liste nur die Werte weiterverwende, die zwischen 1 und 100 liegen (also für den Nutzer nicht über -1), oder?

  3. jetzt wieder der Bezug zur Einleitung: wenn ich durch die If-Bedingungen verhindere, dass ein Item doppelt angezeigt wird - muss ich dann trotzdem für die doppelte Abfrage der Top 3 (auch wenn es nicht die selben Items sind) eine weitere Frage anlegen? Oder ist es okay mit einer Frage, weil die sich nicht ins Gehege kommen können?

related to an answer for: PHP Code klappt nicht - V2.0
in SoSci Survey (dt.) by s049805 (300 points)
ad 1) Wenn Sie Ihren PHP-Code in der Frage ergänzen, dann kann ich da gerne weiterhelfen.

ad 2) dito.

ad 3) Wenn Sie dafür sorgen, dass jedes Item der anderen Frage nur einmal abgefragt wird, reicht eine Frage natürlich. Allerdings tun Sie sich vielleicht in der Auswertung einen Gefallen, wenn Sie die Daten für die Top- und Bottom-Items gleich getrennt sammeln!
$values = valueList('EN06');
arsort($values);
 
$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;
  }
}
 
shuffle($equal);
$needed = 3 - count($greater);
$items = array_merge($greater, array_slice($equal, 0, $needed));

question('EN11', $items);

1 Answer

0 votes

bei den Top 3 nur die 3 Werte haben, die auch im positiven Bereich liegen.

Der Positive Bereich wäre - nach internen Codes von 1..201 - also alles > 100. Am elegantesten könnten Sie das direkt beim Abruf der Werte zu Beginn einschränken:

$posItems = getItems('EB06', '>', 100);
$values = valueList('EN06', $posItems);
arsort($values);
// u.s.w.

Alternativ können Sie den Schwellenwert auf mindestens 101 setzen:

$threshold = $values[$order[2]];
if ($threshold < 101) [
  $threshold = 101;
}
$greater = array();
// u.s.w.

Allerdings gibt es ein weiteres Problem. In der Frage, aus der die Itemliste bezogen wird, können die Teilnehmer eine Ausweichoption wählen.

Auch hier ist der Kniff mit dem getItems() möglich:

$relItems = getItems('EB06', 'valid');
$values = valueList('EN06', $posItems);
// u.s.w.

Alternativ könnten Sie es weiter unten im Code erledigen, indem Sie $value > 0 testen.

  $itemID = (int)ltrim(substr($varID, 5), "0");
  if (($value < $threshold) && ($value > 0)) {
    $smaller[] = $itemID;
by SoSci Survey (85.4k points)
Danke für die Antwort... leider klappt es noch nicht.

1. Problem: Wenn keine Option auf die >101 oder <101 zutrifft, nimmt er durch die shuffel Funktion einfach irgendwelche Items. Dies passiert nicht, wenn statt 3 nur 2 oder 1 Items darauf zutreffen.

Die ein oder zwei höchsten Items werden angezeigt, aber dann bekomme ich zusätzlich diesen Fehler:
Fehler im Fragebogen: Undefined offset: 2
Zeile: 8

PHP-Code

005 arsort($values);
006  
007 $order = array_keys($values);
008 $threshold = $values[$order[2]];
009 $greater = array();
010 $equal = array();
011 foreach ($values as $varID => $value) {
Fehler im Fragebogen: Undefined index:
Zeile: 8

PHP-Code

005 arsort($values);
006  
007 $order = array_keys($values);
008 $threshold = $values[$order[2]];
009 $greater = array();
010 $equal = array();
011 foreach ($values as $varID => $value) {


Mein gesamter PHP Code für die pos. Items lautet:
$posItems = getItems('EN06', '>', 101);
$values = valueList('EN06', $posItems);
arsort($values);
 
$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;
  }
}
 
shuffle($equal);
$needed = 3 - count($greater);
$items = array_merge($greater, array_slice($equal, 0, $needed));

question('EN11', $items);



Bei den neg. Items schaut es anders aus. Seltsamerweise...
Wenn ich hier nur 2 oder 1 Item im Bereich unter 101 habe, wird mir NUR der Fehler angezeigt und nicht mehr die beiden Items, die aber im relevanten Bereich wären. Der PHP Code lautet:
$negItems = getItems('EN06', '<', 101);
$values = valueList('EN06', $negItems);
asort($values);
 
$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) && ($value > 0)) {
    $greater[] = $itemID;
  } elseif ($value == $threshold) {
    $equal[] = $itemID;
  }
}
 
shuffle($equal);
$needed = 3 - count($greater);
$items = array_merge($greater, array_slice($equal, 0, $needed));

question('EN11', $items);


Somit ergeben sich 3 Themen:
1. Das Ausspucken von Werten, wenn es eigentlich keine gültigen Werte gibt (Shuffelfunktion) und
2. Die Fehlermeldung beim den positiven Werten
3. die Fehlermeldung bei den neg. Werten und dass dort gar nichts angezeigt wird.
Das Problem dürfte in folgenden Zeilen liegen:

$order = array_keys($values);
$threshold = $values[$order[2]];

Sie nehmen ja das dritte Item als Grenze. Versuchen Sie folgendes:

$order = array_keys($values);
$threshold = $values[$order[min(2, count($order) - 1)]];

Hier wurde die 2 ersetzt durch: min(2, count($order) - 1)

Heißt übersetzt: Nimm das dritte (Index 2) oder, wenn es weniger sind, dann halt den höchsten Index, den wir haben.
Ja, Funktioniert gut! Jetzt bleibt noch das Problem mit der Shuffel.
Wenn nämlich kein Wert (wegen der Ausweichoption) übrig bleibt - nimmt er 3 Beliebige.
Ich kenne nicht den kompletten aktuellen PHP-Code. Aber es wird wohl auf einen Filter ziemlich zu Beginn hianuslaufen:

$posItems = getItems('EN06', '>', 101);
if (count($posItems) == 0) {
  // Nichts abfragen
} else {
  // Hier der komplette restliche Code
}
...