Generieren einer Liste von Listen mit benutzerdefinierten Werteinschränkungen mit Hypothese

8

Die Geschichte:

Zur Zeit habe ich eine zu testende Funktion, die eine Liste von Ganzzahlen mit den folgenden Regeln erwartet:

  1. Anzahl der Unterlisten (nennen wir es N ) kann von 1 bis 50
  2. sein
  3. Anzahl der Werte in Unterlisten ist für alle Unterlisten (rechteckige Form) gleich und sollte & gt; = 0 und & lt; = 5
  4. sein
  5. Werte in Unterlisten dürfen nicht größer oder gleich der Gesamtzahl der Unterlisten sein. Mit anderen Worten, jeder Wert innerhalb einer Unterliste ist eine ganze Zahl & gt; = 0 und & lt; %Code%

Beispiel gültige Eingaben:

%Vor%

Beispiel ungültige Eingaben:

%Vor%

Ich versuche, es mit property-based-testing zu erreichen und erzeuge verschiedene gültige Eingaben mit N library und versuche, meinen Kopf um hypothesis und lists() zu legen, aber es kann nicht funktionieren:

  • Die Bedingung # 1 ist leicht mit integers() und lists() und min_size argumente
  • zu erreichen
  • die Bedingung # 2 ist unter max_size abgedeckt
  • Die Bedingung Nr. 3 ist das, womit ich mich abmühen muss - denn wenn wir das Chaining strategies together aus dem obigen Beispiel verwenden, haben wir keinen Verweis auf die Länge der "Eltern" -Liste in rectangle_lists

Die Frage:

Wie kann ich die Integer-Werte innerhalb von Unterlisten auf weniger als die Gesamtzahl der Unterlisten begrenzen?

Einige meiner Versuche:

%Vor%

Dieser war weit davon entfernt, die Anforderungen zu erfüllen - die Liste ist nicht streng rechteckig, und generierte Integer-Werte können die generierte Größe der Liste überschreiten.

%Vor%

Hier werden die Anforderungen # 1 und # 2 erfüllt, aber die Integer-Werte können größer als die Größe der Liste sein - Anforderung # 3 ist nicht erfüllt.

    
alecxe 18.09.2016, 18:42
quelle

3 Antworten

5

Es gibt eine gute allgemeine Technik, die oft nützlich ist, wenn Sie versuchen, knifflige Bedingungen wie diese zu lösen: Versuchen Sie etwas zu bauen, das ein bisschen wie das ist, was Sie wollen, aber nicht alle Bedingungen erfüllt und es dann mit einer Funktion zusammensetzt es (z. B. durch Wegwerfen der schlechten Bits oder Flicken von Bits, die nicht ganz funktionieren), damit es die Beschränkungen erfüllt.

Für Ihren Fall könnten Sie Folgendes tun:

%Vor%

In diesem wir:

  1. Erzeuge eine Liste, die ungefähr richtig aussieht (es ist eine Liste von Ganzzahlen, und die Ganzzahlen liegen im selben Bereich wie alle möglichen Indizes, die gültig sein könnten).
  2. Löschen Sie alle ungültigen Indizes aus den Unterlisten
  3. Verkürzen Sie alle Unterlisten, die noch mehr als 5 Elemente enthalten

Das Ergebnis sollte alle drei Bedingungen erfüllen, die Sie benötigen.

Der Parameter average_size ist nicht unbedingt notwendig, aber beim Experimentieren mit diesem habe ich festgestellt, dass er etwas zu anfällig dafür ist, ansonsten leere Unterlisten zu erstellen.

ETA: Entschuldigung. Ich habe gerade gemerkt, dass ich eine Ihrer Bedingungen falsch gelesen habe - das tut nicht wirklich das, was Sie wollen, weil es nicht sicherstellt, dass jede Liste die gleiche Länge hat. Hier ist eine Möglichkeit, dies zu modifizieren, um das zu beheben (es wird etwas komplizierter, also habe ich auf Composite anstelle von Builds umgestellt):

%Vor%

Die Idee ist, dass wir eine "Füller" -Liste erstellen, die die Standardwerte für die Darstellung einer Unterliste bietet (so dass sie dazu neigen, in Richtung einander ähnlicher zu schrumpfen) und dann die Länge der Unterlisten zu zeichnen beschneiden, um diese Konsistenz zu erhalten.

Das ist ziemlich kompliziert, gebe ich zu. Möglicherweise möchten Sie die Flatmap-basierte Version von RecursiveIronic verwenden. Der Hauptgrund, warum ich das vorziehe, ist, dass es tendenziell besser schrumpft, also werden Sie schönere Beispiele daraus machen.

    
DRMacIver 20.09.2016, 12:16
quelle
4

Das kannst du auch mit flatmap machen, obwohl es ein bisschen wie eine Verzerrung ist.

%Vor%

Wie David bereits erwähnt hat, führt dies dazu, dass viele leere Listen erzeugt werden, so dass eine gewisse Durchschnittsgröße erforderlich ist.

%Vor%     
RecursivelyIronic 21.09.2016 01:19
quelle
1

Ziemlich spät, aber für die Nachwelt: Die einfachste Lösung besteht darin, Dimensionen auszuwählen und dann aus der Element-Strategie aufzubauen.

%Vor%     
Zac Hatfield-Dodds 06.03.2018 08:36
quelle