mggg / GerryChain

Use MCMC to analyze districting plans and gerrymanders
https://mggg.github.io/GerryChain/
Other
131 stars 73 forks source link

Print-able constraints #235

Closed maxhully closed 7 months ago

maxhully commented 5 years ago

It would be really nice, for record-keeping and transparency, if

for constraint in constraints:
    print(constraint)

told you enough about the constraints you used for an MCMC that you could re-configure that chain run from scratch. The descriptions should also be human-readable (like "Parts must be contiguous.").

Having these helpful __str__ methods would also be useful in IPython/Jupyter environments, so that a user could quickly verify that a constraint is what they think it is.

ColCarroll commented 5 years ago

Would something like this work? It is a bit of a mess of metaprogramming, but it is a decorator that can be attached to any function, and uses the first line of the docstring as the repr. It has some nice features, like tab-completion continuing to work.

I've attached a screenshot of how to use it on an existing constraint.

I can document it a bit and submit a pull request if it would be helpful.

image

def extract_doc(f):
    if f.__doc__ is None:
        return f.__repr__()
    doc = f.__doc__.split('\n')[0]
    return '{}: {}'.format(f.__name__, doc)

def add_repr(func):
    doc = extract_doc(func)

    class wrapped:
        __doc__ = func.__doc__
        __name__ = func.__name__

        def __repr__(self):
            return doc

    wrapped.__call__ = staticmethod(func)

    return wrapped()
maxhully commented 5 years ago

I like the idea of this approach! I'm worried that using the first name of the doc string might be a brittle solution. It would also be nice if we could bind some parameters (like functools.partial) of the function, and see those in the generated __repr__, since we run into that a lot. Maybe the name of the function and the parameters supplied would be sufficient for our needs? Could we adapt this approach to something along those lines?