rmayormartins commited on
Commit
73c572e
·
1 Parent(s): 5d44156
Files changed (3) hide show
  1. app.py +329 -174
  2. rubric.pdf +0 -0
  3. rubric_table.png +0 -0
app.py CHANGED
@@ -1,207 +1,349 @@
1
- import gradio as gr
2
  import javalang
3
  from typing import Dict, List, Tuple
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
- class JavaPOOEvaluator:
6
- """Java-Judge: OO Paradigm"""
7
  def __init__(self):
8
  self.rubric = {
9
- "classes": 20,
10
- "objetos": 20,
11
- "metodos": 20,
12
- "atributos": 20,
13
- "encapsulamento": 10,
14
- "heranca": 10,
15
- "polimorfismo": 10,
16
- "abstracao": 10,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  }
18
 
19
- def analyze_classes_and_objects(self, code: str) -> Tuple[float, List[str]]:
20
- """Avalia a definição e o uso de classes e objetos"""
21
  score = 0
 
22
  feedback = []
23
 
24
- try:
25
- tree = javalang.parse.parse(code)
26
- classes = list(tree.filter(javalang.tree.ClassDeclaration))
27
-
28
- if classes:
29
- score += 15
30
- feedback.append(f"✓ {len(classes)} classe(s) declarada(s) corretamente.")
31
- else:
32
- feedback.append("⚠ Nenhuma classe declarada encontrada.")
33
-
34
- objects = [node for _, node in tree.filter(javalang.tree.VariableDeclarator) if 'new' in str(node.initializer)]
35
- if objects:
36
- score += 5
37
- feedback.append(f"✓ {len(objects)} objeto(s) criado(s) corretamente.")
38
- else:
39
- feedback.append("⚠ Nenhuma instância de objeto criada.")
40
- except Exception as e:
41
- feedback.append(" Erro ao analisar classes e objetos.")
42
-
43
- return score, feedback
44
-
45
- def analyze_methods(self, code: str) -> Tuple[float, List[str]]:
46
- """Avalia a definição e organização de métodos"""
47
- score = 0
48
- feedback = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
  try:
51
  tree = javalang.parse.parse(code)
52
- methods = list(tree.filter(javalang.tree.MethodDeclaration))
53
-
54
- if methods:
55
- score += 15
56
- feedback.append(f"✓ {len(methods)} método(s) declarado(s) corretamente.")
57
- else:
58
- feedback.append("⚠ Nenhum método declarado encontrado.")
59
- except Exception as e:
60
- feedback.append(f"⚠ Erro ao analisar métodos: {e}")
61
 
62
- return score, feedback
 
 
 
63
 
64
- def analyze_encapsulation(self, code: str) -> Tuple[float, List[str]]:
65
- """Avalia encapsulamento e uso de modificadores"""
66
- score = 0
67
- feedback = []
68
 
69
- try:
70
- tree = javalang.parse.parse(code)
71
- fields = list(tree.filter(javalang.tree.FieldDeclaration))
 
 
72
 
73
- private_count = sum(1 for _, node in fields if 'private' in node.modifiers)
74
- if private_count:
75
- score += 5
76
- feedback.append(f"✓ {private_count} atributo(s) encapsulado(s) com 'private'.")
 
77
 
78
- getters_setters = [method for _, method in tree.filter(javalang.tree.MethodDeclaration) if method.name.startswith('get') or method.name.startswith('set')]
79
- if getters_setters:
80
- score += 5
81
- feedback.append(f"✓ {len(getters_setters)} getter(s) ou setter(s) implementado(s).")
82
- else:
83
- feedback.append("⚠ Nenhum getter ou setter encontrado.")
84
- except Exception as e:
85
- feedback.append("⚠ Erro ao analisar encapsulamento.")
86
 
87
- return score, feedback
 
 
 
88
 
89
- def analyze_inheritance(self, code: str) -> Tuple[float, List[str]]:
90
- """Avalia o uso de herança"""
91
- score = 0
92
- feedback = []
93
 
