<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 This notebook contains high-level tests for tohu's "standard" generators.
Class Integer
Generates random integers in the range [lo, hi].
Step1:  The default distribution is "uniform", but we can use any(?) of the distributions supported by numpy.
Step2:  Class Float
Generates random floating point numbers in the range [lo, hi].
Step3:  Class NumpyRandomGenerator
Generates random numbers using one of the random number generators supported by numpy.
Step4:  Class FakerGenerator
It is also possible to use any generator provided by the faker library.
Step5:  Class Constant
Generates a sequence repeating the same element indefinitely.
Step6:  Class Sequential
Generates a sequence of sequentially numbered strings with a given prefix.
Step7:  Calling reset() on the generator makes the numbering start from 1 again.
Step8:  Note
Step9:  If a new Sequential generator is created from an existing one via the _spawn() method then its count will start again from 1.
Step10:  Class SelectOne
Step11:  It is possible to specify different probabilities for each element to be chosen.
Step12:  Class SelectMultiple
Step13:  Similarly to SelectOne, one can pass a list of probabilities for the values to be chosen.
Step14:  It is also possible to pass a random generator for the argument n. This produces tuples of varying length, where the length of each tuple is determined by the values produced by this generator.
Step15:  Class Subsample
The Subsample generator can extract a subsample from a given set of values, where each individual element is chosen with a given probability p.
Step16:  Class CharString
Step17:  It is possible to vary the length of generated character strings, and to specify the character set.
Step18:  Class DigitString
Step19:  Class HashDigest
Step20:  Class Geolocation
Step21:  Class TimestampNEW
Step22:  Note that the generated items are datetime objects (even though they appear as strings when printed above).
Step23:  Class GeoJSONGeolocationPair
The GeoJSONGeolocationPair allows generating points within a geographical area given by a GeoJSON object.
Step24:  Class ExtractAttribute
Step25:  Using ExtractAttribute we can produce \"derived\" generators which extract the attributes aaa, bbb from the elements produced by g.
Step26:  Class IterateOver
Step27:  Using tohu generators as iterators
Each tohu generator can also be used as a Python iterator producing an (infinite) series of elements.
Step28:  ItemList
The .generate() method produces an ItemList instance.
Step29:  Fundamentally an ItemList behaves like a regular list.
<ASSISTANT_TASK:>
Python Code:
g = Integer(low=100, high=200)
g.reset(seed=12345); print_generated_sequence(g, num=15)
g.reset(seed=9999); print_generated_sequence(g, num=15)
some_integers = g.generate(5, seed=99999)
for x in some_integers:
    print(x)
