synthicity/urbansim — pull request #128 by jiffyclub (2014-11-04 19:14:08+00:00)
Title: Evaluate variables and models a la carte

The main things added here are `eval_variable` and `eval_model`. While I was working on my user meeting demo I wanted to test the functions I'd written but I had to supply the arguments manually, there wasn't a good way to run them under the simulation framework with argument matching and injection. With these functions I could now do something like this:

```python
@sim.injectable()
def func(x, y):
return x + y
```
```python
xy = sim.eval_variable('func')
```

`func` is run exactly as it would be for the purposes of injection and the result is returned to the user. You can supply your own injectables when evaluating a variable:

```python
xy = sim.eval_variable('func', x=5, y=10)
```

Those injectables are only applied temporarily, after the evaluating `func` the sim state goes back to whatever it was before.

`eval_model` works in the same way. I don't expect this feature to be used much in UrbanSim, but it's handy for testing and I could see it being useful in situations where you want to set up a data pipeline that gives a result you want to use interactively instead of passing into models.

`eval_variable`/`model` respect caching. If you want to evaluate something with cacheing turned off you can now use the `cache_disabled` context manager:

```python
with sim.cache_disabled():
xy = sim.eval_variable('func')
```

But note that results calculated while cacheing is disabled globally can still be cached and returned later.

`eval_variable`/`model` take advantage of a new `injectables` context manager that allows you to temporarily set injectables:

```python
with sim.injectables(x=5, y=10, z=20):
xy = sim.eval_variable('func')
yz = sim.eval_variable('func2')
```

When the block is done the simulation state is reset to whatever it was before the `with` statement.