Skip to content

Commit 73951e4

Browse files
committed
cleanup
1 parent e58cd2b commit 73951e4

File tree

2 files changed

+163
-11
lines changed

2 files changed

+163
-11
lines changed

syllabus/badge_calc.ipynb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"id": "fa6b2857",
66
"metadata": {},
77
"source": [
8-
"# Badge Calculations \n",
8+
"# Detailed Grade Calculations \n",
99
"\n",
1010
"```{important} \n",
1111
"This page is generated with code and calculations, you can view them for more precise implementations of what the english sentences mean. \n",
@@ -14,7 +14,7 @@
1414
},
1515
{
1616
"cell_type": "code",
17-
"execution_count": 50,
17+
"execution_count": 1,
1818
"id": "51238030",
1919
"metadata": {
2020
"tags": [
@@ -94,7 +94,7 @@
9494
},
9595
{
9696
"cell_type": "code",
97-
"execution_count": 51,
97+
"execution_count": 2,
9898
"id": "c6f0b2ef",
9999
"metadata": {
100100
"tags": [
@@ -190,7 +190,7 @@
190190
"A 206"
191191
]
192192
},
193-
"execution_count": 51,
193+
"execution_count": 2,
194194
"metadata": {},
195195
"output_type": "execute_result"
196196
}
@@ -210,7 +210,7 @@
210210
},
211211
{
212212
"cell_type": "code",
213-
"execution_count": 52,
213+
"execution_count": 3,
214214
"id": "300f22db",
215215
"metadata": {
216216
"tags": [
@@ -345,7 +345,7 @@
345345
"4 community practice_makeup 1.0 0.857143 0.857143"
346346
]
347347
},
348-
"execution_count": 52,
348+
"execution_count": 3,
349349
"metadata": {},
350350
"output_type": "execute_result"
351351
}
@@ -357,7 +357,7 @@
357357
},
358358
{
359359
"cell_type": "code",
360-
"execution_count": 55,
360+
"execution_count": 4,
361361
"id": "9e9201ab",
362362
"metadata": {
363363
"tags": [

syllabus/badges.md

Lines changed: 156 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,164 @@ jupytext:
44
extension: .md
55
format_name: myst
66
format_version: 0.13
7-
jupytext_version: 1.10.3
7+
jupytext_version: 1.15.1
88
kernelspec:
9-
display_name: Python 3
9+
display_name: Python 3 (ipykernel)
1010
language: python
1111
name: python3
1212
---
1313

14-
# Badge Procedures
14+
# Badge Deadlines and Procedures
1515

1616
This page includes more visual versions of the information on the badge page. You should read both, but this one is often more helpful, because some of the processes take a lot of words to explain and make more sense with a diagram for a lot of people.
1717

18+
```{code-cell} ipython3
19+
%matplotlib inline
20+
import os
21+
from datetime import date,timedelta
22+
import calendar
23+
import pandas as pd
24+
import numpy as np
25+
import seaborn as sns
26+
from myst_nb import glue
27+
# style note: when I wrote this code, it was not all one cell. I merged the cells
28+
# for display on the course website, since Python is not the main outcome of this course
29+
30+
# semester settings
31+
first_day = date(2023,9,5)
32+
last_day = date(2023,12,12)
33+
34+
no_class_ranges = [(date(2023,11,23),date(2023,11,26)),
35+
(date(2023,11,13)),
36+
(date(2023,10,10))]
37+
38+
39+
meeting_days =[1,3] # datetime has 0=Monday
40+
spring_break = (date(2023,3,11),date(2023,3,19))
41+
penalty_free_end = date(2023, 9, 28)
42+
43+
44+
def day_off(cur_date,skip_range_list):
45+
'''
46+
is the current date a day off?
47+
48+
Parameters
49+
----------
50+
cur_date : datetime.date
51+
date to check
52+
skip_range_list : list of datetime.date objects or 2-tuples of datetime.date
53+
dates where there is no class, either single dates or ranges specified by a tuple
54+
55+
Returns
56+
-------
57+
day_is_off : bool
58+
True if the day is off, False if the day has class
59+
'''
60+
# default to not a day off
61+
day_is_off=False
62+
#
63+
for skip_range in skip_range_list:
64+
if type(skip_range) == tuple:
65+
# if any of the conditions are true that increments and it will never go down, flase=0, true=1
66+
day_is_off += skip_range[0]<=cur_date<=skip_range[1]
67+
else:
68+
day_is_off += skip_range == cur_date
69+
#
70+
return day_is_off
71+
72+
73+
# enumerate weeks
74+
meeting_days =[1,3] # spring
75+
mtg_delta = timedelta(meeting_days[1]-meeting_days[0])
76+
week_delta = timedelta(7)
77+
78+
during_sb = lambda d: spring_break[0]<d<spring_break[1]
79+
80+
possible = [(first_day+week_delta*w, first_day+mtg_delta+week_delta*w) for w in range(weeks)]
81+
weekly_meetings = [[c1,c2] for c1,c2 in possible if not(day_off(c1,no_class_ranges))]
82+
meetings = [m for w in weekly_meetings for m in w]
83+
meetings_string = [m.isoformat() for m in meetings]
84+
weekly_meetings
85+
86+
87+
# possible = [(first_day+week_delta*w, first_day+mtg_delta+week_delta*w) for w in range(weeks)]
88+
# weekly_meetings = [[c1,c2] for c1,c2 in possible if not(during_sb(c1))]
89+
meetings = [m for w in weekly_meetings for m in w if not(m in skips)]
90+
91+
92+
# build a table for the dates
93+
badge_types = ['experience', 'review', 'practice']
94+
target_cols = ['review_target','practice_target']
95+
df_cols = badge_types + target_cols
96+
badge_target_df = pd.DataFrame(index=meetings, data=[['future']*len(df_cols)]*len(meetings),
97+
columns=df_cols).reset_index().rename(
98+
columns={'index': 'date'})
99+
# set relative dates
100+
today = date.today()
101+
start_deadline = date.today() - timedelta(7)
102+
complete_deadline = date.today() - timedelta(14)
103+
104+
# mark eligible experience badges
105+
badge_target_df['experience'][badge_target_df['date'] <= today] = 'eligible'
106+
# mark targets, cascading from most recent to oldest to not have to check < and >
107+
badge_target_df['review_target'][badge_target_df['date'] <= today] = 'active'
108+
badge_target_df['practice_target'][badge_target_df['date'] <= today] = 'active'
109+
badge_target_df['review_target'][badge_target_df['date']
110+
<= start_deadline] = 'started'
111+
badge_target_df['practice_target'][badge_target_df['date']
112+
<= start_deadline] = 'started'
113+
badge_target_df['review_target'][badge_target_df['date']
114+
<= complete_deadline] = 'completed'
115+
badge_target_df['practice_target'][badge_target_df['date']
116+
<= complete_deadline] = 'completed'
117+
# mark enforced deadlines
118+
badge_target_df['review'][badge_target_df['date'] <= today] = 'active'
119+
badge_target_df['practice'][badge_target_df['date'] <= today] = 'active'
120+
badge_target_df['review'][badge_target_df['date']
121+
<= start_deadline] = 'started'
122+
badge_target_df['practice'][badge_target_df['date']
123+
<= start_deadline] = 'started'
124+
badge_target_df['review'][badge_target_df['date']
125+
<= complete_deadline] = 'completed'
126+
badge_target_df['practice'][badge_target_df['date']
127+
<= complete_deadline] = 'completed'
128+
badge_target_df['review'][badge_target_df['date']
129+
<= penalty_free_end] = 'penalty free'
130+
badge_target_df['practice'][badge_target_df['date']
131+
<= penalty_free_end] = 'penalty free'
132+
133+
# convert to numbers and set dates as index for heatmap compatibility
134+
status_numbers_hm = {status:i+1 for i,status in enumerate(['future','eligible','active','penalty free','started','completed'])}
135+
badge_target_df_hm = badge_target_df.replace(status_numbers_hm).set_index('date')
136+
137+
# set column names to shorter ones to fit better
138+
badge_target_df_hm = badge_target_df_hm.rename(columns={'review':'review(e)','practice':'practice(e)',
139+
'review_target':'review(t)','practice_target':'practice(t)',})
140+
# build a custom color bar
141+
n_statuses = len(status_numbers_hm.keys())
142+
manual_palette = [sns.color_palette("pastel", 10)[7],
143+
sns.color_palette("colorblind", 10)[2],
144+
sns.color_palette("muted", 10)[2],
145+
sns.color_palette("colorblind", 10)[9],
146+
sns.color_palette("colorblind", 10)[8],
147+
sns.color_palette("colorblind", 10)[3]]
148+
# generate the figure, with the colorbar and spacing
149+
ax = sns.heatmap(badge_target_df_hm,cmap=manual_palette,linewidths=1)
150+
# mote titles from bottom tot op
151+
ax.xaxis.tick_top()
152+
# pull the colorbar object for handling
153+
colorbar = ax.collections[0].colorbar
154+
# fix the location fo the labels on the colorbar
155+
r = colorbar.vmax - colorbar.vmin
156+
colorbar.set_ticks([colorbar.vmin + r / n_statuses * (0.5 + i) for i in range(n_statuses)])
157+
colorbar.set_ticklabels(list(status_numbers_hm.keys()))
158+
# add a title
159+
today_string = today.isoformat()
160+
glue('today',today_string,display=False)
161+
glue('today_notdisplayed',"not today",display=False)
162+
ax.set_title('Badge Status as of '+ today_string);
163+
```
164+
18165
## Prepare work and Experience Badges Process
19166

20167
```{warning}
@@ -67,6 +214,7 @@ gitGraph
67214

68215
Where the "approved" tag represents and approving reivew on the PR.
69216

217+
+++
70218

71219
## Review and Practice Badge
72220

@@ -322,4 +470,8 @@ flowchart TD
322470
rev --> approved[Dr. Brown approves] --> merge[Merge the PR]
323471
merge --o earned
324472
325-
```
473+
```
474+
475+
```{code-cell} ipython3
476+
477+
```

0 commit comments

Comments
 (0)