Explanation: This notebook contains high-level tests for tohu's "standard" generators.
Class Integer
Generates random integers in the range [lo, hi].
End of explanation
#g = Integer(low=100, high=200, distribution=None)
Explanation: The default distribution is "uniform", but we can use any(?) of the distributions supported by numpy.
End of explanation
g = Float(low=2.71828, high=3.14159)
g.reset(seed=12345); print_generated_sequence(g, num=4)
g.reset(seed=9999); print_generated_sequence(g, num=4)
Explanation: Class Float
Generates random floating point numbers in the range [lo, hi].
End of explanation
g1 = NumpyRandomGenerator(method="normal", loc=3.0, scale=5.0)
g2 = NumpyRandomGenerator(method="poisson", lam=30)
g3 = NumpyRandomGenerator(method="exponential", scale=0.3)
g1.reset(seed=12345); print_generated_sequence(g1, num=4)
g2.reset(seed=12345); print_generated_sequence(g2, num=15)
g3.reset(seed=12345); print_generated_sequence(g3, num=4)
Explanation: Class NumpyRandomGenerator
Generates random numbers using one of the random number generators supported by numpy.
End of explanation
g1 = FakerGenerator(method="name")
g2 = FakerGenerator(method="name", locale='hi_IN')
g3 = FakerGenerator(method="phone_number")
g4 = FakerGenerator(method="job")
g1.reset(seed=12345); print_generated_sequence(g1, num=4)
g2.reset(seed=12345); print_generated_sequence(g2, num=4)
g3.reset(seed=12345); print_generated_sequence(g3, num=4)
g4.reset(seed=12345); print_generated_sequence(g4, num=4)
Explanation: Class FakerGenerator
It is also possible to use any generator provided by the faker library.
End of explanation
g = Constant("Foobar"); print_generated_sequence(g, num=10)
g = Constant(42); print_generated_sequence(g, num=20)
Explanation: Class Constant
Generates a sequence repeating the same element indefinitely.
End of explanation
g = Sequential(prefix='Foo_', digits=3)
Explanation: Class Sequential
Generates a sequence of sequentially numbered strings with a given prefix.
End of explanation
g.reset()
print_generated_sequence(g, num=5)
print_generated_sequence(g, num=5)
print("-----------------------------")
g.reset()
print_generated_sequence(g, num=5)
Explanation: Calling reset() on the generator makes the numbering start from 1 again.
End of explanation
g.reset(seed=12345); print_generated_sequence(g, num=5)
g.reset(seed=9999); print_generated_sequence(g, num=5)
Explanation: Note: the method Sequential.reset() supports the seed argument for consistency with other generators, but its value is ignored - the generator is simply reset to its initial value. This is illustrated here:
End of explanation
g1 = Sequential(prefix="Quux_", digits=2)
g1.reset(seed=12345)
print_generated_sequence(g1, num=5)
g2 = g1._spawn()
print_generated_sequence(g1, num=5)
print_generated_sequence(g2, num=5)
Explanation: If a new Sequential generator is created from an existing one via the _spawn() method then its count will start again from 1.
End of explanation
g = SelectOne(values=['foobar', 42, 'quux', True, 1.2345])
g.reset(seed=12345); print_generated_sequence(g, num=15)
g.reset(seed=9999); print_generated_sequence(g, num=15)
Explanation: Class SelectOne
End of explanation
g = SelectOne(values=['aa', 'bb', 'cc'], p=[0.8, 0.15, 0.05])
g.reset(seed=12345); print_generated_sequence(g, num=20)
Explanation: It is possible to specify different probabilities for each element to be chosen.
End of explanation
g = SelectMultiple(values=['foobar', 42, 'quux', True, 1.2345], size=3)
g.reset(seed=12345); print_generated_sequence(g, num=4)
g.reset(seed=99999); print_generated_sequence(g, num=4)
Explanation: Class SelectMultiple
End of explanation
g = SelectMultiple(values=['aa', 'bb', 'cc', 'dd', 'ee'], size=3, p=[0.6, 0.1, 0.2, 0.05, 0.05])
g.reset(seed=12345); print_generated_sequence(g, num=4)
Explanation: Similarly to SelectOne, one can pass a list of probabilities for the values to be chosen.
End of explanation
rand_nums = Integer(low=2, high=5)
g = SelectMultiple(values=['a', 'b', 'c', 'd', 'e'], size=rand_nums)
g.reset(seed=11111); print_generated_sequence(g, num=10, sep='\n')
Explanation: It is also possible to pass a random generator for the argument n. This produces tuples of varying length, where the length of each tuple is determined by the values produced by this generator.
End of explanation
values = list(range(50))
g = Subsample(values, p=0.3)
g.reset(seed=12345); print_generated_sequence(g, num=10, sep='\n')
Explanation: Class Subsample
The Subsample generator can extract a subsample from a given set of values, where each individual element is chosen with a given probability p.
End of explanation
g = CharString(length=15)
g.reset(seed=12345); print_generated_sequence(g, num=5)
g.reset(seed=9999); print_generated_sequence(g, num=5)
Explanation: Class CharString
End of explanation
g = CharString(min_length=4, max_length=12, charset="ABCDEFGHIJKLMNOPQRSTUVWXYZ")
g.reset(seed=12345); print_generated_sequence(g, num=5, sep='\n')
Explanation: It is possible to vary the length of generated character strings, and to specify the character set.
End of explanation
g = DigitString(length=15)
g.reset(seed=12345); print_generated_sequence(g, num=5)
g.reset(seed=9999); print_generated_sequence(g, num=5)
g = DigitString(min_length=5, max_length=20)
g.reset(seed=9999); print_generated_sequence(g, num=10, sep='\n')
Explanation: Class DigitString
End of explanation
g = HashDigest(length=8)
g.reset(seed=12345); print_generated_sequence(g, num=9)
g.reset(seed=9999); print_generated_sequence(g, num=9)
g = HashDigest(length=20)
g.reset(seed=12345); print_generated_sequence(g, num=4)
g.reset(seed=9999); print_generated_sequence(g, num=4)
g = HashDigest(min_length=6, max_length=20)
g.reset(seed=12345); print_generated_sequence(g, num=5, sep='\n')
g = HashDigest(length=16, as_bytes=True)
g.reset(seed=12345); print_generated_sequence(g, num=3, sep='\n')
Explanation: Class HashDigest
End of explanation
g = GeolocationPair()
g.reset(seed=12345); print_generated_sequence(g, num=5, sep='\n')
Explanation: Class Geolocation
End of explanation
from tohu.generators import TimestampNEW
g = TimestampNEW(start='2016-02-14', end='2016-02-18')
g.reset(seed=12345); print_generated_sequence(g, num=5, sep='\n')
g = TimestampNEW(start='1998-03-01 00:02:00', end='1998-03-01 00:02:15')
g.reset(seed=99999); print_generated_sequence(g, num=10, sep='\n')
Explanation: Class TimestampNEW
End of explanation
type(next(g))
Explanation: Note that the generated items are datetime objects (even though they appear as strings when printed above).
End of explanation
import json
from shapely.geometry import MultiPoint
with open('./data/ne_110m_admin_1_states_provinces_shp.geojson', 'r') as f:
    geojson = json.load(f)
