Skip to content

Commit

Permalink
Merge pull request onlyphantom#38 from onlyphantom/veteran
Browse files Browse the repository at this point in the history
enhanced team analytics page and improved cache
  • Loading branch information
onlyphantom authored Apr 24, 2019
2 parents cf72746 + 331e217 commit 5b0e2be
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 56 deletions.
Binary file modified __pycache__/config.cpython-36.pyc
Binary file not shown.
68 changes: 47 additions & 21 deletions app/analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ def team_leadinst_line():
color=alt.condition(
alt.datum.diff > 0,
alt.value("black"),
alt.value("#fd7777")
alt.value("#dc3545")
)
)

Expand All @@ -369,8 +369,7 @@ def team_leadinst_line():
scale=alt.Scale(range=['#375d7b','black']),
legend=alt.Legend(orient='bottom-right',
title=None,
offset=4,
zindex=0)
offset=4)
),
tooltip=['workshop_period:O', 'wh_count']
)
Expand All @@ -384,7 +383,7 @@ def team_leadinst_line():
color=alt.condition(
alt.datum.diff > 0,
alt.value("black"),
alt.value("#fd7777")
alt.value("#dc3545")
)
).transform_filter(
filter={"field":'workshop_period',
Expand Down Expand Up @@ -431,46 +430,72 @@ def factory_homepage():
}
return stats

@cache.cached(timeout=60*60, key_prefix='fa_stats')
def factory_analytics():
dat = df.copy()
yearago = datetime.datetime.now() - datetime.timedelta(weeks=52)
sixmonths = datetime.datetime.now() - datetime.timedelta(weeks=26)
threemonths = datetime.datetime.now() - datetime.timedelta(weeks=13)
dat = dat.loc[(dat.workshop_start >= sixmonths) &
(dat.active == 1) & (dat.name != 'Capstone'), :]
dat['workshop_period'] = dat.loc[:, 'workshop_start'].apply(lambda x: 'Last 3 months' if (x >= threemonths) else '3 months ago')
dat = dat.loc[:,['name','workshop_period','workshop_hours']].groupby(['name','workshop_period']).count().reset_index()
dat.columns = ['name', 'workshop_period', 'wh_count']
dat['diff'] = dat.groupby('name').diff().fillna(method='bfill', limit=1)
df_sum = pd.DataFrame(dat.groupby('name').wh_count.sum())
amonth = datetime.datetime.now() - datetime.timedelta(days=30)

dat_6m = dat.loc[(dat.workshop_start >= sixmonths) &
(dat.active == 1) & (dat.name != 'Capstone'), :]
dat_6m['workshop_period'] = dat_6m.loc[:, 'workshop_start'].apply(lambda x: 'Last 3 months' if (x >= threemonths) else '3 months ago')
dat_6m = dat_6m.loc[:,['name','workshop_period','workshop_hours']].groupby(['name','workshop_period']).count().reset_index()
dat_6m.columns = ['name', 'workshop_period', 'wh_count']
dat_6m['diff'] = dat_6m.groupby('name').diff().fillna(method='bfill', limit=1)
df_sum = pd.DataFrame(dat_6m.groupby('name').wh_count.sum())
max_wh = df_sum.wh_count.max()
min_wh = df_sum.wh_count.min()
max_diff = dat['diff'].max()
min_diff = dat['diff'].min()
max_diff = dat_6m['diff'].max()
min_diff = dat_6m['diff'].min()

dat_12m = dat.loc[(dat.workshop_start >= yearago) &
(dat.active == 1) & (dat.name != 'Capstone'), :]
dat_12m['workshop_period'] = dat_12m.loc[:, 'workshop_start'].apply(
lambda x: 'Past 90 Days' if (x >= threemonths)
else '3 - 6 months' if (x >= sixmonths)
else '6 - 12 months'
)
dat_12m = dat_12m.loc[:,['name','workshop_period','workshop_hours']].groupby(['name','workshop_period']).count().reset_index()
dat_12m.columns = ['name', 'workshop_period', 'wh_count']
dat_12m = dat_12m.pivot(index='name', columns='workshop_period', values='wh_count').fillna(0)
dat_12m = dat_12m.reindex(['6 - 12 months', '3 - 6 months', 'Past 90 Days'], axis=1)
dat_12m['delta'] = dat_12m.iloc[:,2] - dat_12m.iloc[:,1]
dat_12m = dat_12m.sort_values(by=['Past 90 Days', 'delta'], ascending=False)
dat_12m.columns.name = None
dat_12m.index.name= None
def gettimenow():
import arrow
return arrow.get(arrow.utcnow()).humanize()

instructorstats = {
'max_wh': max_wh,
'min_wh': min_wh,
'max_6mths': [i for i in df_sum[df_sum.wh_count == max_wh].index],
'min_6mths': [i for i in df_sum[df_sum.wh_count == min_wh].index],
'max_diff_n': max_diff,
'min_diff_n': min_diff,
'max_diff': [i for i in dat[dat['diff']==max_diff].name.unique()],
'min_diff': [i for i in dat[dat['diff']==min_diff].name.unique()],
'max_diff': [i for i in dat_6m[dat_6m['diff']==max_diff].name.unique()],
'min_diff': [i for i in dat_6m[dat_6m['diff']==min_diff].name.unique()],
'testing': ['Steven Surya', 'Steven Christian'],
'delta_12m': dat_12m.to_html(classes=['table table-bordered table-hover leadinst_table table_12m']),
'updatewhen': gettimenow(),
}
return instructorstats


# @cache.memoize(50)
def factory_accomplishment(u):
workshops = Workshop.query.filter_by(
workshop_instructor=u.id).order_by(Workshop.workshop_start.desc())
workshop_instructor=u).order_by(Workshop.workshop_start.desc())
grped = dict()
totalstud = 0
totalhours = 0


