fix: Corrige cálculo de pontuação da nota do PPG no Componente B
Mudanças: - Implementa escala correta de nota: 7=20, 6=15, 5=10, 4=5, 3=0 - Usa MAIOR nota entre os programas coordenados - Adiciona documentação detalhada no método - Corrige extras para programas adicionais (só conta se > 1) Conforme especificação técnica oficial CAPES
This commit is contained in:
@@ -103,27 +103,54 @@ class CalculadorPontuacao:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def calcular_componente_b(coordenacoes: List[CoordenacaoPrograma]) -> ComponentePontuacao:
|
def calcular_componente_b(coordenacoes: List[CoordenacaoPrograma]) -> ComponentePontuacao:
|
||||||
|
"""
|
||||||
|
Calcula pontuação do Componente B (Coordenação de Programa PPG).
|
||||||
|
|
||||||
|
Regras (máximo 180 pts):
|
||||||
|
- Base: 70 pts por ser coordenador
|
||||||
|
- Tempo: 5 pts/ano (máx 50)
|
||||||
|
- Programas adicionais: 20 pts/programa (máx 40)
|
||||||
|
- Nota do PPG: usar MAIOR nota (7=20, 6=15, 5=10, 4=5, 3=0)
|
||||||
|
"""
|
||||||
if not coordenacoes:
|
if not coordenacoes:
|
||||||
return ComponentePontuacao(base=0, tempo=0, extras=0, bonus=0)
|
return ComponentePontuacao(base=0, tempo=0, extras=0, bonus=0)
|
||||||
|
|
||||||
|
# Base: 70 pts por ser coordenador
|
||||||
base = 70
|
base = 70
|
||||||
|
|
||||||
|
# Tempo: 5 pts/ano (máx 50)
|
||||||
anos_totais = sum(c.periodo.anos_completos(datetime.now()) for c in coordenacoes)
|
anos_totais = sum(c.periodo.anos_completos(datetime.now()) for c in coordenacoes)
|
||||||
tempo = min(int(anos_totais * 5), 50)
|
tempo = min(int(anos_totais * 5), 50)
|
||||||
|
|
||||||
|
# Programas adicionais: 20 pts/programa extra (máx 40)
|
||||||
programas_distintos = len({c.id_programa for c in coordenacoes})
|
programas_distintos = len({c.id_programa for c in coordenacoes})
|
||||||
extras = min((programas_distintos - 1) * 20, 40)
|
extras = min((programas_distintos - 1) * 20, 40) if programas_distintos > 1 else 0
|
||||||
|
|
||||||
nota_bonus = 0
|
# Nota do PPG: usar MAIOR nota entre os programas
|
||||||
|
# Escala: 7=20, 6=15, 5=10, 4=5, 3=0
|
||||||
|
maior_nota = 0
|
||||||
for c in coordenacoes:
|
for c in coordenacoes:
|
||||||
try:
|
try:
|
||||||
nota_num = float(c.nota_ppg)
|
nota_str = str(c.nota_ppg).strip()
|
||||||
if nota_num >= 0:
|
# Trata notas válidas (3-7 ou A para programas novos)
|
||||||
nota_bonus = 20
|
if nota_str in ['7']:
|
||||||
break
|
maior_nota = max(maior_nota, 7)
|
||||||
|
elif nota_str in ['6']:
|
||||||
|
maior_nota = max(maior_nota, 6)
|
||||||
|
elif nota_str in ['5']:
|
||||||
|
maior_nota = max(maior_nota, 5)
|
||||||
|
elif nota_str in ['4']:
|
||||||
|
maior_nota = max(maior_nota, 4)
|
||||||
|
elif nota_str in ['3']:
|
||||||
|
maior_nota = max(maior_nota, 3)
|
||||||
except Exception:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
return ComponentePontuacao(base=base, tempo=tempo, extras=extras, bonus=nota_bonus)
|
# Mapeia nota para pontos
|
||||||
|
mapa_nota = {7: 20, 6: 15, 5: 10, 4: 5, 3: 0}
|
||||||
|
bonus = mapa_nota.get(maior_nota, 0)
|
||||||
|
|
||||||
|
return ComponentePontuacao(base=base, tempo=tempo, extras=extras, bonus=bonus)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def calcular_componente_c(consultoria: Consultoria) -> ComponentePontuacao:
|
def calcular_componente_c(consultoria: Consultoria) -> ComponentePontuacao:
|
||||||
|
|||||||
Reference in New Issue
Block a user