g = GeoJSONGeolocationPair(geojson)
pts = g.generate(N=200, seed=12345)
list(pts)[:10]
MultiPoint(pts)
Explanation: Class GeoJSONGeolocationPair
The GeoJSONGeolocationPair allows generating points within a geographical area given by a GeoJSON object.
End of explanation
class QuuxGenerator(CustomGenerator):
    aaa = Integer(0, 100)
    bbb = HashDigest(length=6)
g = QuuxGenerator()
Explanation: Class ExtractAttribute
End of explanation
h1 = ExtractAttribute(g, 'aaa')
h2 = ExtractAttribute(g, 'bbb')
g.reset(seed=99999); print_generated_sequence(g, num=5, sep='\n')
print_generated_sequence(h1, num=5)
print_generated_sequence(h2, num=5)
Explanation: Using ExtractAttribute we can produce \"derived\" generators which extract the attributes aaa, bbb from the elements produced by g.
End of explanation
seq = ['aa', 'bb', 'cc', 'dd', 'ee']
g = IterateOver(seq)
g.reset(); print(list(g.generate(N=3)))
g.reset(); print(list(g.generate(N=10)))
g.reset(); print(list(g))
Explanation: Class IterateOver
End of explanation
int_generator = Integer(low=100, high=500).reset(seed=99999)
for i, x in enumerate(int_generator):
    if i > 20:
        break
    print(x, end=" ")
Explanation: Using tohu generators as iterators
Each tohu generator can also be used as a Python iterator producing an (infinite) series of elements.
End of explanation
g = HashDigest(length=6)
item_list = g.generate(N=10, seed=12345)
print(item_list)
Explanation: ItemList
The .generate() method produces an ItemList instance.
End of explanation
print(list(item_list))
item_list.reset(seed=999999)
print(list(item_list.subsample(num=6)))
print(list(item_list.subsample(num=6)))
print(list(item_list.subsample(num=6)))
item_list.reset(seed=99999)
print(list(item_list.subsample(p=0.4)))
print(list(item_list.subsample(p=0.4)))
print(list(item_list.subsample(p=0.4)))
Explanation: Fundamentally an ItemList behaves like a regular list.
End of explanation
<END_TASK>