def gettimenow():
import arrow
return arrow.get(arrow.utcnow()).humanize()

for gr in workshops:
category = gr.workshop_category
if category not in grped:
Expand All @@ -491,7 +516,8 @@ def factory_accomplishment(u):
per_page=20, page=1, error_out=True)

stats = {
'joindate': u.join_date,
# 'joindate': u.join_date,
'joindate': "a while ago",
'workshops': workshops.limit(5),
'responses': responses,
'grped': grped,
Expand All @@ -504,8 +530,8 @@ def factory_accomplishment(u):
'topten': df[df.name != 'Capstone'].loc[:,['name','workshop_hours', 'class_size']].groupby(
'name').sum().sort_values(
by='workshop_hours',
ascending=False).head(10).rename_axis(None).to_html(classes=['table thead-light table-striped table-bordered table-hover table-sm'])

ascending=False).head(10).rename_axis(None).to_html(classes=['table thead-light table-striped table-bordered table-hover table-sm']),
'updatewhen': gettimenow(),
}

return stats
5 changes: 3 additions & 2 deletions app/routes.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from flask import render_template, flash, redirect, url_for, g
from flask_login import current_user, login_user, logout_user, login_required
from app import app, db
from app import app, db, cache
from app.analytics import factory_homepage, factory_accomplishment, factory_analytics
from app.users import User
from app.models import Employee, Workshop, Response
Expand Down Expand Up @@ -29,7 +29,8 @@ def accomplishment():
if g.employee is None:
flash('Not registered as a Product team member yet. Check back later!')
return redirect(url_for('index'))
personstats = factory_accomplishment(u=g.employee)
cache.clear()
personstats = factory_accomplishment(u=g.employee.id)
return render_template('accomplishment.html', personstats=personstats)

@app.route('/explorer')
Expand Down
2 changes: 1 addition & 1 deletion app/static/css/pedagogy.css
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ dd {

#submit {
background: rgb(2, 73, 109);
border-radius: 8%;
border-radius: 5px;
border: none;
padding: 1% 2.5%;
color: white;
Expand Down
3 changes: 3 additions & 0 deletions app/templates/accomplishment.html
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ <h4><i class="material-icons md-light">timeline</i> Most Recent Workshops</h4>
</div>
</div>
</div>
<p class="float-right">
<small>Last updated {{ personstats['updatewhen'] }}</small>
</p>
</div>
</div>
<div class="col-12 col-sm-10 col-md-10 col-lg-6 mt-2">
Expand Down
23 changes: 15 additions & 8 deletions app/templates/analytics.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
<div class="jumbotron white">
<h2><i class="material-icons md-dark">insert_chart</i> Team Analytics </h2>
<div class="row">
<div class="col-md-12 col-lg-7 col-sm-12" id="vis_team_1"></div>
<div class="col-md-12 col-lg-7 col-sm-12">
<div id="vis_team_1"></div>
<div class="mt-4">
{{ instructorstats['delta_12m'] | safe }}
</div>
</div>
<div class="col-md-12 col-lg-5 col-sm-12">
<table class="table table-bordered leadinst_table">
<caption>Last updated {{ instructorstats.updatewhen }}</caption>
Expand Down Expand Up @@ -67,16 +72,17 @@ <h2><i class="material-icons md-dark">insert_chart</i> Team Analytics </h2>
<tr>
<th scope="row">Recommendations</th>
<td colspan="2">
{% for inst in instructorstats['min_diff'] %}
{{ inst }}
{% endfor %}
has had limited leading roles in the last 3 months.
Consider more responbsibilities for the individual or call for a performance evaluation.
<!-- Move into separate template and inherit from -->
{% include "sub/recommendations.html" %}
</td>
</tr>
</tbody>
</table>
</div>
</div>

<div class="col-md-12 col-lg-7 col-sm-12">

</div>
</div>
</div>

Expand All @@ -87,13 +93,14 @@ <h2><i class="material-icons md-dark">insert_chart</i> Team Analytics </h2>
renderer: "svg",
actions: {export: false, source: false, editor: false}
};
//var spec = "https://raw.githubusercontent.com/vega/vega/master/docs/examples/bar-chart.vg.json";

