Spaces:
Sleeping
Sleeping
import gradio as gr | |
import javalang | |
from typing import Dict, List, Tuple | |
class JavaPOOEvaluator: | |
"""Java-Judge: OO Paradigm""" | |
def __init__(self): | |
self.rubric = { | |
"classes": 20, | |
"objetos": 20, | |
"metodos": 20, | |
"atributos": 20, | |
"encapsulamento": 10, | |
"heranca": 10, | |
"polimorfismo": 10, | |
"abstracao": 10, | |
} | |
def analyze_classes_and_objects(self, code: str) -> Tuple[float, List[str]]: | |
"""Avalia a definição e o uso de classes e objetos""" | |
score = 0 | |
feedback = [] | |
try: | |
tree = javalang.parse.parse(code) | |
classes = list(tree.filter(javalang.tree.ClassDeclaration)) | |
if classes: | |
score += 15 | |
feedback.append(f"✓ {len(classes)} classe(s) declarada(s) corretamente.") | |
else: | |
feedback.append("⚠ Nenhuma classe declarada encontrada.") | |
objects = [node for _, node in tree.filter(javalang.tree.VariableDeclarator) if 'new' in str(node.initializer)] | |
if objects: | |
score += 5 | |
feedback.append(f"✓ {len(objects)} objeto(s) criado(s) corretamente.") | |
else: | |
feedback.append("⚠ Nenhuma instância de objeto criada.") | |
except Exception as e: | |
feedback.append("⚠ Erro ao analisar classes e objetos.") | |
return score, feedback | |
def analyze_methods(self, code: str) -> Tuple[float, List[str]]: | |
"""Avalia a definição e organização de métodos""" | |
score = 0 | |
feedback = [] | |
try: | |
tree = javalang.parse.parse(code) | |
methods = list(tree.filter(javalang.tree.MethodDeclaration)) | |
if methods: | |
score += 15 | |
feedback.append(f"✓ {len(methods)} método(s) declarado(s) corretamente.") | |
else: | |
feedback.append("⚠ Nenhum método declarado encontrado.") | |
except Exception as e: | |
feedback.append(f"⚠ Erro ao analisar métodos: {e}") | |
return score, feedback | |
def analyze_encapsulation(self, code: str) -> Tuple[float, List[str]]: | |
"""Avalia encapsulamento e uso de modificadores""" | |
score = 0 | |
feedback = [] | |
try: | |
tree = javalang.parse.parse(code) | |
fields = list(tree.filter(javalang.tree.FieldDeclaration)) | |
private_count = sum(1 for _, node in fields if 'private' in node.modifiers) | |
if private_count: | |
score += 5 | |
feedback.append(f"✓ {private_count} atributo(s) encapsulado(s) com 'private'.") | |
getters_setters = [method for _, method in tree.filter(javalang.tree.MethodDeclaration) if method.name.startswith('get') or method.name.startswith('set')] | |
if getters_setters: | |
score += 5 | |
feedback.append(f"✓ {len(getters_setters)} getter(s) ou setter(s) implementado(s).") | |
else: | |
feedback.append("⚠ Nenhum getter ou setter encontrado.") | |
except Exception as e: | |
feedback.append("⚠ Erro ao analisar encapsulamento.") | |
return score, feedback | |
def analyze_inheritance(self, code: str) -> Tuple[float, List[str]]: | |
"""Avalia o uso de herança""" | |
score = 0 | |
feedback = [] | |
try: | |
tree = javalang.parse.parse(code) | |
subclasses = [node for _, node in tree.filter(javalang.tree.ClassDeclaration) if node.extends] | |
if subclasses: | |
score += 10 | |
feedback.append(f"✓ {len(subclasses)} classe(s) estendendo outra(s).") | |
else: | |
feedback.append("⚠ Nenhum uso de herança encontrado.") | |
except Exception as e: | |
feedback.append("⚠ Erro ao analisar herança.") | |
return score, feedback | |
def analyze_polymorphism(self, code: str) -> Tuple[float, List[str]]: | |
"""Avalia o uso de polimorfismo""" | |
score = 0 | |
feedback = [] | |
try: | |
tree = javalang.parse.parse(code) | |
overridden_methods = [node for _, node in tree.filter(javalang.tree.MethodDeclaration) if 'Override' in (node.annotations or [])] | |
if overridden_methods: | |
score += 10 | |
feedback.append(f"✓ {len(overridden_methods)} método(s) sobrescrito(s) corretamente.") | |
else: | |
feedback.append("⚠ Nenhum uso de polimorfismo encontrado.") | |
except Exception as e: | |
feedback.append("⚠ Erro ao analisar polimorfismo.") | |
return score, feedback | |
def analyze_abstraction(self, code: str) -> Tuple[float, List[str]]: | |
"""Avalia o uso de abstração""" | |
score = 0 | |
feedback = [] | |
try: | |
tree = javalang.parse.parse(code) | |
abstract_classes = [node for _, node in tree.filter(javalang.tree.ClassDeclaration) if 'abstract' in node.modifiers] | |
interfaces = list(tree.filter(javalang.tree.InterfaceDeclaration)) | |
if abstract_classes: | |
score += 5 | |
feedback.append(f"✓ {len(abstract_classes)} classe(s) abstrata(s) declarada(s).") | |
else: | |
feedback.append("⚠ Nenhuma classe abstrata encontrada.") | |
if interfaces: | |
score += 5 | |
feedback.append(f"✓ {len(interfaces)} interface(s) declarada(s).") | |
else: | |
feedback.append("⚠ Nenhuma interface encontrada.") | |
except Exception as e: | |
feedback.append("⚠ Erro ao analisar abstração.") | |
return score, feedback | |
def evaluate_code(self, code: str) -> Dict: | |
"""Avalia o código Java""" | |
cls_score, cls_feedback = self.analyze_classes_and_objects(code) | |
meth_score, meth_feedback = self.analyze_methods(code) | |
enc_score, enc_feedback = self.analyze_encapsulation(code) | |
inh_score, inh_feedback = self.analyze_inheritance(code) | |
poly_score, poly_feedback = self.analyze_polymorphism(code) | |
abs_score, abs_feedback = self.analyze_abstraction(code) | |
essential_score = cls_score + meth_score | |
bonus_score = enc_score + inh_score + poly_score + abs_score | |
total_score = essential_score + bonus_score | |
total_score = min(100, total_score) | |
proficiency = "Necessita Melhorias" | |
if total_score >= 90: | |
proficiency = "Excelente" | |
elif total_score >= 75: | |
proficiency = "Bom" | |
elif total_score >= 60: | |
proficiency = "Satisfatório" | |
return { | |
"total_score": total_score, | |
"essential_score": essential_score, | |
"bonus_score": bonus_score, | |
"proficiency": proficiency, | |
"feedback": { | |
"classes_objetos": cls_feedback, | |
"metodos": meth_feedback, | |
"encapsulamento": enc_feedback, | |
"heranca": inh_feedback, | |
"polimorfismo": poly_feedback, | |
"abstracao": abs_feedback, | |
} | |
} | |
# Interface Gradio | |
with gr.Blocks(title="Java-Judge: OO Paradigm", css="#rubric_image img {max-width: 50%; height: auto; margin: 0 auto;}") as demo: | |
gr.Markdown("# Avaliador de POO em Java") | |
gr.Markdown("### [Visualizar a Rubrica em PDF](rubric.pdf)") | |
gr.Markdown("#### Avalie seu código Java com base em critérios de POO") | |
upload = gr.File(label="Carregue arquivos Java para avaliação", file_types=[".java"], file_count="multiple") | |
evaluate_button = gr.Button("Avaliar Código") | |
output = gr.Textbox(label="Resultado da Avaliação", lines=25) | |
gr.Markdown("### Rubrica de Avaliação") | |
rubric_image = gr.Image("rubric_table.png", label="Tabela Resumida da Rubrica", elem_id="rubric_image") | |
def evaluate_code_files(files) -> str: | |
evaluator = JavaPOOEvaluator() | |
results = [] | |
for file in files: | |
with open(file.name, 'r', encoding='utf-8') as f: | |
code = f.read() | |
evaluation = evaluator.evaluate_code(code) | |
result = f"\nArquivo: {file.name}\n" | |
result += f"Pontuação Total: {evaluation['total_score']:.1f}/100\n" | |
result += f"Nível: {evaluation['proficiency']}\n\n" | |
result += "Feedback Detalhado:\n" | |
for category, comments in evaluation['feedback'].items(): | |
result += f"\n{category.replace('_', ' ').title()}:\n" | |
for comment in comments: | |
result += f" {comment}\n" | |
results.append(result) | |
return "\n".join(results) | |
evaluate_button.click(fn=evaluate_code_files, inputs=upload, outputs=output) | |
if __name__ == "__main__": | |
demo.launch(share=True) | |