Initial project import
This commit is contained in:
136
scripts/_arquivados/importar_quadro_voo_2025.py
Normal file
136
scripts/_arquivados/importar_quadro_voo_2025.py
Normal file
@@ -0,0 +1,136 @@
|
||||
"""Importa a aba VOOS do Quadro de Voo 2025 para a base de validacao."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import re
|
||||
import sys
|
||||
from datetime import time, timedelta
|
||||
from pathlib import Path
|
||||
|
||||
import pandas as pd
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(BASE_DIR))
|
||||
|
||||
from src.planejador_missao.utils import normalizar_texto
|
||||
|
||||
|
||||
COLUNAS_VALIDACAO = ["slot_id", "data", "aeronave", "tipo_escala", "tripulante", "funcao", "oi", "horas_voadas", "sbv"]
|
||||
|
||||
|
||||
def _horas(valor: object) -> float:
|
||||
if pd.isna(valor):
|
||||
return 0.0
|
||||
if isinstance(valor, timedelta):
|
||||
return round(valor.total_seconds() / 3600, 2)
|
||||
if isinstance(valor, time):
|
||||
return round(valor.hour + valor.minute / 60 + valor.second / 3600, 2)
|
||||
if isinstance(valor, str):
|
||||
texto = valor.strip()
|
||||
if not texto or texto == "-":
|
||||
return 0.0
|
||||
partes = texto.split(":")
|
||||
if len(partes) >= 2:
|
||||
return round(float(partes[0]) + float(partes[1]) / 60, 2)
|
||||
return float(texto.replace(",", "."))
|
||||
if isinstance(valor, (int, float)):
|
||||
return round(float(valor) * 24, 2) if 0 < float(valor) < 1 else float(valor)
|
||||
return 0.0
|
||||
|
||||
|
||||
def _aeronave(valor: object) -> str:
|
||||
texto = normalizar_texto(valor)
|
||||
match = re.search(r"(\d{4})", texto)
|
||||
if not match:
|
||||
return ""
|
||||
numero = match.group(1)
|
||||
if numero.startswith("20"):
|
||||
return "C97"
|
||||
if numero.startswith("23"):
|
||||
return "C95"
|
||||
if numero.startswith("27"):
|
||||
return "C98"
|
||||
return ""
|
||||
|
||||
|
||||
def _tripulantes(valor: object) -> list[str]:
|
||||
partes = re.split(r"\s*/\s*", str(valor))
|
||||
trips = []
|
||||
for parte in partes:
|
||||
texto = normalizar_texto(parte)
|
||||
texto = re.sub(r"\([^)]*\)", " ", texto)
|
||||
texto = re.sub(r"[^A-Z0-9]+", " ", texto).strip()
|
||||
if texto and texto != "NAN":
|
||||
trips.append(texto)
|
||||
return trips[:2]
|
||||
|
||||
|
||||
def importar(origem: Path, destino: Path) -> pd.DataFrame:
|
||||
raw = pd.read_excel(origem, sheet_name="VOOS", header=None)
|
||||
linhas = []
|
||||
slot_id = 0
|
||||
for _, row in raw.iterrows():
|
||||
data = pd.to_datetime(row[2], errors="coerce")
|
||||
if pd.isna(data) or data.year != 2025:
|
||||
continue
|
||||
if normalizar_texto(row[41]) != "REALIZADO":
|
||||
continue
|
||||
|
||||
aeronave = _aeronave(row[37])
|
||||
if not aeronave:
|
||||
continue
|
||||
|
||||
slot_id += 1
|
||||
tipo_escala = normalizar_texto(row[1])
|
||||
horas_voadas = _horas(row[30])
|
||||
oi = normalizar_texto(row[35])
|
||||
if not oi or oi == "-":
|
||||
oi = normalizar_texto(row[32])
|
||||
|
||||
for idx, tripulante in enumerate(_tripulantes(row[8]), start=1):
|
||||
linhas.append(
|
||||
{
|
||||
"slot_id": slot_id,
|
||||
"data": data.date().isoformat(),
|
||||
"aeronave": aeronave,
|
||||
"tipo_escala": tipo_escala,
|
||||
"tripulante": tripulante,
|
||||
"funcao": "PILOTO" if idx == 1 else "COPILOTO",
|
||||
"oi": oi,
|
||||
"horas_voadas": horas_voadas,
|
||||
"sbv": 0,
|
||||
}
|
||||
)
|
||||
|
||||
df = pd.DataFrame(linhas, columns=COLUNAS_VALIDACAO)
|
||||
destino.parent.mkdir(parents=True, exist_ok=True)
|
||||
df.to_csv(destino, index=False)
|
||||
return df
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="Importa voos realizados de 2025 para a validacao.")
|
||||
parser.add_argument(
|
||||
"--origem",
|
||||
type=Path,
|
||||
default=BASE_DIR / "dados" / "Quadro de Voo 2025 (2).xlsx",
|
||||
help="Planilha com aba VOOS.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--destino",
|
||||
type=Path,
|
||||
default=BASE_DIR / "dados" / "validacao" / "voos_2025.csv",
|
||||
help="CSV de validacao gerado.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
df = importar(args.origem, args.destino)
|
||||
print(f"Arquivo gerado: {args.destino}")
|
||||
print(f"Registros exportados: {len(df)}")
|
||||
print(f"Voos/slots exportados: {df['slot_id'].nunique() if not df.empty else 0}")
|
||||
print(f"Tripulantes exportados: {df['tripulante'].nunique() if not df.empty else 0}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user