vegaEmbed(div, url, opt).then(function(result) {
// Access the Vega view instance (https://vega.github.io/vega/docs/api/view/) as result.view
}).catch(console.error);
}
parse("/data/team_leadinst_line", "#vis_team_1")

document.querySelector('table.table_12m > thead').setAttribute('class', 'thead-light');
</script>
{% endblock %}

28 changes: 28 additions & 0 deletions app/templates/sub/recommendations.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{% if instructorstats['min_diff']|length == 1 %}
{% for inst in instructorstats['min_diff'] %}
{{ inst }}
{% endfor %}
{% else %}
{% set comma = joiner(", ") %}
{% for inst in instructorstats['min_diff'] %}
{{ comma() }}{{ inst }}
{% endfor %}
{% endif %}
had limited leading roles in the last 3 months.
Consider increasing the number of opportunities for the individual(s) or call for a performance evaluation.

<hr>
{% if instructorstats['max_6mths']|length == 1 %}
{% for inst in instructorstats['max_6mths'] %}
{{ inst }}
{% endfor %}
{% else %}
{% set comma = joiner(", ") %}
{% for inst in instructorstats['max_6mths'] %}
{{ comma() }}{{ inst }}
{% endfor %}
{% endif %}
led the team with {{ instructorstats['max_wh'] }} lead instructor assignments.
Consider greater responsibilities for the individual(s). Diversification greatly enhances
personal growth by adding a level of robustness to the person's skill exposure.

47 changes: 23 additions & 24 deletions app/templates/sub/single_response.html
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@

<div class="card response-card">
<p class="card-text">{{ review['comments'] }}</p>
<ul>
{% if review['difficulty'] >= 4%}
<li><i class="material-icons">check</i>Lecture wasn't too difficult</li>
{% endif %}
{% if review['difficulty'] >= 4%}
<li><i class="material-icons">check</i>Training was knowledgeable</li>
{% endif %}
{% if review['objectives'] >= 4 %}
<li><i class="material-icons">check</i>Training objectives were met</li>
{% endif %}
{% if review['timeliness'] >= 4 %}
<li><i class="material-icons">check</i>Time allocated was sufficient</li>
{% endif %}
{% if review['satisfaction_score'] >= 4 %}
<li><i class="material-icons">check</i>Great Overall Experience </li>
{% endif %}
</ul>
<footer class="blockquote-footer">
<small>Student from {{ review['workshop'] }}</small>
</footer>
</div>
<div class="card response-card">
<p class="card-text">{{ review['comments'] }}</p>
<ul>
{% if review['difficulty'] >= 4%}
<li><i class="material-icons">check</i>Lecture wasn't too difficult</li>
{% endif %}
{% if review['difficulty'] >= 4%}
<li><i class="material-icons">check</i>Training was knowledgeable</li>
{% endif %}
{% if review['objectives'] >= 4 %}
<li><i class="material-icons">check</i>Training objectives were met</li>
{% endif %}
{% if review['timeliness'] >= 4 %}
<li><i class="material-icons">check</i>Time allocated was sufficient</li>
{% endif %}
{% if review['satisfaction_score'] >= 4 %}
<li><i class="material-icons">check</i>Great Overall Experience </li>
{% endif %}
</ul>
<footer class="blockquote-footer">
<small>Student from {{ review['workshop'] }}</small>
</footer>
</div>

0 comments on commit 5b0e2be

Please sign in to comment.