Public
Edited
Feb 10, 2023
Insert cell
Insert cell
getCanvasTeams = () => { // NOTE not a real function, these are console commands for different pages...
// first put students into teams manually on Canvas.
// then, run this command to open all collapsed groups on the groups page
document.querySelectorAll('.group-collapsed-item').forEach(g => g.click())
// then, read names of students per team
let teams = [...document.querySelectorAll('.group')].map(g => ({
name: g.querySelector('.group-name').textContent,
players: [...g.querySelectorAll('.group-user-name')].map(e => ({name: e.textContent.trim()}))}))
.filter(t => t.name.includes('Code') && t.players.length >= 3)
// then, dump data and go to course roster and run this to add login ids
const $ = () => {} // (uses jquery)
teams.map(t => ({...t, players: t.players.map(p => ({...p, loginId: $(`.roster_user_name:contains('${p.name}')`).closest('td').next().text().trim() }))}))
// then, go to code defenders and convert login ids to CodeDefenders ids
teams.map(t => ({...t, players: t.players.map(p => ({...p, userId: $(`td:contains('${p.loginId}')`).prev().text().trim() }))}))
// dump the result into a text file!
}
Insert cell
// all the stuff needed to go--see bottom for commands to run
everything = {
// all the stuff needed to go--see bottom for commands to run
async function addPlayer ({userId, gameId, role }) {
await new Promise(resolve => setTimeout(resolve, 1000)) // pause 1 second between players
console.log('Adding player', {userId, gameId, role })
const getFormData = object => Object.keys(object).reduce((formData, key) => {
formData.append(key, object[key]);
return formData;
}, new FormData());
const data = new URLSearchParams(getFormData({formType:'addPlayerToGame',
userId, gameId, role}))
await fetch("/admin/games", {
method: "post",
headers: {
//'Accept': 'application/json',
'Content-Type': "application/x-www-form-urlencoded"
},
body: data
})
}
async function assignTeamToGame({team, role, gameId}) {
// for player in args.team.players, addPlayer(player.userId, args.role, args.gameId)
for (const p of team.players) { await addPlayer({userId: p.userId, role, gameId}) }
}
function assignPairsToGames({pairs, gameIds}) {
// returns a list of assignments of {team, gameId, role}
// for (gameId, pair) in zip(args.pairs, args.gameIds), pair.map assignTeamToGame({gameId, team})
const zip = (l, r) => l.map((e, i) => [e, r[i]])
return zip(pairs, gameIds).map(([pair, gameId]) => [{gameId, team: pair[0], role: 'ATTACKER'}, {gameId, team: pair[1], role: 'DEFENDER'}]).flat()
// for (const [pair, gameId] of ()) {
// await assignTeamToGame({gameId, team: pair[0], role: 'ATTACKER'})
// await assignTeamToGame({gameId, team: pair[1], role: 'DEFENDER'})
// }
}
async function stageAssignments(assignments) {
for (const assignment of assignments) {
await assignTeamToGame(assignment)
}
}
function randomlyPairTeams({teams}) {
// returns pairs (requires teams is even)
// randomly sort args.teams, then zip(args.teams[:half], args.teams[half:]) and map ['ATTACKER', 'DEFENDER'] to role for those teams
const rand = teams.sort(() => Math.random() > .5)
const zip = (l, r) => l.map((e, i) => [e, r[i]])
console.log('Remember to save these pairs!')
return zip(rand.slice(0, teams.length/2), rand.slice(teams.length/2, teams.length))
}
function readStagedGames() {
// Note you can use search bar to filter before querying
// return gameIds : ["T0", "T1"]
return [...document.querySelectorAll('#table-staged-games tbody tr td:nth-child(2)')].map(e => e.textContent)
}
// DO THESE!!!
// teams = allTeams.attu1 // get subset for this server
// pairs = randomlyPairTeams({teams})
// pairs2 = pairs.map(([l, r], i) => [r, pairs[(i + 1) % pairs.length][0]]) // for the second round, change pairings and swap alignments
// gameIds = readStagedGames()
// assignments = assignPairsToGames({pairs, gameIds})
// stageAssignments(assignments)
}
Insert cell
zip = (l, r) => l.map((e, i) => [e, r[i]])
Insert cell
pairs = zip([1, 2, 3], ['a', 'b', 'c'])
Insert cell
pairs.map(([l, r], i) => [r, pairs[(i + 1) % pairs.length][0]])
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