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.
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.
https://edisciplinas.usp.br/mod/assign/view.php?id=LeituraeEscrita
`},
{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.
Erros em exercícios de Manipulação de Entrada geralmente estão relacionados a atribuições erradas de variáveis.
https://edisciplinas.usp.br/mod/assign/view.php?id=ManipulacaodeEntrada
`},
{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.
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.
https://edisciplinas.usp.br/mod/assign/view.php?id=Logica
`},
{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.
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.
https://edisciplinas.usp.br/mod/assign/view.php?id=Matematica
`},
{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.
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.
https://edisciplinas.usp.br/mod/assign/view.php?id=Condicao
`},
{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.
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.
https://edisciplinas.usp.br/mod/assign/view.php?id=Lacos
`},
{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.
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.
https://edisciplinas.usp.br/mod/assign/view.php?id=Vetor
`},
{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.
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.
https://edisciplinas.usp.br/mod/assign/view.php?id=CasoGeral
`},
{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.
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.
https://edisciplinas.usp.br/mod/assign/view.php?id=CasoLimite
`},
{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.
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.
https://edisciplinas.usp.br/mod/assign/view.php?id=CasoNulo
`},
{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.
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.
https://edisciplinas.usp.br/mod/assign/view.php?id=CasoNegativo
`},
{subject: "Igualdade", suggestion: `Entradas iguais podem causar resultados inesperados, por isso é importante se testar Igualdade, tanto em casos numéricos quanto em casos textuais
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.
https://edisciplinas.usp.br/mod/assign/view.php?id=Igualdade
`},
{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.
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.
https://edisciplinas.usp.br/mod/assign/view.php?id=TipodeEntrada
`}];
}
// 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
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;
}
}
}
}
this.wrongTags = this.wrongTagsAux.filter((element, i) => this.wrongTagsAux.indexOf(element) === i);
}
// 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 += `.
`;
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.
`;
}
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.
`;
performanceText += `Dos seus últimos ${performance.lastTagErrors.length} erros ${(100*(this.lastErrorsPerTagGraph[wrongTags[i]]/performance.lastTagErrors.length)).toFixed(2)}% foram em testes de ${wrongTags[i]}.
`;
}
performanceText += `
Últimos ${performance.lastTagErrors.length} Erros | |
${performance.tag[0].tag} | ${(100*(this.lastErrorsPerTagGraph[performance.tag[0].tag]/performance.lastTagErrors.length)).toFixed(2)}% |
${performance.tag[1].tag} | ${(100*(this.lastErrorsPerTagGraph[performance.tag[1].tag]/performance.lastTagErrors.length)).toFixed(2)}% |
${performance.tag[2].tag} | ${(100*(this.lastErrorsPerTagGraph[performance.tag[2].tag]/performance.lastTagErrors.length)).toFixed(2)}% |
${performance.tag[3].tag} | ${(100*(this.lastErrorsPerTagGraph[performance.tag[3].tag]/performance.lastTagErrors.length)).toFixed(2)}% |
${performance.tag[4].tag} | ${(100*(this.lastErrorsPerTagGraph[performance.tag[4].tag]/performance.lastTagErrors.length)).toFixed(2)}% |
${performance.tag[5].tag} | ${(100*(this.lastErrorsPerTagGraph[performance.tag[5].tag]/performance.lastTagErrors.length)).toFixed(2)}% |
`;*/ } return performanceText; } // 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.