Gonzalo Pincheira A. - @gpincheiraa
1° Historia en la pedagogía
2° Boolean Academia
3° eDX, Pruebas de Software y MAGIC
4° Integración Continua y Github Classroom
5° Octokit y JavaScript
6° Conclusiones
Desde Joven me interesó el trabajo con computadoras y pedagogía.
En 6to de primaria, a los 12 años, fui seleccionado para enseñar a todos los compañeros que se interesaran en aprender a computadores.
A los 13 años hice mi primer programa: Un pokedéx con fotos de emulador de GameBoy editadas en paint, incluidas en un script Visual Basic.
En mi adolescencia en el liceo y universidad, acostumbraba realizar clases particulares gratuitas a familiares, amigos y conocidos
Desde el 2014 he participado en comunidades de Software: Más de 15 charlas y Workshops en Vivo
+ 300hrs de pedagogía en el sistema REUF de Estado
2019 junto a Sebastián Jiménez fundamos Boolean Academia. Más de 30 egresados del curso FullStack JavaScript PRO
Nace en 2016 como idea de enseñar tecnologías pero con profundo hincapié en material práctico
Primeras consultorías en Desarollo de Software con Angular en 2018
Experiencia online como parte de nuestra metodología enseñando prácticas como Pruebas de Software e Integración Continua
Sabiamos que la experiencia que queriamos construir para los estudiantes era DEMASIADO COSTOSA
EdX es un proveedor de cursos en línea masivos y abiertos.
Trabajan con las universidades y organizaciones líderes a nivel mundial
Me interesó porque enseñaban Pruebas de Software e Integración Continua
Al cursarlo descubri que no solo enseñaban pruebas, sino que las usaban para revisar los trabajos
Ahora ya estaba egresado…
… ¿Cómo lo habrán hecho para revisar masivamente todos los trabajos?
MAGIC: Massive Automated Grading in the Cloud
MAGIC: Massive Automated Grading in the Cloud
MAGIC: Massive Automated Grading in the Cloud
MAGIC: Massive Automated Grading in the Cloud
Cómo implementamos?
Que herramienta usamos para dar más fluidez a los laboratorios
Respuestas: Github Classroom y Jest
Framework de pruebas con una interfaz super fluida en terminal y fácil integración
Ecosistema para administrar repositorios y administrar tareas que se pueden Auto-Evaluar
#!/usr/bin/env node
const {
getStudentsList,
getCourseLaboratories,
writeCourseLabsByStudent,
checkStudentLaboratoriesResults,
wait
} = require('../src/main')
async function main() {
const studentsList = await getStudentsList()
const laboratories = await getCourseLaboratories() || []
const usernamesList = studentsList
.map(({ username }) => username)
let courseLabsResultsMap = {}
// obtener resultados y obtener objeto, e imprimir objeto en cada iteración (privado)
for (username of usernamesList) {
try {
const studentResults = await checkStudentLaboratoriesResults(username, laboratories.length)
courseLabsResultsMap = {
...courseLabsResultsMap,
...studentResults,
}
await wait(3)
} catch(error) {
console.error(error)
process.exit(1)
}
}
await writeCourseLabsByStudent(courseLabsResultsMap)
}
main()
async function checkStudentLaboratoriesResults(studentUsername, totalLabs) {
return collectResults(studentUsername, totalLabs)
.then(results => {
const { progressDisplay, progressValue } = getCourseCompletedPercentage(results, totalLabs)
const studentResults = {
[studentUsername]: {
username: studentUsername,
lastRevision: (new Date()).getTime(),
successTasks: progressDisplay,
completedPercentage: progressValue,
results
}
}
return prettyCheckLabsMessage(studentUsername, studentResults)
})
}
async function collectResults(studentUsername, totalLabs) {
// https://github.com/booleancl/lab-19-DiegoMoralesC/actions/workflows/classroom.yml/badge.svg
// https://docs.github.com/en/rest/reference/actions#list-jobs-for-a-workflow-run
const studentLabsRequesPaths = getStudentLabsRequestPaths(
studentUsername,
totalLabs
)
const results = []
for (labRequest of studentLabsRequesPaths) {
console.log(`Processing ${labRequest.labPath} for student ${studentUsername}`)
try {
const workflowsResponse = await octokit.request(labRequest.url)
const [ lastWorkflow ] = workflowsResponse.data.workflow_runs
if (!lastWorkflow) {
const message = `Lab ${labRequest.labPath} without Autograding`
results.push({
id: labRequest.labPath,
status: 'completed',
conclusion: 'success-with-failure',
message
})
continue
}
const jobsResponse = await octokit.request(`GET /repos/booleancl/${labRequest.labPath}/actions/runs/${lastWorkflow.id}/jobs`)
const [ lastPipeline ] = jobsResponse.data.jobs
.map(({ status, conclusion, html_url}) => ({
id: labRequest.labPath,
status,
conclusion,
html_url,
message: `Lab ${labRequest.labPath} ${conclusion === 'success'? 'OK' : 'FAILED'}`
}))
results.push(lastPipeline)
} catch (error) {
results.push({
id: labRequest.labPath,
status: 'failure',
conclusion: 'failure',
message: `Lab ${labRequest.labPath} FAILED: ${error.message}`
})
}
clearLastLine()
}
return Promise.resolve(results)
}
function getStudentLabsRequestPaths(studentUsername, totalLabs) {
const labPaths = []
for (let labIndex = 1; labIndex <= totalLabs; labIndex++) {
const labId = labIndex < 10 ? `0${labIndex}` : labIndex
const labPath = `${PREFIX_LAB}-${labId}-${studentUsername}`
const url = `GET /repos/booleancl/${labPath}/actions/runs`
labPaths.push({ labPath, url })
}
return labPaths
}
Gonzalo Pincheira A. - @gpincheiraa