<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Primitive generators
This notebook contains tests for tohu's primitive generators.
Step1:  Constant
Constant simply returns the same, constant value every time.
Step2:  Boolean
Boolean returns either True or False, optionally with different probabilities.
Step3:  Integer
Integer returns a random integer between low and high (both inclusive).
Step4:  Float
Float returns a random float between low and high (both inclusive).
Step5:  HashDigest
HashDigest returns hex strings representing hash digest values (or alternatively raw bytes).
HashDigest hex strings (uppercase)
Step6:  HashDigest hex strings (lowercase)
Step7:  HashDigest byte strings
Step8:  NumpyRandomGenerator
This generator can produce random numbers using any of the random number generators supported by numpy.
Step9:  FakerGenerator
FakerGenerator gives access to any of the methods supported by the faker module. Here are a couple of examples.
Example
Step10:  Example
Step11:  IterateOver
IterateOver is a generator which simply iterates over a given sequence. Note that once the generator has been exhausted (by iterating over all its elements), it needs to be reset before it can produce elements again.
Step12:  SelectOne
Step13:  By default, all possible values are chosen with equal probability, but this can be changed by passing a distribution as the parameter p.
Step14:  We can see that the item 'cc' has the highest chance of being selected (70%), followed by 'ee' and 'aa' (12% and 10%, respectively).
Timestamp
Timestamp produces random timestamps between a start and end time (both inclusive).
Step15:  If start or end are dates of the form YYYY-MM-DD (without the exact HH
Step16:  For convenience, one can also pass a single date, which will produce timestamps during this particular date.
Step17:  Note that the generated items are datetime objects (even though they appear as strings when printed above).
Step18:  We can use the .strftime() method to create another generator which returns timestamps as strings instead of datetime objects.
Step19:  CharString
Step20:  It is possible to explicitly specify the character set.
Step21:  There are also a few pre-defined character sets.
Step22:  DigitString
DigitString is the same as CharString with charset='0123456789'.
Step23:  Sequential
Generates a sequence of sequentially numbered strings with a given prefix.
Step24:  Calling reset() on the generator makes the numbering start from 1 again.
Step25:  Note that 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
<ASSISTANT_TASK:>
Python Code:
import tohu
from tohu.v4.primitive_generators import *
from tohu.v4.dispatch_generators import *
from tohu.v4.utils import print_generated_sequence
print(f'Tohu version: {tohu.__version__}')
Explanation: Primitive generators
This notebook contains tests for tohu's primitive generators.
End of explanation
g = Constant('quux')
print_generated_sequence(g, num=10, seed=12345)
Explanation: Constant
Constant simply returns the same, constant value every time.
End of explanation
g1 = Boolean()
g2 = Boolean(p=0.8)
print_generated_sequence(g1, num=20, seed=12345)
print_generated_sequence(g2, num=20, seed=99999)
Explanation: Boolean
Boolean returns either True or False, optionally with different probabilities.
End of explanation
g = Integer(low=100, high=200)
print_generated_sequence(g, num=10, seed=12345)
Explanation: Integer
Integer returns a random integer between low and high (both inclusive).
End of explanation
g = Float(low=2.3, high=4.2)
print_generated_sequence(g, num=10, sep='\n', fmt='.12f', seed=12345)
Explanation: Float
Float returns a random float between low and high (both inclusive).
End of explanation
g = HashDigest(length=6)
print_generated_sequence(g, num=10, seed=12345)
Explanation: HashDigest
HashDigest returns hex strings representing hash digest values (or alternatively raw bytes).
HashDigest hex strings (uppercase)
End of explanation
g = HashDigest(length=6, uppercase=False)
print_generated_sequence(g, num=10, seed=12345)
Explanation: HashDigest hex strings (lowercase)
End of explanation
g = HashDigest(length=10, as_bytes=True)
print_generated_sequence(g, num=5, seed=12345, sep='\n')
Explanation: HashDigest byte strings
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: NumpyRandomGenerator
This generator can produce random numbers using any of the random number generators supported by numpy.
End of explanation
g = FakerGenerator(method='name')
print_generated_sequence(g, num=8, seed=12345)
Explanation: FakerGenerator
FakerGenerator gives access to any of the methods supported by the faker module. Here are a couple of examples.
Example: random names
End of explanation
g = FakerGenerator(method='address')
print_generated_sequence(g, num=8, seed=12345, sep='\n---\n')
Explanation: Example: random addresses
End of explanation
seq = ['a', 'b', 'c', 'd', 'e']
g = IterateOver(seq)
g.reset()
print([x for x in g])
print([x for x in g])
g.reset()
print([x for x in g])
Explanation: IterateOver
IterateOver is a generator which simply iterates over a given sequence. Note that once the generator has been exhausted (by iterating over all its elements), it needs to be reset before it can produce elements again.
End of explanation
some_items = ['aa', 'bb', 'cc', 'dd', 'ee']
g = SelectOne(some_items)
print_generated_sequence(g, num=30, seed=12345)
Explanation: SelectOne
End of explanation
g = SelectOne(some_items, p=[0.1, 0.05, 0.7, 0.03, 0.12])
print_generated_sequence(g, num=30, seed=99999)
Explanation: By default, all possible values are chosen with equal probability, but this can be changed by passing a distribution as the parameter p.
End of explanation
g = Timestamp(start='1998-03-01 00:02:00', end='1998-03-01 00:02:15')
print_generated_sequence(g, num=10, sep='\n', seed=99999)
Explanation: We can see that the item 'cc' has the highest chance of being selected (70%), followed by 'ee' and 'aa' (12% and 10%, respectively).
Timestamp
Timestamp produces random timestamps between a start and end time (both inclusive).
End of explanation
g = Timestamp(start='2018-02-14', end='2018-02-18')
print_generated_sequence(g, num=5, sep='\n', seed=12345)
Explanation: If start or end are dates of the form YYYY-MM-DD (without the exact HH:MM:SS timestamp), they are interpreted as start='YYYY-MM-DD 00:00:00 and end='YYYY-MM-DD 23:59:59', respectively - i.e., as the beginning and the end of the day.
End of explanation
g = Timestamp(date='2018-01-01')
print_generated_sequence(g, num=5, sep='\n', seed=12345)
Explanation: For convenience, one can also pass a single date, which will produce timestamps during this particular date.
End of explanation
g.reset(seed=12345)
[next(g), next(g), next(g)]
Explanation: Note that the generated items are datetime objects (even though they appear as strings when printed above).
End of explanation
h = Timestamp(date='2018-01-01').strftime('%-d %b %Y, %H:%M (%a)')
h.reset(seed=12345)
[next(h), next(h), next(h)]
Explanation: We can use the .strftime() method to create another generator which returns timestamps as strings instead of datetime objects.
End of explanation
g = CharString(length=15)
print_generated_sequence(g, num=5, seed=12345)
print_generated_sequence(g, num=5, seed=99999)
Explanation: CharString
End of explanation
g = CharString(length=12, charset="ABCDEFG")
print_generated_sequence(g, num=5, sep='\n', seed=12345)
Explanation: It is possible to explicitly specify the character set.
End of explanation
g1 = CharString(length=12, charset="<lowercase>")
g2 = CharString(length=12, charset="<alphanumeric_uppercase>")
print_generated_sequence(g1, num=5, sep='\n', seed=12345); print()
print_generated_sequence(g2, num=5, sep='\n', seed=12345)
Explanation: There are also a few pre-defined character sets.
End of explanation
g = DigitString(length=15)
print_generated_sequence(g, num=5, seed=12345)
print_generated_sequence(g, num=5, seed=99999)
Explanation: DigitString
DigitString is the same as CharString with charset='0123456789'.
End of explanation
g = Sequential(prefix='Foo_', digits=3)
Explanation: 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=99999); print_generated_sequence(g, num=5)
Explanation: Note that 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
<END_TASK>