94
- try:
95
- tree = javalang.parse.parse(code)
96
- subclasses = [node for _, node in tree.filter(javalang.tree.ClassDeclaration) if node.extends]
97
-
98
- if subclasses:
99
- score += 10
100
- feedback.append(f"✓ {len(subclasses)} classe(s) estendendo outra(s).")
101
- else:
102
- feedback.append("⚠ Nenhum uso de herança encontrado.")
103
  except Exception as e:
104
- feedback.append("Erro ao analisar herança.")
105
 
106
- return score, feedback
107
 
108
- def analyze_polymorphism(self, code: str) -> Tuple[float, List[str]]:
109
- """Avalia o uso de polimorfismo"""
110
- score = 0
111
- feedback = []
112
-
113
- try:
114
- tree = javalang.parse.parse(code)
115
- overridden_methods = [node for _, node in tree.filter(javalang.tree.MethodDeclaration) if 'Override' in (node.annotations or [])]
116
-
117
- if overridden_methods:
118
- score += 10
119
- feedback.append(f"✓ {len(overridden_methods)} método(s) sobrescrito(s) corretamente.")
120
- else:
121
- feedback.append("⚠ Nenhum uso de polimorfismo encontrado.")
122
- except Exception as e:
123
- feedback.append("⚠ Erro ao analisar polimorfismo.")
124
 
125
- return score, feedback
 
 
126
 
127
- def analyze_abstraction(self, code: str) -> Tuple[float, List[str]]:
128
- """Avalia o uso de abstração"""
129
- score = 0
130
- feedback = []
131
 
132
- try:
133
- tree = javalang.parse.parse(code)
134
- abstract_classes = [node for _, node in tree.filter(javalang.tree.ClassDeclaration) if 'abstract' in node.modifiers]
135
- interfaces = list(tree.filter(javalang.tree.InterfaceDeclaration))
136
-
137
- if abstract_classes:
138
- score += 5
139
- feedback.append(f"✓ {len(abstract_classes)} classe(s) abstrata(s) declarada(s).")
140
  else:
141
- feedback.append(" Nenhuma classe abstrata encontrada.")
142
 
143
- if interfaces:
144
- score += 5
145
- feedback.append(f"✓ {len(interfaces)} interface(s) declarada(s).")
146
- else:
147
- feedback.append("⚠ Nenhuma interface encontrada.")
148
- except Exception as e:
149
- feedback.append("⚠ Erro ao analisar abstração.")
150
 
151
- return score, feedback
 
 
 
 
 
 
 
 
152
 
153
- def evaluate_code(self, code: str) -> Dict:
154
- """Avalia o código Java"""
155
- cls_score, cls_feedback = self.analyze_classes_and_objects(code)
156
- meth_score, meth_feedback = self.analyze_methods(code)
157
- enc_score, enc_feedback = self.analyze_encapsulation(code)
158
- inh_score, inh_feedback = self.analyze_inheritance(code)
159
- poly_score, poly_feedback = self.analyze_polymorphism(code)
160
- abs_score, abs_feedback = self.analyze_abstraction(code)
161
-
162
- essential_score = cls_score + meth_score
163
- bonus_score = enc_score + inh_score + poly_score + abs_score
164
- total_score = essential_score + bonus_score
165
- total_score = min(100, total_score)
166
-
167
- proficiency = "Necessita Melhorias"
168
- if total_score >= 90:
169
- proficiency = "Excelente"
170
- elif total_score >= 75:
171
- proficiency = "Bom"
172
- elif total_score >= 60:
173
- proficiency = "Satisfatório"
174
-
175
- return {
176
- "total_score": total_score,
177
- "essential_score": essential_score,
178
- "bonus_score": bonus_score,
179
- "proficiency": proficiency,
180
- "feedback": {
181
- "classes_objetos": cls_feedback,
182
- "metodos": meth_feedback,
183
- "encapsulamento": enc_feedback,
184
- "heranca": inh_feedback,
185
- "polimorfismo": poly_feedback,
186
- "abstracao": abs_feedback,
187
- }
188
- }
189
 
190
  # Interface Gradio
