Published
Edited
Feb 27, 2020
Insert cell
md`# datasys`
Insert cell
Insert cell
schedule_in = yaml.safeLoad(schedule_in_raw)
Insert cell
schedule_events = Object.entries(schedule_in).map(([k, v])=> {
return v.map(e=> {
const {date, week, location, ...rest} = e
const locationOneKthGet = l=> ({
type: 'kth-place',
title: l,
})
const locationGet = l=> {
const ls = !l?[]:l.split(', ')
if (!ls.length) return null
if (ls.length==1) return locationOneKthGet(ls[0])
return ({
type: 'many',
value: ls.map(locationOneKthGet),
})
}
return {
...rest,
location: locationGet(location),
date: {
week: parseInt(k.match(/\d+/)[0]),
orgStr: date,
...dateLineParse(date),
},
}
})
}).reduce((a, b)=> a.concat(b), [])
Insert cell
assignment_raw = `
- [03, 18, 01, [A, M, K, L]]
- [03, 18, 01, [A, M, K, L]]
- [03, 23, 02, [K, L]]
- [03, 26, 03, [A, M, K]]
- [03, 31, 04, [A, M, K]]
- [04, 03, 05, [M, K]]
- [04, 08, 06, [M, L]]
- [04, 20, 07, [M, L]]
- [04, 24, 08, [M, L]]
- [04, 28, 08, [A, L]]
- [05, 04, 09, [A, L]]
- [05, 06, 09, [A, L]]
- [05, 11, 10, [K, L]]
- [05, 13, 10, [K, L]]
`
Insert cell
assignment_config = yaml.safeLoad(assignment_raw).map(([month, day, project, tutors])=> ({
month: parseInt(month),
day: parseInt(day),
project: parseInt(project),
tutors,
}))
Insert cell
tutorsMap = {
const raw = yaml.safeLoad(`
K:
name: Kaj Munhoz Arfvidsson
email: kajarf@kth.se
M:
name: Martin Lindström
email: mali5@kth.se
L:
name: Leonard Pauli
email: leonardp@kth.se
A:
name: Albin Mosskull
email: albinmos@kth.se

`)
Object.entries(raw).map(([id, o])=> o.id = id)
return raw
}
Insert cell
dateLineParse = str=> {
// Mon 6 apr 10:00-12:00
const dateLineRegex = /(?<dayName>[^ ]+) (?<dateNr>\d+) (?<monthNameShort>[^ ]+) (?<timeStart>[^-]+)-(?<timeEnd>[^-]+)/
const match = dateLineRegex.exec(str)
if (!match) return null
const {groups: {dayName, dateNr, monthNameShort, timeStart, timeEnd}} = match

const months = 'january,february,march,april,may,june,july,august,september,october,november,december'.split(',')
const monthsMap = Object.fromEntries(months.map((m, i)=> [m.substring(0, 3), i]))

const monthIndex = monthsMap[monthNameShort]

return {
monthIndex,
day: parseInt(dateNr),
timeStart, timeEnd,
dayName, monthNameShort,
}
}
Insert cell
dateLineParse('Mon 6 apr 10:00-12:00')
Insert cell
events_assembled = schedule_events.map(event=> {
if (event.type!=='tutorial') return {...event}
const {tutors, project: projectNr} = assignment_config
.find(c=> c.month === event.date.monthIndex+1 && c.day === event.date.day) || {}
return {
...event,
projectNr,
tutors: tutors.map(tid=> tutorsMap[tid]),
}
})
Insert cell
events_vis(events_assembled)
Insert cell
tutConsultationsNrMap = {
const tut = Object.fromEntries(Object.keys(tutorsMap).map(k=> [k, 0]))
assignment_config.map(m=> m.tutors.map(tid=> tut[tid]++))
return tut
}
Insert cell
tuts_tot_salary = salary(Object.entries(tutConsultationsNrMap).map(([_, nr])=> nr).reduce((a, v)=> a+v, 0))
Insert cell
Math.round(tuts_tot_salary/0.7/0.9/1000)*1000 // estimated tot cost for all tuts for KTH
Insert cell
salary = consultations=> consultations*(2+4)*150
Insert cell
kth_location_href = q=> `https://www.kth.se/search?q=${encodeURIComponent(q)}&entityFilter=kth-place&filterLabel=Facilities`
Insert cell
md`## TODO
project canvas downloads: https://kth.instructure.com/courses/17171/pages/project-descriptions-and-submission-instructions?module_item_id=188105
project canvas quizzes: https://kth.instructure.com/courses/17171/quizzes

`
Insert cell
events_vis = es=> {
const container = html`<div class="events"></div>`
const element = html`<div class="events-elem">
<style>
.events-elem {
padding-bottom: 30px;
}

.events {
display: flex;
flex-direction: column;
max-height: 900px;
flex-wrap: wrap;
}

.events > .week-separator {
margin-top: 10px;
color: hsla(0,0%,0%,0.5);
}

.events > .event {
margin: 5px;
min-width: 500px;
}

.events > .event .date {
min-width: 60px;
display: inline-block;
}

.events > .event .tag {
padding: 2px 8px;
border-radius: 4px;
background-color: hsl(0,0%,90%);
}
.events > .event .tag[data-type="tutorial"] {
background-color: hsl(250,100%,90%);
}
.events > .event .tag[data-type="presentation"] {
background-color: hsl(50,80%,90%);
}
.events > .event .tag[data-type="test"] {
background-color: hsl(30,70%,90%);
}
.events > .event .tag[data-type="examination"] {
background-color: hsl(10,70%,90%);
}

.events > .event .tutor {
border-radius: 1000px;
display: inline-flex;
width: 1.3em;
height: 1.3em;

background-color: hsl(0,0%,90%);
margin-left: 3px;

justify-content: center;
align-items: center;
vertical-align: middle;
position: relative;
top: -1px;
}
.events > .event .tutor > span {
font-size: 0.7em;
color: hsla(0,0%,0%,0.65);
font-weight: bold;
font-family: sans-serif;
}
.events > .event .tutor[data-id="L"] {
background-color: hsl(200,100%,80%);
}
.events > .event .tutor[data-id="K"] {
background-color: hsl(30,60%,70%);
}
.events > .event .tutor[data-id="M"] {
background-color: hsl(350,80%,80%);
}
.events > .event .tutor[data-id="A"] {
background-color: hsl(135,70%,80%);
}

</style>
<h1>datasys ht.2020 overview</h1>

${container}

<br/><br/>
<h3>Notes:</h3>
For each project, also check
<a href="https://kth.instructure.com/courses/17171/pages/project-descriptions-and-submission-instructions?module_item_id=188105">canvas downloads</a>
and
<a href="https://kth.instructure.com/courses/17171/quizzes">canvas quizzes</a>
<br/>
<div style="opacity: 0.5; font-size: 0.8em; margin-top: 10px;">Created by Leonard Pauli, for datasys (KTH course EP1200), feb 2020</div>
</div>`
const locationElGet = l=>
l === null? ''
: l.type === 'many'? (()=> {
const p = html`<span></span>`
l.value.map(locationElGet).map((el, i)=> (i>0&&p.append(', '), p.appendChild(el)))
return p
})()
: l.type === 'kth-place'?
html`<a href="${kth_location_href(l.title)}">${l.title}</a>`
: null
const tutorElGet = t=> html`<span class="tutor" data-id="${t.id}"><span>${t.id}</span></span>`
const tutorsElGet = ts=> {
const el = html`<span></span>`
ts.map(tutorElGet).map(e=> el.appendChild(e))
return el
}
const projectElGet = nr=> {
const link = html`<a class="tag project" href="https://www.nand2tetris.org/project${nr<10?'0':''}${nr}">pr.${nr}</a>`
return link
}
let weekPrev = null
es.map(e=> {
if (weekPrev!==e.date.week) {
container.appendChild(html`<div class="week-separator">Week ${e.date.week}</div>`)
weekPrev = e.date.week
}
const el = html`<div class="event">
<span class="date">${e.date.day} ${e.date.monthNameShort}:</span>
${e.date.timeStart}-${e.date.timeEnd}:
<span class="tag" data-type="${e.type}">${e.type}</span>
${e.type==='tutorial'? projectElGet(e.projectNr): ''}
${e.location?locationElGet(e.location):''}
${e.type==='tutorial'? tutorsElGet(e.tutors): ''}
</div>`
container.appendChild(el)
})
element.value = es
return element
}
Insert cell
md`## Dependencies`
Insert cell
yaml = require('js-yaml@3.13.1/dist/js-yaml.js')
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more