getBestAvg method

Future<String> getBestAvg(
  1. List<TimeTraining> timesList,
  2. int numAvg
)

Método para calcular la mejor media de X tiempos en una sesión.

Este método calcula la mejor media (más baja) de un bloque de numAvg tiempos, ordenados por fecha de más reciente a más antigua. Para cada bloque, se eliminan el mejor y el peor tiempo, y se calcula la media con los tiempos restantes (regla WCA).

Parámetros:

  • timesList: Lista de objetos TimeTraining registrados en la sesión.
  • numAvg: Número de tiempos consecutivos que se usan para calcular la media.

Retorna:

  • String: La mejor media en formato "mm:ss.ss".
    • "--:--.--" si no hay suficientes tiempos para calcular la media.

Implementation

Future<String> getBestAvg(List<TimeTraining> timesList, int numAvg) async {
  if (timesList.length < numAvg) {
    // SI NO HAY SUFICIENTES TIEMPOS PARA HACER LA MEDIA, DEVUELVE EL VALOR POR
    // DEFECTO
    return "--:--.--";
  }

  // MEJOR MEDIA (VALOR MAS BAJO)
  double bestAvgTimeInSeconds = double.infinity;

  // ORDENAMOS LA LISTA POR FECHA MAS RECIENTE
  timesList.sort((a, b) {
    DateTime dateA = DateTime.parse(a.registrationDate);
    DateTime dateB = DateTime.parse(b.registrationDate);
    // ORDENAMOS DE MAS RECIENTE A MAS ANTIGUO
    return dateB.compareTo(dateA);
  });

  // RECORREMOS LA LISTA TOMBANDO BLOQUES DE numAvg TIEMPOS
  for (int i = 0; i <= timesList.length - numAvg; i++) {
    // TOMAMOS UN BLOQUE DE numAvg TIEMPOS
    List<TimeTraining> block = timesList.sublist(i, i + numAvg);

    // ORDENAMOS EL BLOQUE POR TIEMPO (DE MENOR A MAYOR)
    block.sort((a, b) => a.timeInSeconds.compareTo(b.timeInSeconds));

    // ELIMINAMOS EL MEJOR Y EL PEOR TIEMPO
    List<TimeTraining> trimmedBlock = block.sublist(1, block.length - 1);

    // CALCULAMOS LA MEDIA DEL BLOQUE QUEDANDO CON LOS TIEMPOS RESTANTES
    double sum = 0.0;
    for (var time in trimmedBlock) {
      sum += time.timeInSeconds;
    }
    double avgTimeInSeconds = sum / trimmedBlock.length;

    // COMPARAMOS CON LAS OTRAS MEDIAS Y ACTUALIZAMOS LA MEJOR MEDIA
    if (avgTimeInSeconds < bestAvgTimeInSeconds) {
      bestAvgTimeInSeconds = avgTimeInSeconds;
    }
  }

  // CONVERTIMOS EL TIEMPO EN SEGUNDOS EN FORMATO "mm:ss.ss"
  String formatTime(double timeInSeconds) {
    int minutes = timeInSeconds ~/ 60;
    double seconds = timeInSeconds % 60;
    // AÑADE UN CARACTER '0' A LA IZQUIERDA SI TIENE MENOS DE 5 CARACTERES
    // (si es 9.45 -> 09.45, pero si es 11.45 se queda igual)
    return "${minutes}:${seconds.toStringAsFixed(2).padLeft(5, '0')}";
  }
  return formatTime(bestAvgTimeInSeconds);
}