# fakir
## a mildly monadic module for fast faking

A deliberately minimalist library for building graphs of random number
generators with interesting dependencies, and running them to generate
plausible-looking "fake data" for a variety of domains.

Pure Python with type annotations; depends only on the standard `random`
module.

Let's generate some bogus data with a vaguely oil-and-gas flavor:

    from fakir import fixed, rng_fn, uniform, normal, choice, tupled, ifelse
    from random import Random
    import sys
    
    from typing import List
    
    def main(argv: List[str]) -> int:
        animal = choice(['Wolf', 'Eagle', 'Cheetah'])
        geo = choice(['Outcrop', 'Karst', 'Tundra'])
    
        formation = animal + fixed(' ') + geo
    
        area = normal(40, 10)
        height = uniform(10, 100)
        volume = area * height
    
        phase = choice(['Oil', 'Gas'])
        price = ifelse(phase == fixed('Oil'),
            uniform(30, 60),
            uniform(1.5, 4.5)
        )
    
        row = tupled(formation, area, height, volume, phase, price, area.iid(), price.iid())
    
        r = Random(12345)
        for i in range(100):
            print(row.generate(r))
    
        return 0
    
    if __name__ == '__main__':
        sys.exit(main(sys.argv))

`fakir` is "monad-inspired": there's an explicit `bind`, but graphs are
implicitly monadic by default.
That is, in the example above, `price` generates prices corresponding to the
phase generated by `phase` in a given "generation cycle"---it's as if we really
had written (using the phase and price produced "tupled" by `phase_price`):

    phase = choice(['Oil', 'Gas'])
    phase_price = phase.bind(
            lambda p: (
                uniform(30, 60) if p == 'Oil' else uniform(1.5, 4.5)
            ).fmap(lambda pr: (p, pr))) 

To "opt out" of this implicit bind, clone Fakir objects into independent
identically distributed objects with the `iid` method.

Why is this a "package" and not a "module"? PEP 561 says that's the only way to get type information distributed (with `py.typed`). Someone who actually cares enough to bother should start a petition or something, because this kind of unbridled complexity addiction is what's destroying Python and the last shreds of my sanity.

View the full [pdoc3-generated API documentation](https://ghcdn.rawgit.org/derrickturk/fakir/master/doc/fakir/index.html).

Install with:
    pip install fakir

Or download directly [from PyPI](https://pypi.org/project/fakir/).

### (c) 2020 dwt | terminus data science, LLC
### available under the Apache License 2.0