191
- with gr.Blocks(title="Java-Judge: OO Paradigm", css="#rubric_image img {max-width: 50%; height: auto; margin: 0 auto;}") as demo:
192
  gr.Markdown("# Avaliador de POO em Java")
193
- gr.Markdown("### [Visualizar a Rubrica em PDF](rubric.pdf)")
194
- gr.Markdown("#### Avalie seu código Java com base em critérios de POO")
195
-
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  upload = gr.File(label="Carregue arquivos Java para avaliação", file_types=[".java"], file_count="multiple")
197
  evaluate_button = gr.Button("Avaliar Código")
198
  output = gr.Textbox(label="Resultado da Avaliação", lines=25)
199
-
200
- gr.Markdown("### Rubrica de Avaliação")
201
- rubric_image = gr.Image("rubric_table.png", label="Tabela Resumida da Rubrica", elem_id="rubric_image")
202
 
203
  def evaluate_code_files(files) -> str:
204
- evaluator = JavaPOOEvaluator()
 
205
  results = []
206
 
207
  for file in files:
@@ -209,14 +351,27 @@ with gr.Blocks(title="Java-Judge: OO Paradigm", css="#rubric_image img {max-widt
209
  code = f.read()
210
  evaluation = evaluator.evaluate_code(code)
211
 
212
- result = f"\nArquivo: {file.name}\n"
213
- result += f"Pontuação Total: {evaluation['total_score']:.1f}/100\n"
214
- result += f"Nível: {evaluation['proficiency']}\n\n"
215
- result += "Feedback Detalhado:\n"
216
- for category, comments in evaluation['feedback'].items():
217
- result += f"\n{category.replace('_', ' ').title()}:\n"
218
- for comment in comments:
219
- result += f" {comment}\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  results.append(result)
221
 
222
  return "\n".join(results)
@@ -224,4 +379,4 @@ with gr.Blocks(title="Java-Judge: OO Paradigm", css="#rubric_image img {max-widt
224
  evaluate_button.click(fn=evaluate_code_files, inputs=upload, outputs=output)
225
 
226
  if __name__ == "__main__":
227
- demo.launch(share=True)
 
 
1
  import javalang
2
  from typing import Dict, List, Tuple
3
+ from dataclasses import dataclass
4
+
5
+ @dataclass
6
+ class RubricCriterion:
7
+ name: str
8
+ description: str
9
+ weight: int
10
+ is_essential: bool
11
+ levels: Dict[str, Dict[str, float]]
12
+
13
+ class EnhancedJavaPOOEvaluator:
14
+ """Avaliador POO com rubrica detalhada"""
15
 
 
 
16
  def __init__(self):
17
  self.rubric = {
18
+ "classes_objects": RubricCriterion(
19
+ name="Classes e Objetos",
20
+ description="Avalia a definição e uso de classes e objetos",
21
+ weight=20,
22
+ is_essential=True,
23
+ levels={
24
+ "Fraco": {"threshold": 0, "description": "Nenhuma ou poucas classes/objetos"},
25
+ "Regular": {"threshold": 10, "description": "Classes básicas sem organização clara"},
26
+ "Bom": {"threshold": 15, "description": "Classes bem estruturadas e objetos adequados"},
27
+ "Excelente": {"threshold": 20, "description": "Excelente uso de classes e objetos"}
28
+ }
29
+ ),
30
+ "methods": RubricCriterion(
31
+ name="Métodos",
32
+ description="Avalia métodos e sua organização",
33
+ weight=20,
34
+ is_essential=True,
35
+ levels={
36
+ "Fraco": {"threshold": 0, "description": "Poucos métodos ou mal estruturados"},
37
+ "Regular": {"threshold": 10, "description": "Métodos básicos sem sobrecarga"},
38
+ "Bom": {"threshold": 15, "description": "Boa organização e alguns métodos sobrecarregados"},
39
+ "Excelente": {"threshold": 20, "description": "Excelente organização e uso de sobrecarga"}
40
+ }
41
+ ),
42
+ "attributes": RubricCriterion(
43
+ name="Atributos",
44
+ description="Avalia atributos e sua organização",
45
+ weight=20,
46
+ is_essential=True,
47
+ levels={
48
+ "Fraco": {"threshold": 0, "description": "Poucos atributos ou mal organizados"},
49
+ "Regular": {"threshold": 10, "description": "Atributos básicos sem encapsulamento"},
50
+ "Bom": {"threshold": 15, "description": "Boa organização de atributos"},
51
+ "Excelente": {"threshold": 20, "description": "Excelente organização e encapsulamento"}
52
+ }
53
+ ),
54
+ "encapsulation": RubricCriterion(
55
+ name="Encapsulamento",
56
+ description="Avalia uso de modificadores e getters/setters",
57
+ weight=10,
58
+ is_essential=False,
59
+ levels={
60
+ "Ausente": {"threshold": 0, "description": "Sem encapsulamento"},
61
+ "Parcial": {"threshold": 5, "description": "Encapsulamento básico"},
62
+ "Bom": {"threshold": 7.5, "description": "Bom uso de encapsulamento"},
63
+ "Excelente": {"threshold": 10, "description": "Encapsulamento completo e correto"}
64
+ }
65
+ ),
66
+ "inheritance": RubricCriterion(
67
+ name="Herança",
68
+ description="Avalia uso de herança",
69
+ weight=10,
70
+ is_essential=False,
71
+ levels={
72
+ "Ausente": {"threshold": 0, "description": "Sem uso de herança"},
73
+ "Parcial": {"threshold": 5, "description": "Uso básico de herança"},
74
+ "Bom": {"threshold": 7.5, "description": "Bom uso de herança"},
75
+ "Excelente": {"threshold": 10, "description": "Uso avançado e apropriado de herança"}
76
+ }
77
+ ),
78
+ "polymorphism": RubricCriterion(
79
+ name="Polimorfismo",
80
+ description="Avalia uso de polimorfismo",
81
+ weight=10,
82
+ is_essential=False,
83
+ levels={
84
+ "Ausente": {"threshold": 0, "description": "Sem uso de polimorfismo"},
85
+ "Parcial": {"threshold": 5, "description": "Uso básico de sobrescrita"},
86
+ "Bom": {"threshold": 7.5, "description": "Bom uso de polimorfismo"},
87
+ "Excelente": {"threshold": 10, "description": "Uso avançado de polimorfismo"}
88
+ }
89
+ ),
90
+ "abstraction": RubricCriterion(
91
+ name="Abstração",
92
+ description="Avalia uso de abstrações",
93
+ weight=10,
94
+ is_essential=False,
95
+ levels={
96
+ "Ausente": {"threshold": 0, "description": "Sem uso de abstração"},
97
+ "Parcial": {"threshold": 5, "description": "Uso básico de interfaces/classes abstratas"},
98
+ "Bom": {"threshold": 7.5, "description": "Bom uso de abstração"},
99
+ "Excelente": {"threshold": 10, "description": "Uso completo de abstrações"}
100
+ }
101
+ )
102
  }
103
 
104
+ def evaluate_criterion(self, criterion: RubricCriterion, analysis_result: Dict) -> Tuple[float, str, str]:
105
+ """Avalia um critério específico baseado nos resultados da análise"""
106
  score = 0
107
+ level = list(criterion.levels.keys())[0] # Nível mais baixo por padrão
108
  feedback = []
109
 
110
+ if criterion.name == "Classes e Objetos":
111
+ num_classes = len(analysis_result.get("classes", []))
112
+ num_objects = len(analysis_result.get("objects", []))
113
+
114
+ if num_classes >= 3 and num_objects >= 5:
115
+ score = criterion.weight
116
+ level = "Excelente"
117
+ elif num_classes >= 2 and num_objects >= 3:
118
+ score = criterion.weight * 0.75
119
+ level = "Bom"
120
+ elif num_classes >= 1 and num_objects >= 1:
121
+ score = criterion.weight * 0.5
122
+ level = "Regular"
123
+
124
+ feedback.append(f"Encontradas {num_classes} classes e {num_objects} objetos")
125
+
126
+ elif criterion.name == "Métodos":
127
+ methods = analysis_result.get("methods", [])
128
+ method_names = [m.name for m in methods]
129
+ overloaded = len([name for name in method_names if method_names.count(name) > 1])
130
+
131
+ if len(methods) >= 5 and overloaded >= 2:
132
+ score = criterion.weight
133
+ level = "Excelente"
134
+ elif len(methods) >= 3 and overloaded >= 1:
135
+ score = criterion.weight * 0.75
136
+ level = "Bom"
137
+ elif len(methods) >= 1:
138
+ score = criterion.weight * 0.5
139
+ level = "Regular"
140
+
141
+ feedback.append(f"Encontrados {len(methods)} métodos, sendo {overloaded} sobrecarregados")
142
+
143
+ elif criterion.name == "Atributos":
144
+ attributes = analysis_result.get("attributes", [])
145
+ num_private = analysis_result["encapsulation"]["private_count"]
146
+
147
+ if len(attributes) >= 5 and num_private >= 3:
148
+ score = criterion.weight
149
+ level = "Excelente"
150
+ elif len(attributes) >= 3 and num_private >= 1:
151
+ score = criterion.weight * 0.75
152
+ level = "Bom"
153
+ elif len(attributes) >= 1:
154
+ score = criterion.weight * 0.5
155
+ level = "Regular"
156
+
157
+ feedback.append(f"Encontrados {len(attributes)} atributos, sendo {num_private} privados")
158
+
159
+ elif criterion.name == "Encapsulamento":
160
+ num_private = analysis_result["encapsulation"]["private_count"]
161
+ num_getters_setters = analysis_result["encapsulation"]["getters_setters"]
162
+
163
+ if num_private >= 3 and num_getters_setters >= 4:
164
+ score = criterion.weight
165
+ level = "Excelente"
166
+ elif num_private >= 2 and num_getters_setters >= 3:
167
+ score = criterion.weight * 0.75
168
+ level = "Bom"
169
+ elif num_private >= 1 and num_getters_setters >= 2:
170
+ score = criterion.weight * 0.5
171
+ level = "Parcial"
172
+
173
+ feedback.append(f"Encontrados {num_private} atributos privados e {num_getters_setters} getters/setters")
174
+
175
+ elif criterion.name == "Herança":
176
+ subclasses = analysis_result["inheritance"]["subclasses"]
177
+
178
+ if len(subclasses) >= 3:
179
+ score = criterion.weight
180
+ level = "Excelente"
181
+ elif len(subclasses) >= 2:
182
+ score = criterion.weight * 0.75
183
+ level = "Bom"
184
+ elif len(subclasses) >= 1:
185
+ score = criterion.weight * 0.5
186
+ level = "Parcial"
187
+
188
+ feedback.append(f"Encontradas {len(subclasses)} classes que usam herança")
189
+
190
+ elif criterion.name == "Polimorfismo":
191
+ overridden = len(analysis_result["polymorphism"]["overridden_methods"])
192
+
193
+ if overridden >= 3:
194
+ score = criterion.weight
195
+ level = "Excelente"
196
+ elif overridden >= 2:
197
+ score = criterion.weight * 0.75
198
+ level = "Bom"
199
+ elif overridden >= 1:
200
+ score = criterion.weight * 0.5
201
+ level = "Parcial"
202
+
203
+ feedback.append(f"Encontrados {overridden} métodos sobrescritos")
204
+
205
+ elif criterion.name == "Abstração":
206
+ abstract_classes = len(analysis_result["abstraction"]["abstract_classes"])
207
+ interfaces = len(analysis_result["abstraction"]["interfaces"])
208
+
209
+ if abstract_classes >= 1 and interfaces >= 1:
210
+ score = criterion.weight
211
+ level = "Excelente"
212
+ elif abstract_classes >= 1 and interfaces >= 0:
213
+ score = criterion.weight * 0.75
214
+ level = "Bom"
215
+ elif abstract_classes >= 1 or interfaces >= 1:
216
+ score = criterion.weight * 0.5
217
+ level = "Parcial"
218
+
219
+ feedback.append(f"Encontradas {abstract_classes} classes abstratas e {interfaces} interfaces")
220
+
221
+ return score, level, ". ".join(feedback)
222
+
223
+ def analyze_code(self, code: str) -> Dict:
224
+ """Analisa o código Java e retorna dados brutos"""
225
+ analysis = {
226
+ "classes": [],
227
+ "objects": [],
228
+ "methods": [],
229
+ "attributes": [],
230
+ "encapsulation": {"private_count": 0, "getters_setters": 0},
231
+ "inheritance": {"subclasses": []},
232
+ "polymorphism": {"overridden_methods": []},
233
+ "abstraction": {"abstract_classes": [], "interfaces": []}
234
+ }
235
 
236
  try:
237
  tree = javalang.parse.parse(code)
 
 
 
 
 
 
 
 
 
238
 
239
+ # Análise de classes e objetos
240
+ analysis["classes"] = [node for _, node in tree.filter(javalang.tree.ClassDeclaration)]
241
+ analysis["objects"] = [node for _, node in tree.filter(javalang.tree.VariableDeclarator)
242
+ if isinstance(node.initializer, javalang.tree.ClassCreator)]
243
 
244
+ # Análise de métodos
245
+ analysis["methods"] = [node for _, node in tree.filter(javalang.tree.MethodDeclaration)]
 
 
246
 
247
+ # Análise de atributos e encapsulamento
248
+ fields = [node for _, node in tree.filter(javalang.tree.FieldDeclaration)]
249
+ analysis["attributes"] = fields
250
+ analysis["encapsulation"]["private_count"] = sum(1 for field in fields
251
+ if "private" in field.modifiers)
252
 
253
+ # Contagem de getters e setters
254
+ methods = analysis["methods"]
255
+ getters_setters = sum(1 for method in methods
256
+ if method.name.startswith('get') or method.name.startswith('set'))
257
+ analysis["encapsulation"]["getters_setters"] = getters_setters
258
 
259
+ # Análise de herança
260
+ analysis["inheritance"]["subclasses"] = [cls for cls in analysis["classes"]
261
+ if cls.extends is not None]
 
 
 
 
 
262
 
263
+ # Análise de polimorfismo
264
+ analysis["polymorphism"]["overridden_methods"] = [method for method in methods
265
+ if any(ann.name == "Override"
266
+ for ann in (method.annotations or []))]
267
 
268
+ # Análise de abstração
269
+ analysis["abstraction"]["abstract_classes"] = [cls for cls in analysis["classes"]
270
+ if "abstract" in cls.modifiers]
271
+ analysis["abstraction"]["interfaces"] = [node for _, node in tree.filter(javalang.tree.InterfaceDeclaration)]
272
 
 
 
 
 
 
 
 
 
 
273
  except Exception as e:
274
+ print(f"Erro na análise: {str(e)}")
275
 
276
+ return analysis
277
 
278
+ def evaluate_code(self, code: str) -> Dict:
279
+ """Avalia o código Java usando a rubrica detalhada"""
280
+ analysis = self.analyze_code(code)
281
+ evaluation = {
282
+ "scores": {},
283
+ "levels": {},
284
+ "feedback": {},
285
+ "summary": {
286
+ "essential_score": 0,
287
+ "bonus_score": 0,
288
+ "total_score": 0
289
+ }
290
+ }
 
 
 
291
 
292
+ # Avalia cada critério
293
+ for criterion_key, criterion in self.rubric.items():
294
+ score, level, feedback = self.evaluate_criterion(criterion, analysis)
295
 
296
+ evaluation["scores"][criterion_key] = score
297
+ evaluation["levels"][criterion_key] = level
298
+ evaluation["feedback"][criterion_key] = feedback
 
299
 
300
+ if criterion.is_essential:
301
+ evaluation["summary"]["essential_score"] += score
 
 
 
 
 
 
302
  else:
303
+ evaluation["summary"]["bonus_score"] += score
304
 
305
+ evaluation["summary"]["total_score"] = min(100,
306
+ evaluation["summary"]["essential_score"] +
307
+ evaluation["summary"]["bonus_score"])
 
 
 
 
308
 
309
+ # Determina nível geral
310
+ if evaluation["summary"]["total_score"] >= 90:
311
+ evaluation["summary"]["proficiency"] = "Excelente"
312
+ elif evaluation["summary"]["total_score"] >= 75:
313
+ evaluation["summary"]["proficiency"] = "Bom"
314
+ elif evaluation["summary"]["total_score"] >= 60:
315
+ evaluation["summary"]["proficiency"] = "Satisfatório"
316
+ else:
317
+ evaluation["summary"]["proficiency"] = "Necessita Melhorias"
318
 
319
+ return evaluation
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320
 
321
  # Interface Gradio
322
+ with gr.Blocks(title="Avaliador de POO em Java") as demo:
323
  gr.Markdown("# Avaliador de POO em Java")
324
+ gr.Markdown("""
325
+ Este avaliador analisa código Java em relação aos princípios de Programação Orientada a Objetos.
326
+
327
+ Critérios avaliados:
328
+
329
+ """)
330
+ # Links usando caminho completo do Hugging Face
331
+ gr.HTML(f"""
332
+ <h3>
333
+ <a href="https://huggingface.co/spaces/rmayormartins/java-judge-oo/resolve/main/assets/rubric.pdf" target="_blank">📄 Visualizar Rubrica PDF</a>
334
+ </h3>
335
+ <h3>
336
+ <a href="https://huggingface.co/spaces/rmayormartins/java-judge-oo/resolve/main/assets/rubric_table.PNG" target="_blank">📊 Visualizar Tabela da Rubrica</a>
337
+ </h3>
338
+ """)
339
+
340
  upload = gr.File(label="Carregue arquivos Java para avaliação", file_types=[".java"], file_count="multiple")
341
  evaluate_button = gr.Button("Avaliar Código")
342
  output = gr.Textbox(label="Resultado da Avaliação", lines=25)
 
 
 
343
 
344
  def evaluate_code_files(files) -> str:
345
+ """Função para avaliar múltiplos arquivos Java"""
346
+ evaluator = EnhancedJavaPOOEvaluator()
347
  results = []
348
 
349
  for file in files:
 
351
  code = f.read()
352
  evaluation = evaluator.evaluate_code(code)
353
 
354
+ # Formatar resultado por arquivo
355
+ result = f"\n{'='*50}\nAvaliação do arquivo: {file.name}\n{'='*50}\n\n"
356
+
357
+ # Pontuação e nível geral
358
+ result += f"Pontuação Total: {evaluation['summary']['total_score']:.1f}/100\n"
359
+ result += f"Nível de Proficiência: {evaluation['summary']['proficiency']}\n"
360
+ result += f"Pontuação Essencial: {evaluation['summary']['essential_score']:.1f}/60\n"
361
+ result += f"Pontuação Bônus: {evaluation['summary']['bonus_score']:.1f}/40\n\n"
362
+
363
+ # Detalhamento por critério
364
+ result += "Avaliação Detalhada por Critério:\n"
365
+ result += "-" * 30 + "\n\n"
366
+
367
+ for criterion_key, criterion in evaluator.rubric.items():
368
+ result += f"• {criterion.name}:\n"
369
+ result += f" Nível: {evaluation['levels'][criterion_key]}\n"
370
+ result += f" Pontuação: {evaluation['scores'][criterion_key]:.1f}/{criterion.weight}\n"
371
+ if evaluation['feedback'][criterion_key]:
372
+ result += f" Feedback: {evaluation['feedback'][criterion_key]}\n"
373
+ result += "\n"
374
+
375
  results.append(result)
376
 
377
  return "\n".join(results)
 
379
  evaluate_button.click(fn=evaluate_code_files, inputs=upload, outputs=output)
380
 
381
  if __name__ == "__main__":
382
+ demo.launch(debug=True)
rubric.pdf DELETED
Binary file (143 kB)
 
rubric_table.png DELETED
Binary file (109 kB)