You are looking at historical revision 30558 of this page. It may differ significantly from its current revision.
data-generators
Requirements
Repository
https://bitbucket.org/certainty/data-generators/overview
Authors
Introduction
This egg provides primitives and combinators to generate random data. That may be useful for testing or other occasions where you just need a way to quickly generate data.
Examples
(use json data-generators) ;; generate a json document (define (gen-json-doc #!optional (nesting 5)) (generator (with-output-to-string (lambda () (json-write (<- (gen-json-value nesting))))))) ;; this is the only tricky part ;; we need to stop the recursion at a certain level of nesting and yet ;; we want to reduce the construction of generators to a minimum (define (gen-json-value nesting) (let ((scalar (gen-json-scalar))) (if (positive? nesting) (let ((complex (gen-json-complex (sub1 nesting))) (bool (gen-bool))) (generator (if (<- bool) (<- scalar) (<- complex)))) scalar))) (define (gen-json-scalar) (gen-sample-of (gen-json-null) (gen-json-string) (gen-json-number))) (define (gen-json-string) (with-size (range 0 20) (gen-string-of (gen-char #\A #\z)))) (define (gen-json-null) (gen-constant (void))) (define (gen-json-number) (gen-sample-of (gen-fixnum) (gen-real))) (define (gen-json-complex nesting) (gen-sample-of (gen-json-object (sub1 nesting)) (gen-json-array (sub1 nesting)))) (define (gen-json-object nesting) (gen-vector-of (gen-pair-of (gen-json-string) (gen-json-value (sub1 nesting))))) (define (gen-json-array nesting) (gen-list-of (gen-json-value (sub1 nesting)))) ;; now let's print our documents (with-size (range 0 20) (gen-for-each 10 print (gen-json-doc 10)))
API
Generators
A generator is a means to create random values that possibly adhere to some constraints. By nature a generator represents and infinite stream of random values.
[syntax] (generator ?body ...)Creates a new generator. You can use this to define your own generators.
Example:
(define (my-gen start)
(generator (+ start 42))
(<- (my-gen 10)) ;=> 52
Extracting data from generators
[procedure] (<- gen)Invokes the generator gen once and returns that value.
[procedure] (<- amount gen)Invokes the generator gen amount times and returns a list of values
[procedure] (gen-for-each n proc gen)Invokes the generator gen n times and applies proc to each value in turn.
Ranges
Many generators accept a range argument that specifies the upper and lower bounds. You can use the following procedures to work with ranges.
[procedure] (range lower upper)Creates a range that covers values from lower to upper. There are three variations of this:
- lower is #f and upper is not #f -> creates a range from (gen-current-fixnum-min) till upper
- lower is not #f and upper is #f -> creates a range from lower till (gen-current-fixnum-max)
- lower is not #f and upper is not #f -> creates a range from lower till upper
Generic generator
The library provides a generic generator procedure that is able to build the correct generator based on the type of the supplied arguments.
[procedure] (gen lower upper)Creates a generator that can be created for the given argument types. Currently supported types are:
- fixnum
- flonum
- char
Creates a generator that can be created for the given range. It dispatches on the type of the lower bound. Currently supported types are:
- fixnum
- flonum
- char
Registers a type-predicate with a generator. When the generic generator procedure gen is invoked, it will dispatch on the first argument using the registered type-predicates.
Parameters
[parameter] gen-current-fixnum-minThe smallest fixnum that should be generated.
[parameter] gen-current-fixnum-maxThe biggest fixnum that should be generated
Primitives
[procedure] (gen-constant value)Generator that always returns value.
[procedure] (gen-fixnum)Generator for a fixnum between gen-current-fixnum-min and gen-current-fixnum-max.
[procedure] (gen-fixnum upper-bound)Generator for a fixnum between gen-current-fixnum-min and upper-bound
[procedure] (gen-fixnum range)Generator for a fixnum within the given range
[procedure] (gen-fixnum lower-bound upper-bound)Generator for a fixnum between lower-bound and upper-bound
[procedure] (gen-odd-fixnum ...)This generator supports all the variations for gen-fixnum but it will only yield odd numbers
[procedure] (gen-even-fixnum ...)This generator supports all the variations for gen-fixnum but it will only yield even numbers
[procedure] (gen-int8)Generator for a fixnum between -127 and 127.
[procedure] (gen-uint8)Generator for a fixnum between 0 and 255.
[procedure] (gen-int16)Generator for a fixnum between -32767 and 3276.
[procedure] (gen-uint16)Generator for a fixnum between 0 and 65535.
[procedure] (gen-int32)Generator for a fixnum between -2147483647 and 2147483647.
[procedure] (gen-uint32)Generator for a fixnum between 0 and 4294967295.
[procedure] (gen-int64)Generator for a fixnum between -9223372036854775807 and 9223372036854775807.
[procedure] (gen-uint8)Generator for a fixnum between 0 and 18446744073709551615.
[procedure] (gen-real)Generator for a real number between 0.0 and 1.0.
[procedure] (gen-real upper-bound)Generator for a real number between 0.0 and upper-bound.
[procedure] (gen-real range)Generator for a real number in the given range.
[procedure] (gen-real lower-bound upper-bound)Generator for a real number between lower-bound and upper-bound.
[procedure] (gen-char)Generator for a character from char-set:graphic.
[procedure] (gen-char charset)Generator for a character from the char-set charset.
[procedure] (gen-char range)Generator for a character in the given range.
[procedure] (gen-char lower-bound upper-bound)Generator for a character from the char-set build from lower-bound to upper-bound. lower-bound must be <= upper-bound as compared with char<=?.
Example:
(gen-char #\a #\z)
[procedure] (gen-bool)
Generator for a random boolean value
[procedure] (gen-sample candidates)Generator that draws a random sample from the list of candidates.
Combinators
[parameter] (gen-current-default-size)A generator that must return a fixnum. It's used to determine the size for generators that can have a length. This defaults to (gen-uint8).
[procedure] (gen-values-of . gens)Generator that returns multiple values. Each value is generated with the given generators
[procedure] (gen-pair-of car-gen cdr-gen)Generator for a pair where the car is generated with car-gen and the cdr is generated with with cdr-gen.
[procedure] (gen-sample-of . gens)Generator that draws a random generator from the list of possible generators and invokes it once.
[procedure] (gen-tuple-of . gens)Generator for a tuple where each element is generated by the given generators.
[procedure] (gen-string-of char-gen size #!optional (size (gen-current-default-size)))Generator for a string where each character is generated from char-gen. The size parameter specifies the size of the strings that are generated. It is expected to be a thunk that returns the size as a fixnum. See with-size for a more convenient way to adjust this.
[procedure] (gen-list-of gen #!optional (size (gen-current-default-size)))Generator for a list where each element is generated with the given generator gen. The size parameter specifies the size of the list that is generated. It is expected to be a thunk that returns the size as a fixnum. See with-size for a more convenient way to adjust this.
[procedure] (gen-alist-of car-gen cdr-gen #!optional (size (gen-current-default-size)))Generator for an alist where each car is generated with car-gen and each cdr is generated with with cdr-gen. The size parameter specifies the size of the list that is generated. It is expected to be a thunk that returns the size as a fixnum. See with-size for a more convenient way to adjust this.
[procedure] (gen-vector-of gen #!optional (size (gen-current-default-size)))Generator for a vector where each element is generated with the given generator gen. The size parameter specifies the size of the vector that is generated. It is expected to be a thunk that returns the size as a fixnum. See with-size for a more convenient way to adjust this.
[procedure] (gen-hash-table-of key-gen value-gen #!optional (size (gen-current-default-size)))Generator for a hash-table where each key is generated by key-gen and each value is generated by value-gen. The size parameter specifies the size of the hash-table that is generated. It is expected to be a thunk that returns the size as a fixnum. See with-size for a more convenient way to adjust this.
[procedure] (gen-record ctor . slot-gens)Generator for a record that is created with the given ctor where each slot is generated with the given slot-gens.
[procedure] (gen-transform transformer gen)Generator that retrieves values from gen and applies transformer to this value.
[syntax] (with-size size-spec ...)Use this to constrain the size of the data generated by the combinators. size-spec is either a fixnum a range or a generator. If it is a fixnum all data will be generated with the size equal to that fixnum. If it is a range, all data will be generated with a size that lies within that range. If it's a generator, this generator is expected to return the size.
Defining your own generators
To define your own generators you can use the generator-syntax.
(define (gen-foo) (generator "foo")) (with-size 3 (gen-list-of (gen-foo))) ;=> ("foo" "foo" "foo")
See also
For a very exhaustive and systematic approach to all kinds of random sources see: srfi-27
License
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. A full copy of the GPL license can be found at <http://www.gnu.org/licenses/>.