Skip to content

Commit

Permalink
Improve demo code
Browse files Browse the repository at this point in the history
  • Loading branch information
matejak committed Nov 25, 2023
1 parent c6c7997 commit cbbfdec
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 57 deletions.
82 changes: 76 additions & 6 deletions estimage/plugins/demo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
import json

import flask
import numpy as np

from ... import simpledata, data


NULL_CHOICE = ("noop", "Do Nothing")


def load_data():
try:
with open("/tmp/estimage_demo.json") as f:
Expand All @@ -17,6 +21,78 @@ def load_data():
return ret



class Demo:
def __init__(self, targets_by_id, loader):
self.targets_by_id = targets_by_id
self.loader = loader

plugin_data = load_data()
self.day_index = plugin_data.get("day_index", 0)
if self.day_index == 0:
start(targets_by_id.values(), loader)

def get_sensible_choices(self):
targets = self.get_ordered_wip_targets()
sensible_choices = [(t.name, t.title) for t in targets]
if not sensible_choices:
sensible_choices = [NULL_CHOICE]
return sensible_choices

def get_ordered_wip_targets(self):
return sorted(self.get_not_finished_targets(), key=lambda t: t.name)

def get_actual_choices(self):
targets = self.get_ordered_wip_targets()
plugin_data = load_data()
velocity_in_stash = plugin_data.get("velocity_in_stash", dict())
label = f"{t.title} {velocity_in_stash.get(t.name, 0):.2g}/{t.point_cost}"
actual_choices = [(t.name, label) for t in targets]
if not actual_choices:
actual_choices = [NULL_CHOICE]
return actual_choices

def evaluate_progress(self, velocity_in_stash, names, model, plugin_data):
for name in names:
target = self.targets_by_id[name]

if velocity_in_stash[name] > model.remaining_point_estimate_of(name).expected:
flask.flash(f"Finished {name}")
conclude_target(target, self.loader, plugin_data["day_index"])
else:
begin_target(target, self.loader, plugin_data["day_index"])

def apply_work(self, progress, names, model):
plugin_data = load_data()
self.day_index += 1
plugin_data["day_index"] = self.day_index
if len(names) == 1 and names[0] == "noop":
pass
else:
velocity_in_stash = plugin_data.get("velocity_in_stash", dict())
apply_velocities(names, progress, velocity_in_stash)
plugin_data["velocity_in_stash"] = velocity_in_stash
evaluate_progress(velocity_in_stash, names, model, plugin_data)
save_data(plugin_data)

def get_not_finished_targets(self):
targets = self.targets_by_id.values()
ret = [t for t in targets if t.state in (data.State.todo, data.State.in_progress)]
ret = [t for t in ret if not t.children]
return ret


def apply_velocity(of_what, how_many, velocity_in_stash):
velocity_in_stash[of_what] = velocity_in_stash.get(of_what, 0) + float(how_many)


def apply_velocities(names, progress, velocity_in_stash):
proportions = np.random.rand(len(names))
proportions *= progress / sum(proportions)
for name, proportion in zip(names, proportions):
apply_velocity(name, proportion, velocity_in_stash)


def save_data(what):
old = load_data()
old.update(what)
Expand Down Expand Up @@ -104,9 +180,3 @@ def conclude_target(target, loader, day_index):

TEMPLATE_OVERRIDES = {
}


def get_not_finished_targets(targets):
ret = [t for t in targets if t.state in (data.State.todo, data.State.in_progress)]
ret = [t for t in ret if not t.children]
return ret
59 changes: 8 additions & 51 deletions estimage/plugins/demo/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,14 @@

import flask
import flask_login
import numpy as np

from ...webapp import web_utils
from . import forms
from . import get_not_finished_targets, load_data, reset_data, save_data, start, conclude_target, begin_target
from .. import demo

bp = flask.Blueprint("demo", __name__, template_folder="templates")


def apply_velocity(of_what, how_many, velocity_in_stash):
velocity_in_stash[of_what] = velocity_in_stash.get(of_what, 0) + float(how_many)


def evaluate_progress(velocity_in_stash, targets_by_id, names, model, plugin_data, loader):
for name in names:
target = targets_by_id[name]

if velocity_in_stash[name] > model.remaining_point_estimate_of(target.name).expected:
flask.flash(f"Finished {target.name}")
conclude_target(target, loader, plugin_data["day_index"])
else:
begin_target(target, loader, plugin_data["day_index"])


def apply_velocities(names, progress, velocity_in_stash):
proportions = np.random.rand(len(names))
proportions *= progress / sum(proportions)
for name, proportion in zip(names, proportions):
apply_velocity(name, proportion, velocity_in_stash)


@bp.route('/demo', methods=("GET", "POST"))
@flask_login.login_required
def next_day():
Expand All @@ -41,45 +18,25 @@ def next_day():

cls, loader = web_utils.get_retro_loader()
targets_by_id, model = web_utils.get_all_tasks_by_id_and_user_model("retro", user_id)
targets = get_not_finished_targets(targets_by_id.values())
targets = [targets_by_id[n] for n in sorted([t.name for t in targets])]

plugin_data = load_data()
if (day_index := plugin_data.get("day_index", 0)) == 0:
start(targets_by_id.values(), loader)
doer = demo.Demo(targets_by_id, loader)

form = forms.DemoForm()
choices = [(t.name, t.title) for t in targets]
if not choices:
choices = [("noop", "Do Nothing")]
form.issues.choices = choices
velocity_in_stash = plugin_data.get("velocity_in_stash", dict())
form.issues.choices = doer.get_sensible_choices()

if form.validate_on_submit():
plugin_data = load_data()
plugin_data["day_index"] = day_index + 1
names = form.issues.data
if len(names) == 1 and names[0] == "noop":
pass
else:
apply_velocities(names, form.progress.data, velocity_in_stash)
plugin_data["velocity_in_stash"] = velocity_in_stash
evaluate_progress(velocity_in_stash, targets_by_id, names, model, plugin_data, loader)
save_data(plugin_data)
doer.apply_work(form.progress.data, form.issues.data, model)

targets = get_not_finished_targets(targets)
choices = [(t.name, f"{t.title} {velocity_in_stash.get(t.name, 0):.2g}/{t.point_cost}") for t in targets]
if not choices:
choices = [("noop", "Do Nothing")]
form.issues.choices = choices
form.issues.choices = doer.get_actual_choices()

return web_utils.render_template(
'demo.html', title='Demo Plugin', reset_form=forms.ResetForm(), plugin_form=form, day_index=day_index)
'demo.html', title='Demo Plugin', reset_form=forms.ResetForm(), plugin_form=form, day_index=doer.day_index)


@bp.route('/reset', methods=("POST", ))
@flask_login.login_required
def reset():
reset_form = forms.ResetForm()
if reset_form.validate_on_submit():
reset_data()
demo.reset_data()
return flask.redirect(flask.url_for("demo.next_day"))
1 change: 1 addition & 0 deletions estimage/plugins/demo/tests/test_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ def some_targets():


def test_select_tasks_not_finished(some_targets):
doer = tm.Demo(some_targets, loader)
assert not tm.get_not_finished_targets([])
assert len(tm.get_not_finished_targets(some_targets)) == 2

0 comments on commit cbbfdec

Please sign in to comment.