|
@@ -1,223 +1,340 @@
|
|
-// Dados constantes
|
|
|
|
-const exerciseTheme = [ "Leitura e Escrita",
|
|
|
|
- "Manipulação de Entrada",
|
|
|
|
- "Lógica",
|
|
|
|
- "Matemática",
|
|
|
|
- "Condição",
|
|
|
|
- "Condição de Parada",
|
|
|
|
- "Laço",
|
|
|
|
- "Vetor"]
|
|
|
|
|
|
|
|
-const testCaseTypes = [ "Caso Geral",
|
|
|
|
- "Caso Limite",
|
|
|
|
- "Caso Nulo",
|
|
|
|
- "Caso Negativo",
|
|
|
|
- "Igualdade",
|
|
|
|
- "Tipo de Entrada"]
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-// Aquisição de dados externos
|
|
|
|
-// Dados vindos do Avaliador Automático
|
|
|
|
-let exerciseType = [exerciseTheme[getRandomInt(0, exerciseTheme.length)],
|
|
|
|
- exerciseTheme[getRandomInt(0, exerciseTheme.length)]];
|
|
|
|
-
|
|
|
|
-let testCases = [ {tag: testCaseTypes[getRandomInt(0, testCaseTypes.length)], incorrect: getRandomInt(0,2)},
|
|
|
|
- {tag: testCaseTypes[getRandomInt(0, testCaseTypes.length)], incorrect: getRandomInt(0,2)},
|
|
|
|
- {tag: testCaseTypes[getRandomInt(0, testCaseTypes.length)], incorrect: getRandomInt(0,2)},
|
|
|
|
- {tag: testCaseTypes[getRandomInt(0, testCaseTypes.length)], incorrect: getRandomInt(0,2)},
|
|
|
|
- {tag: testCaseTypes[getRandomInt(0, testCaseTypes.length)], incorrect: getRandomInt(0,2)},
|
|
|
|
- {tag: testCaseTypes[getRandomInt(0, testCaseTypes.length)], incorrect: getRandomInt(0,2)}];
|
|
|
|
-
|
|
|
|
-let allIncorrect = true;
|
|
|
|
-
|
|
|
|
-// Dados vindos da base de dados associada ao aluno
|
|
|
|
-let types = [ {type: exerciseTheme[0], total: 1, errors: 0},
|
|
|
|
- {type: exerciseTheme[1], total: 3, errors: 0},
|
|
|
|
- {type: exerciseTheme[2], total: 2, errors: 0},
|
|
|
|
- {type: exerciseTheme[3], total: 1, errors: 0},
|
|
|
|
- {type: exerciseTheme[4], total: 2, errors: 0},
|
|
|
|
- {type: exerciseTheme[5], total: 9, errors: 2},
|
|
|
|
- {type: exerciseTheme[6], total: 4, errors: 0},
|
|
|
|
- {type: exerciseTheme[7], total: 1, errors: 0}];
|
|
|
|
-
|
|
|
|
-let tags = [{tag: testCaseTypes[0], total: 15, errors: 0},
|
|
|
|
- {tag: testCaseTypes[1], total: 8, errors: 1},
|
|
|
|
- {tag: testCaseTypes[2], total: 5, errors: 1},
|
|
|
|
- {tag: testCaseTypes[3], total: 6, errors: 0},
|
|
|
|
- {tag: testCaseTypes[4], total: 7, errors: 0},
|
|
|
|
- {tag: testCaseTypes[5], total: 4, errors: 0}];
|
|
|
|
-
|
|
|
|
-let lastErrorsPerType = []; // Fila com os últimos 50 erros
|
|
|
|
-
|
|
|
|
-for (let i = 0; i<50; i++){
|
|
|
|
- lastErrorsPerType.push(exerciseTheme[getRandomInt(0, exerciseTheme.length)])
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-let lastErrorsPerTag = []; // Fila com os últimos 50 erros
|
|
|
|
-
|
|
|
|
-for (let i = 0; i<50; i++){
|
|
|
|
- lastErrorsPerTag.push(testCaseTypes[getRandomInt(0,testCaseTypes.length)])
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-// Variáveis internas
|
|
|
|
-let incorrect = false;
|
|
|
|
-let sugestions = [];
|
|
|
|
-let performance = [];
|
|
|
|
-
|
|
|
|
-let wrongTags = [];
|
|
|
|
-let wrongTagsAux = [];
|
|
|
|
-
|
|
|
|
-let lastErrorsPerTypeGraph = {};
|
|
|
|
-let lastErrorsPerTagGraph = {};
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-// Funções auxiliares
|
|
|
|
-// Função que retorna um valor inteiro aleatório a partir de um intervalo definido
|
|
|
|
-function getRandomInt(min, max) {
|
|
|
|
- min = Math.ceil(min);
|
|
|
|
- max = Math.floor(max);
|
|
|
|
- return Math.floor(Math.random() * (max - min)) + min;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// Função que encontra um objeto dentro de um array a partir do valor de uma de suas chaves
|
|
|
|
-function findObject(array,key,value) {
|
|
|
|
- for(let i = 0; i < array.length; i++) {
|
|
|
|
- if(array[i][key] === value) {
|
|
|
|
- return i
|
|
|
|
|
|
+export class Assistant {
|
|
|
|
+
|
|
|
|
+ constructor () {
|
|
|
|
+ this.incorrect = false;
|
|
|
|
+ this.allWrong = true;
|
|
|
|
+ this.wrongTags = [];
|
|
|
|
+ this.wrongTagsAux = [];
|
|
|
|
+ this.lastErrorsPerTypeGraph = [];
|
|
|
|
+ this.lastErrorsPerTagGraph = [];
|
|
|
|
+ this.suggestions = [{subject: "Leitura e Escrita", suggestion: `A Leitura e a Escrita são partes fundamentais na criação de um código, pois permitem a interação do usuário com o código e muitas vezes são fundamentais para a aquisição de entradas e para o fornecimento de saídas em um programa.<br><br>
|
|
|
|
+ <img src='http://127.0.0.1:81/moodle/mod/iassign/ilm/iVProg/1.0.20200221/ivprog/img/leitura.png' alt='leitura.png' style='float:right;max-width:100%;'>
|
|
|
|
+ <img src='http://127.0.0.1:81/moodle/mod/iassign/ilm/iVProg/1.0.20200221/ivprog/img/escrita.png' alt='escrita.png' vspace='30' style='float:right;max-width:100%;'>
|
|
|
|
+ Erros em exercícios de Leitura e Escrita geralmente estão associados a erros de digitação e a atribuições erradas de tipo de variável.<br><br>
|
|
|
|
+ <a href='https://edisciplinas.usp.br/mod/assign/view.php?id=LeituraeEscrita'>https://edisciplinas.usp.br/mod/assign/view.php?id=LeituraeEscrita</a><br><br>`},
|
|
|
|
+ {subject: "Manipulação de Entrada", suggestion: `A Manipulação de Entrada ocorre quando a entrada completa ou fragmentos da entrada devem ser alterados, trocados, substituídos pelo programa.<br><br>
|
|
|
|
+ Erros em exercícios de Manipulação de Entrada geralmente estão relacionados a atribuições erradas de variáveis.<br><br>
|
|
|
|
+ <a href='https://edisciplinas.usp.br/mod/assign/view.php?id=ManipulacaodeEntrada'>https://edisciplinas.usp.br/mod/assign/view.php?id=ManipulacaodeEntrada</a><br><br>`},
|
|
|
|
+ {subject: "Lógica", suggestion: `A Lógica é parte fundamental na elaboração de um programa, já que códigos são compostos de construções e operações lógicas. O desenvolvimento de raciocínio lógico é parte crucial na jornada de aprendizagem de programação.<br><br>
|
|
|
|
+ Erros em exercícios de Lógica geralmente estão relacionados a um entendimento errôneo do enunciado do exercício e a uma falta de consideração de todos os cenários possíveis para o exercício.<br><br>
|
|
|
|
+ <a href='https://edisciplinas.usp.br/mod/assign/view.php?id=Logica'>https://edisciplinas.usp.br/mod/assign/view.php?id=Logica</a><br><br>`},
|
|
|
|
+ {subject: "Matemática", suggestion: `Problemas de Matemática são muito utilizados no ensino de programação, seu formato lógico permite a aplicação quase que direta de problemas matemáticos vistos no Ensino Fundamental e Médio, sendo uma boa porta de entrada para transpor problemas para o ambiente virtual para que possam ser resolvidos através de programação.<br><br>
|
|
|
|
+ Erros em exercício de Matemática geralmente estão relacionados a erros em operações matemáticas e a falta de conhecimento sobre um conceito matemático.<br><br>
|
|
|
|
+ <a href='https://edisciplinas.usp.br/mod/assign/view.php?id=Matematica'>https://edisciplinas.usp.br/mod/assign/view.php?id=Matematica</a><br><br>`},
|
|
|
|
+ {subject: "Condição", suggestion: `O uso de Condições é muito importante na programação, pois permite que se construa programas com comportamentos diferentes para situações diferentes, permitindo uma grande aplicabilidade aos códigos.<br>
|
|
|
|
+ <img src='http://127.0.0.1:81/moodle/mod/iassign/ilm/iVProg/1.0.20200221/ivprog/img/condicao.png' alt='condicao.png' vspace='30' style='float:right;max-width:100%;'>
|
|
|
|
+ Erros em exercícios de Condição estão geralmente relacionados ao limite da condição, ou seja, nos valores adjacentes aos valores que satisfazem a condição.<br><br>
|
|
|
|
+ <a href='https://edisciplinas.usp.br/mod/assign/view.php?id=Condicao'>https://edisciplinas.usp.br/mod/assign/view.php?id=Condicao</a><br><br>`},
|
|
|
|
+ {subject: "Laço", suggestion: `O conceito de Laço tem muita importância para a programação, pois permite a repetição de uma tarefa até que uma condição de parada seja satisfeita, eliminando a necessidade de ter que ficar escrevendo diversas vezes o código da tarefa.<br>
|
|
|
|
+ <img src='http://127.0.0.1:81/moodle/mod/iassign/ilm/iVProg/1.0.20200221/ivprog/img/laco1.png' alt='laco1.png' vspace='30' style='float:right;max-width:100%;'>
|
|
|
|
+ <img src='http://127.0.0.1:81/moodle/mod/iassign/ilm/iVProg/1.0.20200221/ivprog/img/laco2.png' alt='laco2.png' style='float:right;max-width:100%;'>
|
|
|
|
+ <img src='http://127.0.0.1:81/moodle/mod/iassign/ilm/iVProg/1.0.20200221/ivprog/img/laco3.png' alt='laco3.png' vspace='30' style='float:right;max-width:100%;'>
|
|
|
|
+ Erros em exercícios de Laços geralmente estão relacionados à condição de parada, à atribuição da variável da condição de parada antes do laço e à manipulação da variável da condição de parada depois do laço.<br><br>
|
|
|
|
+ <a href='https://edisciplinas.usp.br/mod/assign/view.php?id=Lacos'>https://edisciplinas.usp.br/mod/assign/view.php?id=Lacos</a><br><br>`},
|
|
|
|
+ {subject: "Vetor", suggestion: `O uso de Vetores acrescenta diversas possibilidades a um programa, permite que conjuntos de dados sejam armazenados e manipulados de forma mais eficiente, o que facilita o uso de conjuntos de dados em programas.<br>
|
|
|
|
+ <img src='http://127.0.0.1:81/moodle/mod/iassign/ilm/iVProg/1.0.20200221/ivprog/img/vetor.png' alt='vetor.png' vspace='30' style='float:right;max-width:100%;'>
|
|
|
|
+ Erros em exercícios com Vetores geralmente estão relacionados a erros no uso do índice dos vetores, o que resulta no uso de dados errados, por isso sempre é importante checar se os índices estão sendo usados da forma correta.<br><br>
|
|
|
|
+ <a href='https://edisciplinas.usp.br/mod/assign/view.php?id=Vetor'>https://edisciplinas.usp.br/mod/assign/view.php?id=Vetor</a><br><br>`},
|
|
|
|
+ {subject: "Caso Geral", suggestion: `Quando um programa é utilizado, geralmente a maioria de suas execuções ocorrerá em um Caso Geral, em função disso a maioria dos testes são iniciados testando Casos Gerais, a fim de verificar o funcionamento da região do programa que concrentrará a maioria dos casos.<br><br>
|
|
|
|
+ Os Casos Gerais ocorrem nos valores que não apresentam um comportamento especial, ou seja, os casos comuns, que não se encaixam nos outros Tipos de Caso Teste.<br><br>
|
|
|
|
+ <a href='https://edisciplinas.usp.br/mod/assign/view.php?id=CasoGeral'>https://edisciplinas.usp.br/mod/assign/view.php?id=CasoGeral</a><br><br>`},
|
|
|
|
+ {subject: "Caso Limite", suggestion: `Levantar quais são os Casos Limites do problema a ser resolvido é fundamental para se avaliar o funcionamento adequado do programa desenvolvido, pois ao se testá-los podem ser encontrados erros que não são observados nos Casos Gerais.<br><br>
|
|
|
|
+ Os Casos Limites ocorrem nos valores que se encontram no limite da mudança de comportamento do programa. Por exemplo, em um programa que retorna se um número inteiro é maior que 5, os Casos Limites seriam os valores 5 e 6.<br><br>
|
|
|
|
+ <a href='https://edisciplinas.usp.br/mod/assign/view.php?id=CasoLimite'>https://edisciplinas.usp.br/mod/assign/view.php?id=CasoLimite</a><br><br>`},
|
|
|
|
+ {subject: "Caso Nulo", suggestion: `É sempre importante testar o funcionamento adequado do programa desenvolvido em casos de entrada nula (Caso Nulo), pois o zero pode ter um impacto muito grande em diferentes cálculos, sempre deve se tomar cuidado com possíveis multiplicações e divisões por zero.<br><br>
|
|
|
|
+ O Caso Nulo ocorre quando a entrada do programa é nula. Por exemplo, em um programa que trabalha com números, um Caso Nulo ocorre quando uma das entradas é zero, já em um programa que trabalha com texto, um Caso Nulo ocorre quando a entrada é um texto vazio.<br><br>
|
|
|
|
+ <a href='https://edisciplinas.usp.br/mod/assign/view.php?id=CasoNulo'>https://edisciplinas.usp.br/mod/assign/view.php?id=CasoNulo</a><br><br>`},
|
|
|
|
+ {subject: "Caso Negativo", suggestion: `É sempre importante testar o funcionamento adequado do programa desenvolvido em casos de entradas negativas (Caso Negativo), já que números negativos podem inverter comportamentos esperados e bagunçar cálculos que não esperavam por números negativos, sempre deve se checar se os cálculos realizados estão preparados para lidar com números negativos.<br><br>
|
|
|
|
+ O Caso Negativo ocorre quando a entrada do programa é negativa. Por exemplo, em um programa que multiplica dois números, um exemplo de Caso Negativo seriam os valores 5 e -6.<br><br>
|
|
|
|
+ <a href='https://edisciplinas.usp.br/mod/assign/view.php?id=CasoNegativo'>https://edisciplinas.usp.br/mod/assign/view.php?id=CasoNegativo</a><br><br>`},
|
|
|
|
+ {subject: "Igualdade", suggestion: `Entradas iguais podem causar resultados inesperados, por isso é importante se testar Igualdade, tanto em casos numéricos quanto em casos textuais<br><br>
|
|
|
|
+ A Igualdade ocorre quando o programa apresenta entradas idênticas, por exemplo, em um progama que recebe uma lista de números e tem que retornar os números primos presentes nessa lista sem repetir números.<br><br>
|
|
|
|
+ <a href='https://edisciplinas.usp.br/mod/assign/view.php?id=Igualdade'>https://edisciplinas.usp.br/mod/assign/view.php?id=Igualdade</a><br><br>`},
|
|
|
|
+ {subject: "Tipo de Entrada", suggestion: `Ao se elaborar um programa, é fundamental garantir que os Tipos de Entrada estão que estão sendo recebidos estão corretos, pois uma entrada de um tipo inesperado pode afetar gravemente o funcionamento de um programa.<br><br>
|
|
|
|
+ O Tipo de Entrada é testado quando se fornece um tipo de entrada diferente do esperado. Um exemplo de um teste de Tipo de Entrada é fornecer um número real em um programa que recebe números inteiros.<br><br>
|
|
|
|
+ <a href='https://edisciplinas.usp.br/mod/assign/view.php?id=TipodeEntrada'>https://edisciplinas.usp.br/mod/assign/view.php?id=TipodeEntrada</a><br><br>`}];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Função que encontra um objeto dentro de um array a partir do valor de uma de suas chaves
|
|
|
|
+ findObject(array,key,value) {
|
|
|
|
+ for(let i = 0; i < array.length; i++) {
|
|
|
|
+ if(array[i][key] === value) {
|
|
|
|
+ return i
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-}
|
|
|
|
-
|
|
|
|
|
|
|
|
-
|
|
|
|
-// Funções do agente
|
|
|
|
-// Função que analisa o exercício em relação às tags
|
|
|
|
-function updateTags(testCases,tags,lastErrorsPerTag) {
|
|
|
|
- for (var i = 0; i < testCases.length; i++) {
|
|
|
|
- for (var j = 0; j < tags.length; j++) {
|
|
|
|
- if (testCases[i].tag === tags[j].tag) {
|
|
|
|
- tags[j].total += 1;
|
|
|
|
- if (testCases[i].incorrect) {
|
|
|
|
- incorrect = true;
|
|
|
|
- tags[j].errors += 1;
|
|
|
|
- lastErrorsPerTag.push(testCases[i].tag);
|
|
|
|
- if (lastErrorsPerTag.length > 50) {
|
|
|
|
- lastErrorsPerTag.shift();
|
|
|
|
|
|
+ // Funções do agente
|
|
|
|
+ // Função que analisa o exercício em relação às tags
|
|
|
|
+ updateTags(testCases,performance) {
|
|
|
|
+ for (let i = 0; i < testCases.length; i++) {
|
|
|
|
+ for (let j = 0; j < performance.tag.length; j++) {
|
|
|
|
+ if (testCases[i].tags.toString() === performance.tag[j].tag) {
|
|
|
|
+ performance.tag[j].total += 1;
|
|
|
|
+ if (!testCases[i].grade) {
|
|
|
|
+ this.incorrect = true;
|
|
|
|
+ performance.tag[j].errors += 1;
|
|
|
|
+ performance.lastTagErrors.push(testCases[i].tags.toString());
|
|
|
|
+ if (performance.lastTagErrors.length > 50) {
|
|
|
|
+ performance.lastTagErrors.shift();
|
|
|
|
+ }
|
|
|
|
+ this.wrongTagsAux.push(testCases[i].tags.toString());
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ this.allWrong = false;
|
|
}
|
|
}
|
|
- wrongTagsAux.push(testCases[i].tag);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ this.wrongTags = this.wrongTagsAux.filter((element, i) => this.wrongTagsAux.indexOf(element) === i);
|
|
}
|
|
}
|
|
- wrongTags = wrongTagsAux.filter((element, i) => wrongTagsAux.indexOf(element) === i)
|
|
|
|
- //wrongTags = [...new Set(wrongTagsAux)]; // CUIDADO com o set
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// Função que analisa o exercício em relação aos types
|
|
|
|
-function updateTypes(exerciseType,types,lastErrorsPerType) {
|
|
|
|
- for (var i = 0; i < exerciseType.length; i++) {
|
|
|
|
- for (var j = 0; j < types.length; j++) {
|
|
|
|
- if (exerciseType[i] === types[j].type) {
|
|
|
|
- types[j].total += 1;
|
|
|
|
- if (incorrect) {
|
|
|
|
- types[j].errors += 1;
|
|
|
|
- lastErrorsPerType.push(exerciseType[i]);
|
|
|
|
- if (lastErrorsPerType.length > 50) {
|
|
|
|
- lastErrorsPerType.shift();
|
|
|
|
|
|
+
|
|
|
|
+ // Função que analisa o exercício em relação aos types
|
|
|
|
+ updateTypes(exerciseType,performance) {
|
|
|
|
+ for (let i = 0; i < exerciseType.length; i++) {
|
|
|
|
+ for (let j = 0; j < performance.type.length; j++) {
|
|
|
|
+ if (exerciseType[i] === performance.type[j].type) {
|
|
|
|
+ performance.type[j].total += 1;
|
|
|
|
+ if (this.incorrect) {
|
|
|
|
+ performance.type[j].errors += 1;
|
|
|
|
+ performance.lastTypeErrors.push(exerciseType[i]);
|
|
|
|
+ if (performance.lastTypeErrors.length > 50) {
|
|
|
|
+ performance.lastTypeErrors.shift();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-}
|
|
|
|
|
|
+
|
|
|
|
+ // Função que contabiliza as ocorrências dentro das fila de últimos erros
|
|
|
|
+ lastErrors(performance) {
|
|
|
|
+ performance.lastTypeErrors.forEach((x) => this.lastErrorsPerTypeGraph[x] = (this.lastErrorsPerTypeGraph[x] || 0)+1);
|
|
|
|
+ performance.lastTagErrors.forEach((x) => this.lastErrorsPerTagGraph[x] = (this.lastErrorsPerTagGraph[x] || 0)+1);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Função que adiciona o desempenho à saída
|
|
|
|
+ addPerformance(exerciseType,wrongTags,performance) {
|
|
|
|
+ let performanceText = "";//"Desempenho\n\n";
|
|
|
|
+ performanceText += `Neste exercício relacionado a ${exerciseType[0]}`;
|
|
|
|
+ for (let i = 1; i < exerciseType.length; i++) {
|
|
|
|
+ if (i+1 === exerciseType.length) {
|
|
|
|
+ performanceText += ` e ${exerciseType[i]}`;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ performanceText += `, ${exerciseType[i]}`;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ performanceText += ` você `;
|
|
|
|
+ if(this.allWrong) {
|
|
|
|
+ performanceText += `errou todos os testes`;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ if (this.incorrect) {
|
|
|
|
+ performanceText += `errou os teste que envolvem ${wrongTags[0]}`;
|
|
|
|
+ for (let i = 1; i < wrongTags.length; i++) {
|
|
|
|
+ if (i+1 === wrongTags.length) {
|
|
|
|
+ performanceText += ` e ${wrongTags[i]}`;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ performanceText += `, ${wrongTags[i]}`;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else{
|
|
|
|
+ performanceText += `acertou todos os teste`;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ performanceText += `.<br><br><br>`;
|
|
|
|
+ for (let i = 0; i < exerciseType.length; i++) {
|
|
|
|
+ let obj = this.findObject(performance.type,"type",exerciseType[i]);
|
|
|
|
+ performanceText += `Seu desempenho em exercícios com ${exerciseType[i]} é de ${(100*(1-performance.type[obj].errors/performance.type[obj].total)).toFixed(2)}% de sucesso.<br><br>`;
|
|
|
|
+ }
|
|
|
|
+ if (this.incorrect & !this.allWrong) {
|
|
|
|
+ for (let i = 0; i < wrongTags.length; i++) {
|
|
|
|
+ let obj = this.findObject(performance.tag,"tag",wrongTags[i]);
|
|
|
|
+ performanceText += `Seu desempenho em testes de ${wrongTags[i]} é de ${(100*(1-performance.tag[obj].errors/performance.tag[obj].total)).toFixed(2)}% de sucesso.<br><br>`;
|
|
|
|
+ performanceText += `Dos seus últimos ${performance.lastTagErrors.length} erros ${(100*(this.lastErrorsPerTagGraph[wrongTags[i]]/performance.lastTagErrors.length)).toFixed(2)}% foram em testes de ${wrongTags[i]}.<br><br>`;
|
|
|
|
+ }
|
|
|
|
+ performanceText += `<table align='center' cellpadding='4' bgcolor='transparent' style='width: 40%;'><tr><td align='center' colspan='2' style='height: 50px;'><b>Últimos ${performance.lastTagErrors.length} Erros</b></td></tr>`;
|
|
|
|
+ performanceText += `<tr style='height: 250px;'><td colspan='2' class='piechart'>
|
|
|
|
+ <style>
|
|
|
|
+ .piechart {
|
|
|
|
+ display: block;
|
|
|
|
+ position: absolute;
|
|
|
|
+ width: 17%;
|
|
|
|
+ height:0;
|
|
|
|
+ padding-bottom: 17%;
|
|
|
|
+ border-radius: 50%;
|
|
|
|
+ background-image: conic-gradient(`;
|
|
|
|
+ let dg = 0;
|
|
|
|
+ if (this.lastErrorsPerTagGraph[performance.tag[0].tag]) {
|
|
|
|
+ performanceText += `pink ${360*this.lastErrorsPerTagGraph[performance.tag[0].tag]/performance.lastTagErrors.length}deg,`;
|
|
|
|
+ dg += 360*this.lastErrorsPerTagGraph[performance.tag[0].tag]/performance.lastTagErrors.length;
|
|
|
|
+ }
|
|
|
|
+ if (this.lastErrorsPerTagGraph[performance.tag[1].tag]) {
|
|
|
|
+ performanceText += `red 0 ${dg+360*this.lastErrorsPerTagGraph[performance.tag[1].tag]/performance.lastTagErrors.length}deg,`;
|
|
|
|
+ dg += 360*this.lastErrorsPerTagGraph[performance.tag[1].tag]/performance.lastTagErrors.length;
|
|
|
|
+ }
|
|
|
|
+ if (this.lastErrorsPerTagGraph[performance.tag[2].tag]) {
|
|
|
|
+ performanceText += `blue 0 ${dg+360*this.lastErrorsPerTagGraph[performance.tag[2].tag]/performance.lastTagErrors.length}deg,`;
|
|
|
|
+ dg += 360*this.lastErrorsPerTagGraph[performance.tag[2].tag]/performance.lastTagErrors.length;
|
|
|
|
+ }
|
|
|
|
+ if (this.lastErrorsPerTagGraph[performance.tag[3].tag]) {
|
|
|
|
+ performanceText += `yellow 0 ${dg+360*this.lastErrorsPerTagGraph[performance.tag[3].tag]/performance.lastTagErrors.length}deg,`;
|
|
|
|
+ dg += 360*this.lastErrorsPerTagGraph[performance.tag[3].tag]/performance.lastTagErrors.length;
|
|
|
|
+ }
|
|
|
|
+ if (this.lastErrorsPerTagGraph[performance.tag[4].tag]) {
|
|
|
|
+ performanceText += `green 0 ${dg+360*this.lastErrorsPerTagGraph[performance.tag[4].tag]/performance.lastTagErrors.length}deg,`;
|
|
|
|
+ }
|
|
|
|
|
|
-// Função que contabiliza as ocorrências dentro das fila de últimos erros
|
|
|
|
-function lastErrors() {
|
|
|
|
- lastErrorsPerType.forEach((x) => lastErrorsPerTypeGraph[x] = (lastErrorsPerTypeGraph[x] || 0)+1);
|
|
|
|
- lastErrorsPerTag.forEach((x) => lastErrorsPerTagGraph[x] = (lastErrorsPerTagGraph[x] || 0)+1);
|
|
|
|
-}
|
|
|
|
|
|
+ performanceText += `white 0);
|
|
|
|
+ }
|
|
|
|
+ body,
|
|
|
|
+ .piechart {
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ align-items: center;
|
|
|
|
+ }
|
|
|
|
+ </style></td></tr>`;
|
|
|
|
+
|
|
|
|
+ if (this.lastErrorsPerTagGraph[performance.tag[0].tag]) {
|
|
|
|
+ performanceText += `<tr style='background-color:pink;'><td>${performance.tag[0].tag}</td><td style='text-align: center;'>${(100*(this.lastErrorsPerTagGraph[performance.tag[0].tag]/performance.lastTagErrors.length)).toFixed(2)}%</td></tr>`;
|
|
|
|
+ }
|
|
|
|
+ if (this.lastErrorsPerTagGraph[performance.tag[1].tag]) {
|
|
|
|
+ performanceText += `<tr style='background-color:red;'><td style='color: white;'>${performance.tag[1].tag}</td><td style='text-align: center; color: white;'>${(100*(this.lastErrorsPerTagGraph[performance.tag[1].tag]/performance.lastTagErrors.length)).toFixed(2)}%</td></tr>`;
|
|
|
|
+ }
|
|
|
|
+ if (this.lastErrorsPerTagGraph[performance.tag[2].tag]) {
|
|
|
|
+ performanceText += `<tr style='background-color:blue;'><td style='color: white;'>${performance.tag[2].tag}</td><td style='text-align: center; color: white;'>${(100*(this.lastErrorsPerTagGraph[performance.tag[2].tag]/performance.lastTagErrors.length)).toFixed(2)}%</td></tr>`;
|
|
|
|
+ }
|
|
|
|
+ if (this.lastErrorsPerTagGraph[performance.tag[3].tag]) {
|
|
|
|
+ performanceText += `<tr style='background-color:yellow;'><td>${performance.tag[3].tag}</td><td style='text-align: center;'>${(100*(this.lastErrorsPerTagGraph[performance.tag[3].tag]/performance.lastTagErrors.length)).toFixed(2)}%</td></tr>`;
|
|
|
|
+ }
|
|
|
|
+ if (this.lastErrorsPerTagGraph[performance.tag[4].tag]) {
|
|
|
|
+ performanceText += `<tr style='background-color:green;'><td style='color: white;'>${performance.tag[4].tag}</td><td style='text-align: center; color: white;'>${(100*(this.lastErrorsPerTagGraph[performance.tag[4].tag]/performance.lastTagErrors.length)).toFixed(2)}%</td></tr>`;
|
|
|
|
+ }
|
|
|
|
+ if (this.lastErrorsPerTagGraph[performance.tag[5].tag]) {
|
|
|
|
+ performanceText += `<tr style='background-color:white;'><td>${performance.tag[5].tag}</td><td style='text-align: center;'>${(100*(this.lastErrorsPerTagGraph[performance.tag[5].tag]/performance.lastTagErrors.length)).toFixed(2)}%</td></tr>`;
|
|
|
|
+ }
|
|
|
|
+ performanceText += `</table>`;
|
|
|
|
+/*
|
|
|
|
+
|
|
|
|
+ for (let i = 0; i < performance.tag.length; i++) {
|
|
|
|
+ if (this.lastErrorsPerTagGraph[performance.tag[i].tag]) {
|
|
|
|
+ if (wrongTags.includes(performance.tag[i].tag)) {
|
|
|
|
+ performanceText += `<tr style='background-color:orange;'><td><b>${performance.tag[i].tag}</b></td><td style='text-align: center;'><b>${(100*(this.lastErrorsPerTagGraph[performance.tag[i].tag]/performance.lastTagErrors.length)).toFixed(2)}%</b></td></tr>`;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ performanceText += `<tr style='background-color:white;'><td>${performance.tag[i].tag}</td><td style='text-align: center;'>${(100*(this.lastErrorsPerTagGraph[performance.tag[i].tag]/performance.lastTagErrors.length)).toFixed(2)}%</td></tr>`;
|
|
|
|
+ }
|
|
|
|
|
|
-// Função que adiciona o desempenho à saída
|
|
|
|
-function addPerformance(exerciseType,wrongTags) {
|
|
|
|
- let performanceText = "Desempenho\n\n";
|
|
|
|
- performanceText += `Neste exercício relacionado a ${exerciseType} você `;
|
|
|
|
- if (incorrect) {
|
|
|
|
- performanceText += `errou os teste que envolvem ${wrongTags}.\n\n`;
|
|
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ performanceText += `</table>`;
|
|
|
|
+ performanceText += `<p class='piechart'>
|
|
|
|
+ <style>
|
|
|
|
+ .piechart {
|
|
|
|
+ display: block;
|
|
|
|
+ position: absolute;
|
|
|
|
+ width: 15%;
|
|
|
|
+ height:0;
|
|
|
|
+ padding-bottom: 15%;
|
|
|
|
+ border-radius: 50%;
|
|
|
|
+ background-image: conic-gradient(`;
|
|
|
|
+ let dg = 0;
|
|
|
|
+ if (this.lastErrorsPerTagGraph[performance.tag[0].tag]) {
|
|
|
|
+ performanceText += `pink ${360*this.lastErrorsPerTagGraph[performance.tag[0].tag]/performance.lastTagErrors.length}deg,`;
|
|
|
|
+ dg += 360*this.lastErrorsPerTagGraph[performance.tag[0].tag]/performance.lastTagErrors.length;
|
|
|
|
+ }
|
|
|
|
+ if (this.lastErrorsPerTagGraph[performance.tag[1].tag]) {
|
|
|
|
+ performanceText += `red 0 ${dg+360*this.lastErrorsPerTagGraph[performance.tag[1].tag]/performance.lastTagErrors.length}deg,`;
|
|
|
|
+ dg += 360*this.lastErrorsPerTagGraph[performance.tag[1].tag]/performance.lastTagErrors.length;
|
|
|
|
+ }
|
|
|
|
+ if (this.lastErrorsPerTagGraph[performance.tag[2].tag]) {
|
|
|
|
+ performanceText += `blue 0 ${dg+360*this.lastErrorsPerTagGraph[performance.tag[2].tag]/performance.lastTagErrors.length}deg,`;
|
|
|
|
+ dg += 360*this.lastErrorsPerTagGraph[performance.tag[2].tag]/performance.lastTagErrors.length;
|
|
|
|
+ }
|
|
|
|
+ if (this.lastErrorsPerTagGraph[performance.tag[3].tag]) {
|
|
|
|
+ performanceText += `yellow 0 ${dg+360*this.lastErrorsPerTagGraph[performance.tag[3].tag]/performance.lastTagErrors.length}deg,`;
|
|
|
|
+ dg += 360*this.lastErrorsPerTagGraph[performance.tag[3].tag]/performance.lastTagErrors.length;
|
|
|
|
+ }
|
|
|
|
+ if (this.lastErrorsPerTagGraph[performance.tag[4].tag]) {
|
|
|
|
+ performanceText += `green 0 ${dg+360*this.lastErrorsPerTagGraph[performance.tag[4].tag]/performance.lastTagErrors.length}deg,`;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ performanceText += `white 0);
|
|
|
|
+ }
|
|
|
|
+ body,
|
|
|
|
+ .piechart {
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ align-items: center;
|
|
|
|
+ }
|
|
|
|
+ </style>
|
|
|
|
+ </p>`;*/
|
|
|
|
+ }
|
|
|
|
+ return performanceText;
|
|
}
|
|
}
|
|
- else {
|
|
|
|
- performanceText += `acertou todos os teste.\n\n`;
|
|
|
|
|
|
+
|
|
|
|
+ // Função que adiciona a sugestão à saída
|
|
|
|
+ addSuggestion(exerciseType,wrongTags) {
|
|
|
|
+ let suggestionText = "";//"Sugestões\n\n";
|
|
|
|
+ if (this.incorrect) {
|
|
|
|
+ if (!this.allWrong) {
|
|
|
|
+ for (let i = 0; i < wrongTags.length; i++) {
|
|
|
|
+ let obj = this.findObject(this.suggestions,"subject",wrongTags[i]);
|
|
|
|
+ suggestionText += this.suggestions[obj].suggestion;
|
|
|
|
+ }
|
|
|
|
+ for (let i = 0; i < exerciseType.length; i++) {
|
|
|
|
+ let obj = this.findObject(this.suggestions,"subject",exerciseType[i]);
|
|
|
|
+ suggestionText += this.suggestions[obj].suggestion;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ suggestionText += `Sempre é importante testar o programa desenvolvido antes de aplicá-lo em um ambiente real, lembre-se de testar o programa antes de submetê-lo à avaliação automática.<br><br>`;
|
|
|
|
+ for (let i = 0; i < exerciseType.length; i++) {
|
|
|
|
+ let obj = this.findObject(this.suggestions,"subject",exerciseType[i]);
|
|
|
|
+ suggestionText += this.suggestions[obj].suggestion;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ suggestionText += `Parabéns!!! Seu exercício não apresentou erros.<br><br>`;
|
|
|
|
+ }
|
|
|
|
+ return suggestionText;
|
|
}
|
|
}
|
|
- for (let i = 0; i < exerciseType.length; i++) {
|
|
|
|
- let obj = findObject(types,"type",exerciseType[i]);
|
|
|
|
- performanceText += `Seu desempenho em exercícios com ${exerciseType[i]} é de ${(100*(1-types[obj].errors/types[obj].total)).toFixed(2)}% de sucesso\n\n`;
|
|
|
|
|
|
+
|
|
|
|
+ async get(url) {
|
|
|
|
+ let response = await fetch(url);
|
|
|
|
+ let data = await response.json();
|
|
|
|
+ return data
|
|
}
|
|
}
|
|
- if (incorrect) {
|
|
|
|
- for (let i = 0; i < wrongTags.length; i++) {
|
|
|
|
- let obj = findObject(tags,"tag",wrongTags[i]);
|
|
|
|
- performanceText += `Seu desempenho em testes de ${wrongTags[i]} é de ${(100*(1-tags[obj].errors/tags[obj].total)).toFixed(2)}% de sucesso\n\n`;
|
|
|
|
- performanceText += `Dos seus últimos 50 erros ${(100*(lastErrorsPerTagGraph[wrongTags[i]]/lastErrorsPerTag.length)).toFixed(2)}% foram em testes de ${wrongTags[i]}\n\n`;
|
|
|
|
|
|
+
|
|
|
|
+ async post(url, data) {
|
|
|
|
+ let payload = new FormData();
|
|
|
|
+ payload.append("data",JSON.stringify(data));
|
|
|
|
+ let options = {
|
|
|
|
+ method : "POST",
|
|
|
|
+ body : payload
|
|
}
|
|
}
|
|
|
|
+ let response = await fetch(url, options);
|
|
|
|
+ await response.text();
|
|
}
|
|
}
|
|
- console.log(performanceText);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// Função que adiciona a sugestão à saída
|
|
|
|
-function addSugestion(wrongTypes,wrongTags) {
|
|
|
|
- let sugestionText = "Sugestões\n\n";
|
|
|
|
- if (incorrect) {
|
|
|
|
- sugestionText += `Levantar quais são os Casos Limites do problema a ser resolvido é fundamental para se avaliar o funcionamento adequado do programa desenvolvido, pois ao se testá-los podem ser encontrados erros que não são observados nos Casos Gerais.\n\n`;
|
|
|
|
- sugestionText += `[Explicação de Casos Limites]\n\n`;
|
|
|
|
- sugestionText += `[Exemplo de Casos Limites e Casos Gerais]\n\n`;
|
|
|
|
- sugestionText += `[Material ou link sobre Casos Limites]\n\n\n`;
|
|
|
|
- sugestionText += `O conceito de Laço é muito importante na programação, pois com ele ….\n\n`;
|
|
|
|
- sugestionText += `[Explicação sobre Laços]\n\n`;
|
|
|
|
- sugestionText += `[Exemplo do uso de Laços no iVProg]\n\n`;
|
|
|
|
- sugestionText += `[Material ou link sobre Laços]\n\n`;
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- sugestionText += `Parabéns!!! Seu exercício não apresentou erros.\n\n`;
|
|
|
|
|
|
+
|
|
|
|
+ async analise(url,exerciseType,testCases) {
|
|
|
|
+ let data = this.get(url);
|
|
|
|
+ return Promise.resolve(data).then((performance) => {
|
|
|
|
+ this.updateTags(testCases,performance);
|
|
|
|
+ this.updateTypes(exerciseType,performance);
|
|
|
|
+ this.lastErrors(performance);
|
|
|
|
+ let assistantData = {exerciseType: exerciseType, testCases: testCases, performance: performance};
|
|
|
|
+ this.post(url,assistantData);
|
|
|
|
+ let text = [];
|
|
|
|
+ text.push(this.addPerformance(exerciseType,this.wrongTags,performance));
|
|
|
|
+ text.push(this.addSuggestion(exerciseType,this.wrongTags));
|
|
|
|
+ return text;
|
|
|
|
+ });
|
|
}
|
|
}
|
|
- console.log(sugestionText);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-// Exibição dos valores recebidos
|
|
|
|
-console.log("\nAntes da Execução\n");
|
|
|
|
-console.table(exerciseType);
|
|
|
|
-console.table(testCases);
|
|
|
|
-console.table(types);
|
|
|
|
-console.table(tags);
|
|
|
|
-//console.table(lastErrorsPerType);
|
|
|
|
-//console.table(lastErrorsPerTag);
|
|
|
|
-console.log("*****************************************************************\n");
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-// Execução do agente
|
|
|
|
-updateTags(testCases,tags,lastErrorsPerTag);
|
|
|
|
-updateTypes(exerciseType,types,lastErrorsPerType);
|
|
|
|
-lastErrors();
|
|
|
|
-addPerformance(exerciseType,wrongTags);
|
|
|
|
-addSugestion(exerciseType,wrongTags);
|
|
|
|
-console.log("*****************************************************************\n");
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-// Reescrita do dados na base de dados associada ao aluno
|
|
|
|
-console.log("Após Execução\n");
|
|
|
|
-console.table(types);
|
|
|
|
-console.table(tags);
|
|
|
|
-console.table(lastErrorsPerTypeGraph);
|
|
|
|
-console.table(lastErrorsPerTagGraph);
|
|
|
|
-//console.table(lastErrorsPerType);
|
|
|
|
-//console.table(lastErrorsPerTag);
|
|
|
|
-console.log("\n");
|
|
|
|
-
|
|
|