letters = 'abcdefghijklmnopqrstuvwxyz'

Foobar = namedtuple('Foobar', ('foo', 'bar'))
items = [Foobar(c+c, c+c+c) for c in letters]

items[:3]

"""
Explanation: Extracting attributes and aliasing
End of explanation
"""


xx = SelectOne(items)
yy = xx.foo
zz = xx.bar

"""
Explanation: Let's define a generator xx which selects random elements from items, and two other generators yy and zz which extract individual attributes from these elements.
End of explanation
"""


xx.reset(seed=12345)

print_generated_sequence(xx, num=10, sep='\n')
print_generated_sequence(yy, num=10)
print_generated_sequence(zz, num=10)

"""
Explanation: When xx is reset, internally this also automatically resets yy and zz with the same seed (because they are "dependent generators" whose parent is xx).
End of explanation
"""


class QuuxGenerator(CustomGenerator):
    xx = SelectOne(items)
    yy = xx.foo
    zz = xx.bar
    ww = yy  # alias

g = QuuxGenerator()

list(g.generate(10, seed=12345))

"""
Explanation: This also works if xx, yy, zz are defined inside a CustomGenerator.
End of explanation
"""


class FoobarGenerator(CustomGenerator):
    foo = Integer(0, 100)
    bar = HashDigest(length=8)

fg = FoobarGenerator()

items2 = list(fg.generate(10, seed=12345))
items2

class QuuxGenerator(CustomGenerator):
    xx = SelectOne(items2)
    yy = xx.foo
    zz = xx.bar

g = QuuxGenerator()

g.reset(seed=99999); print_generated_sequence(g, num=10, sep='\n')

"""
Explanation: Just for illustration, let's repeat the last example but with a different set of items (produced by another custom generator, although this doesn't really matter).
End of explanation
"""


class QuuxGenerator(CustomGenerator):
    aaa = Integer(0, 100)
    bbb = HashDigest(length=6)

g = QuuxGenerator()

"""
Explanation: 
End of explanation
"""


h1 = ExtractAttribute(g, 'aaa')
h2 = ExtractAttribute(g, 'bbb')

g.reset(seed=99999)
print_generated_sequence(g, num=10, sep='\n')
print_generated_sequence(h1, num=10)
print_generated_sequence(h2, num=10)

"""
Explanation: Using ExtractAttribute we can produce \"derived\" generators which extract the attributes aaa, bbb from the elements produced by g.
End of explanation
"""


letters = 'abcdefghijklmnopqrstuvwxyz'
mapping = dict([(c, c.upper()) for c in letters])

"""
Explanation: Class Lookup
Create mapping from lowercase to uppercase letters.
End of explanation
"""


g = SelectOne(letters)
h = Lookup(g, mapping)

g.reset(seed=12345)
print_generated_sequence(g, num=20)
print_generated_sequence(h, num=20)

"""
Explanation: Create generator g which selects a random letter and generator h which looks up each letter in the lowercase->uppercase mapping.
End of explanation
"""


