import spacy #spacy model imported in the init of class Semantica2 #nlp = spacy.load('es_core_news_sm') #nlp = spacy.load('es_core_news_md') #nlp = spacy.load('es_core_news_lg') from codeScripts.Dependencies.SentenceTransformer2 import * from codeScripts.rubricsOut import SemanticOutput, OrtographicOutput, SintacticOutput from codeScripts.utils import spelling_corrector, mu_index, FHuertas_index, check_senteces_words, save_json,create_file_path #Done class Semantica2(): """ This class allows to compute the semantic level of the rubric """ #funciones para la extraccion/generacion de kw --- no integradas def __init__(self, settings): self.output = SemanticOutput(settings) self.spacy_model = spacy.load(settings.spacy_package) self.settings = settings def computeSimilarity(self,sentences1,sentences2,similarityMethod): """ This function applies a defined method to obtain the similarity between two sentences Inputs: -sentences1: First set of sentences to compare -sentences2: Second set of sentences to compare -similarityMethod: The inherited similarity method selected in getSimilarity Outputs: -similar: The similarity score """ if similarityMethod.lower() == "spacy": r1 = self.spacy_model(sentences1) r2 = self.spacy_model(sentences2) similar = round(r1.similarity(r2), 3) else: similar = self.settings.BertModels_glbl.similarity(self.settings.model_path, sentences1, sentences2)[0][0].item() return similar class Ortografia2 (): """ This class allows to compute the ortographic level of the rubric """ def __init__(self, settings): self.output = OrtographicOutput() self.settings = settings def Evaluation(self, respuesta_alumno): """ This method is used for calculating the ortographic mark. Inputs: respuesta_alumno: The student's answer. Outputs: nota_Orto: The generated mark. """ #some exceptions that should not be considered as mistakes exceptionsTxt = open('codeScripts/OrtographicExceptions.txt', encoding="utf-8") exceptions = exceptionsTxt.readline() exceptionsTxt.close() nota_Orto = 0 if respuesta_alumno == "": self.output.number_mistakes.append(0) self.settings.faltasOrto = 0 else: #obtaining the number of mistakes using hunspell errores, mistakes = spelling_corrector(respuesta_alumno, self.settings.hunspell_aff, self.settings.hunspell_dic) for mistake in mistakes: if mistake not in exceptions: if mistake not in self.output.mistakes: self.output.mistakes.append(mistake) else: errores-=1 #storing the mistakes for debugging purposes self.output.number_mistakes.append(errores) #counting the number of errors when surpassing a fixed number of them (config parameter) if errores <= self.settings.FaltasSalvaguarda: nota_Orto = self.settings.PesoOrtografia self.settings.faltasOrto = 0 else: self.settings.faltasOrto = errores #computing the mark applying rubric weights try: rel = self.settings.PesoOrtografia/self.settings.NMaxErrores nota_Orto = self.settings.PesoOrtografia - (errores - self.settings.FaltasSalvaguarda) * rel except: nota_Orto = 0 if nota_Orto < 0: nota_Orto = 0 return nota_Orto def SaveMistakes(self): """ This method is used for saving some information about the students' found mistakes """ save_json(create_file_path('RecopiledMistakes.json', doctype= 2),self.output.mistakes, False) save_json(create_file_path('NumberMistakes.json', doctype= 2),self.output.number_mistakes, False) class Sintaxis2(): """ This class allows to compute the syntactic level of the rubric """ def __init__(self, settings): self.output = SintacticOutput() self.settings = settings def Evaluation(self, respuesta_alumno): """ This method is used for calculating the syntactic mark. Inputs: respuesta_alumno: The student's answer. Outputs: nota_Sintaxis: The generated mark. """ if respuesta_alumno == '': self.output.leg_FH.append(0) self.output.leg_mu.append(0) self.settings.palabrasPorFrase = 0 return 0 else: #obtaining FH and mu indexes sentencesLenght, wordsLenght, syll, letter_per_word = check_senteces_words(respuesta_alumno) print("wordsLenght: " + str(wordsLenght)) FH, _ = FHuertas_index(sentencesLenght, wordsLenght, syll) mu, _ = mu_index(sentencesLenght, wordsLenght, letter_per_word) #storing the indexes self.output.leg_FH.append(FH) self.output.leg_mu.append(mu) #calculating the grade nota_Sintaxis = (self.settings.PesoSintaxis/2) * FH/80 + (self.settings.PesoSintaxis/2) * mu/60 if nota_Sintaxis > self.settings.PesoSintaxis: nota_Sintaxis = self.settings.PesoSintaxis print("sentencesLenght: " + str(sentencesLenght)) self.settings.palabrasPorFrase = round(wordsLenght/sentencesLenght,2) return nota_Sintaxis def saveResults(self): """ This method is used for saving some information about the students' readability """ self.output.saveLegibilityResults() def GenerateFeedback(settings, respuesta, OrtoMark, SintMark, SemanMarkSpacy, SemanMarkBert): """ This function is used to analyze grades and generate appropriate feedback based on sentences. Inputs: -settings: The settings of the experiment. -respuesta: The student's response. -OrtoMark: The calification of the ortographic level. -SintMark: The calification of the syntactic level. -SemanMarkSpacy: The calification of the semantic level - spacy. -SemanMarkBert: The calification of the semantic level - bert. Outputs: -feedback: The generated feedback. """ feedback = "" #if blank response if respuesta == "": feedback = feedback + "Respuesta en blanco" else: #pre-defined sentences in case: <5 - <10 - 10 if settings.Ortografia: feedback = feedback + "\nNivel ortográfico: \n" if OrtoMark < settings.PesoOrtografia/2: feedback = feedback + "El estudiante cometió " + str(settings.faltasOrto) + " faltas de ortografía y no alcanzó el aprobado en este nivel de la rúbrica. El sistema reconoce un fallo si se ha producido un error en acento de puntuación o en una palabra no recogida en un diccionario español. \n" elif OrtoMark < settings.PesoOrtografia: feedback = feedback + "El estudiante cometió " + str(settings.faltasOrto) + " faltas de ortografía. El sistema reconoce un fallo si se ha producido un error en acento de puntuación o en una palabra no recogida en un diccionario español. \n" else: feedback = feedback + "El estudiante redactó su respuesta sin aparentes fallos de ortografía. \n" if settings.Sintaxis: feedback = feedback + "\nNivel sintáctico: \n" if SintMark < settings.PesoSintaxis/2: feedback = feedback + "La respuesta del estudiante incluye elementos que dificultan su correcta legibilidad y no alcanzó el aprobado en este nivel de la rúbrica. Hay " + str(settings.palabrasPorFrase) + " palabras por frase. El sistema tiene en consideración para la legibilidad el promedio de sílabas por palabra y la media de palabras por frase. Además, el uso de guiones o puntos es desaconsejable. \n" elif SintMark < settings.PesoSintaxis: feedback = feedback + "La respuesta del estudiante incluye elementos que dificultan su correcta legibilidad. Hay " + str(settings.palabrasPorFrase) + " palabras por frase. El sistema tiene en consideración para la legibilidad el promedio de sílabas por palabra y la media de palabras por frase. Además, el uso de guiones o puntos es desaconsejable. \n" else: feedback = feedback + "La respuesta del estudiante fue redactada con aparente buena legibilidad \n" if settings.Semantica: feedback = feedback + "\nNivel semántico, primer modelo: \n" if SemanMarkSpacy < settings.PesoSemantics/2: feedback = feedback + "El estudiante no responde correctamente a todas las minipreguntas y no alcanzó el aprobado en este nivel de la rúbrica. Debería profundizar más en " + settings.minipreguntasMalSpacy + ". El sistema evalúa una respuesta en base a la similitud que existe entre ésta y la respuesta de referencia de cada minipregunta. \n" elif SemanMarkSpacy < settings.PesoSemantics: feedback = feedback + "El estudiante no responde correctamente a todas las minipreguntas. Para mejorar podría profundizar más en " + settings.minipreguntasMalSpacy + ". El sistema evalúa una respuesta en base a la similitud que existe entre ésta y la respuesta de referencia de cada minipregunta. \n" else: feedback = feedback + "El estudiante responde a cada minipregunta de forma similar a la respuesta de referencia. \n" feedback = feedback + "\nNivel semántico, segundo modelo: \n" if SemanMarkBert < settings.PesoSemantics/2: feedback = feedback + "El estudiante no responde correctamente a todas las minipreguntas y no alcanzó el aprobado en este nivel de la rúbrica. Debería profundizar más en " + settings.minipreguntasMalBert + ". El sistema evalúa una respuesta en base a la similitud que existe entre ésta y la respuesta de referencia de cada minipregunta.\n" elif SemanMarkBert < settings.PesoSemantics: feedback = feedback + "El estudiante no responde correctamente a todas las minipreguntas. Para mejorar podría profundizar más en " + settings.minipreguntasMalBert + ". El sistema evalúa una respuesta en base a la similitud que existe entre ésta y la respuesta de referencia de cada minipregunta. \n" else: feedback = feedback + "El estudiante responde a cada minipregunta de forma similar a la respuesta de referencia. \n" feedback = feedback + "\n\nPor favor, si observa alguna diferencia significativa entre la calificación de ambos modelos, entre a valorar la nota del estudiante. " return feedback