Hay dos torneos populares en el fútbol: la Champions League y la Europa League. En función de sus resultados,
se calcula la denominada
Clasificación de las asociaciones de fútbol . Según esta clasificación, se determina además cuántos equipos de cada país participarán en torneos posteriores.
En este artículo, crearé una aplicación basada en la plataforma
lsFusion abierta y gratuita que calculará esta calificación. Almacenará todos sus datos en PostgreSQL, proporcionará una interfaz web para cambiarlos y mostrarlos con capacidades de filtrado y clasificación, así como también importará resultados de coincidencias utilizando una API especial.
Todo el código para implementar esta aplicación constará de unas 300 líneas significativas.
Lógica de dominio
La creación de cualquier sistema de información comienza con la tarea de la lógica de dominio.
En primer lugar, es lógico seleccionar los directorios más simples que solo tienen un código y un nombre:
- Torneo Liga de Campeones o Europa League.
- Temporada 2018-2019 / 2017-2018 etc.
- Ronda . Final, Semifinal, Fase de grupos, etc. Se puede considerar como una composición para el torneo, pero en esta implementación lo destaqué como una entidad separada.
- Pais Esta aplicación se utiliza como la Asociación de Fútbol. Por ejemplo, el club de Mónaco se encuentra en el país de Mónaco, pero juega en el campeonato francés.
- Club Barcelona, Real Madrid, Manchester United, etc.
Dado que lsFusion usa el mismo tipo de lógica para declararlos, declararemos un metacódigo (o plantilla de código) que generará la lógica correspondiente:
Metacódigo de declaración de directorio Él anunciará:
- Clase con nombre de pila
- Propiedades con código y nombre para la nueva clase.
- Tres formas: editar un objeto, una forma con una lista de todos los objetos, que luego se agrega al navegador, un diálogo para seleccionar este objeto. Como diálogo, puede usar la segunda forma, pero luego el usuario tendrá la oportunidad de cambiar los objetos al elegir, lo que puede provocar errores por parte de los usuarios.
Se pasan cuatro parámetros al metacódigo:
- Identificador (objeto) . Con este nombre se crearán clases y formularios. La construcción ### se usa para hacer que la primera letra del identificador se capitalice en el código resultante.
- Nombre en singular . Usado para el título de la clase y la forma.
- El nombre está en plural . Utilizado para cuadro combinado y diálogo.
- Longitud del nombre En los nombres de diferentes objetos, se esperan diferentes longitudes, lo cual es importante al construir la interfaz.
Usando el metacódigo creado, agregue las cinco entidades descritas anteriormente:
El código generado, por ejemplo, para un torneo se verá así:
Agregue el enlace al país a la lógica del club generada. Para hacer esto, primero cree la propiedad correspondiente, que luego colocará en los formularios de edición y visualización del club:
Ponemos toda la lógica creada en un módulo maestro separado (archivo Master.lsf).
Ahora crea una entidad
League . Ella determinará el torneo de una temporada en particular. Por ejemplo, Champions League 2017-18 o Europa League 2018-19. La liga no tendrá un nombre, sino solo enlaces al torneo y la temporada. Por lo tanto, no usaremos el metacódigo anterior, pero haremos la misma lógica y lo pondremos en el nuevo módulo de la Liga:
Y finalmente, agregue la lógica de los partidos. Para hacer esto, cree la clase
Match , que se referirá a la liga y la ronda. Para él, los clubes que participaron en él, y el resultado también se le preguntará. Ponemos todo esto en un módulo Match separado:
Importación de datos
Desafortunadamente, logré encontrar solo una API pública y gratuita que sea compatible con todas las Eurocopas. Esta es
la API de fútbol . Sin embargo, hay problemas:
- No hay resultados hasta 2016.
- No hay calificaciones para la Europa League hasta 2018.
- Hay ciertos errores en los datos. Por ejemplo, Irtysh Pavlodar está asignado a Rusia, aunque este club representa a Kazajstán. Además, Europa Fc por alguna razón se refiere a España en lugar de Gibraltar.
Los errores de datos pueden corregirse manualmente utilizando formularios creados previamente. Sin embargo, dado que el cálculo del coeficiente total se basa en los últimos cinco años, desafortunadamente, no funcionará calcular el coeficiente total a partir de los datos de API Football. Si alguien en los comentarios sugiere dónde obtener los datos necesarios en cualquier formato de años anteriores, estaré muy agradecido. Pero, dado que hay datos completos para 2018, será posible verificar la exactitud del cálculo para al menos este año.
La API que necesitamos se implementa en forma de solicitudes HTTP, donde los parámetros se transmiten a través de la URL y se indica una clave de acceso especial en el encabezado. Declare la lógica correspondiente:
Todas las acciones de importación de datos se colocarán en el formulario de
ligas creado anteriormente. Allí colocaremos la clave de acceso en la barra de herramientas de la tabla con la lista de ligas:
Primero, implementamos la lista de ligas. Para esto, la API de fútbol tiene una url especial: / ligas. Una solicitud GET le devuelve JSON del formulario:
La respuesta { "api":{ "results":2, "leagues":[ { "league_id":1, "name":"2018 Russia World Cup", "country":"World", "country_code":null, "season":2018, "season_start":"2018-06-14", "season_end":"2018-07-15", "logo":"https://www.api-football.com/public/leagues/1.png", "flag":null, "standings":0, "is_current":1 }, { "league_id":2, "name":"Premier League", "country":"England", "country_code":"GB", "season":2018, "season_start":"2018-08-10", "season_end":"2019-05-12", "logo":"https://www.api-football.com/public/leagues/2.png", "flag":"https://www.api-football.com/public/flags/gb.svg", "standings":1, "is_current":1 } ] } }
Para generar una solicitud GET y registrar el cuerpo de respuesta, se utiliza la siguiente construcción:
Escribe el resultado en la propiedad de
resultado local sin parámetros de tipo FILE.
Para analizar un archivo en formato JSON, se crea un formulario cuya estructura corresponde a la estructura JSON. Puede generarlo en el IDE utilizando el elemento del menú:

Para el JSON anterior, el formulario se verá así (teniendo en cuenta solo aquellos valores que se importarán):
Para importar directamente desde la propiedad del
resultado JSON en el formato del formulario
importLeagues, use el siguiente comando:
Después de su ejecución, los valores correspondientes del archivo JSON se colocarán en las propiedades
torneoName ,
seasonName y
leagueId :

Es decir, el valor de
torneoName (0) será "Copa Mundial", y en
torneoName (1) será "Premier League".
Desafortunadamente, API Football no tiene una entidad de torneo en absoluto. La única forma de vincular todas las ligas es tener un nombre que coincida con las ligas del mismo torneo de diferentes temporadas. Para hacer esto, en la importación, primero agrupamos todos los nombres de las ligas importadas y, si no en la base de datos, creamos nuevos torneos:
Tampoco hay códigos para las estaciones, por lo que al importar ligas, se crean de la misma manera. Después de crear los objetos que faltan, las ligas se importan directamente. Los torneos y las temporadas se buscan por nombre utilizando las propiedades creadas anteriormente a través de
GROUP AGGR :
Por defecto, los datos se cargarán, pero solo se guardarán en la base de datos cuando el usuario haga clic en el botón Guardar en el formulario. Si es necesario, puede agregar el comando
APLICAR al final de la acción para que se guarde inmediatamente en la base de datos sin una vista previa.
Y finalmente, agregue la acción de importación al formulario de lista de liga:
Del mismo modo, importamos clubes y partidos. Sin embargo, dado que la API proporciona la capacidad de importarlos solo para una liga específica, la acción debe tomar la liga como entrada:
Importar clubes y partidosHay una peculiaridad para los partidos: los códigos de equipo van dentro de las
etiquetas adicionales de
homeTeam y
awayTeam . Los grupos correspondientes se crean para ellos por analogía con api. Además, en su interior tienen las mismas etiquetas
team_id . Como las propiedades con el mismo nombre no se pueden agregar al formulario, se
usa la palabra clave especial
EXTID , que define el nombre de la etiqueta en el JSON importado.
Para que todas las importaciones estén en la misma forma, y dado que están vinculadas a las ligas, las llevamos todas a la misma forma. Además, agregamos equipos y partidos al formulario para poder ver lo que se importa antes de guardar:
La forma resultante se verá así:

Todas las importaciones se colocarán en un módulo APIFootball separado.
Cálculo del coeficiente
Procedemos directamente al cálculo del coeficiente de país de la UEFA. Es lógico poner todo el código en un módulo UEFA especialmente instalado para esto.
Primero, tenga en cuenta que Football API proporciona una interfaz para importar todos los partidos, y no solo las Eurocopas. Por lo tanto, separamos los partidos de Eurocup según el nombre del torneo (es más correcto tener una propiedad primaria separada para esto, pero la implementación de las propiedades siempre se puede cambiar sin modificar el resto de la lógica):
Primero, calculemos los puntos que cada club recibe en una temporada por los resultados de partidos específicos.
Durante este período, cada equipo recibe:
2 puntos en caso de victoria;
1 punto en caso de empate.
Desde 1999, estos puntos se dividen en dos si se obtienen en rondas de calificación, es decir:
1 punto en caso de victoria;
0.5 puntos por un empate.
Crea propiedades auxiliares que determinen la relación entre el partido y el club:
Para determinar cuántos puntos se anotan en cada partido, agregamos la propiedad primaria del tipo numérico para la ronda, que por defecto será igual a uno:
Luego contamos puntos por victorias y empates y sumamos:
Los puntos para los partidos se marcan como MATERIALIZADOS para que se guarden en la tabla y no se calculen cada vez.
Ahora necesita contar puntos de bonificación:
Además, se otorgan puntos de bonificación:
Se otorga 1 punto en caso de que el equipo llegue a cuartos de final, semifinales y finales en copas europeas;
4 puntos por alcanzar la fase de grupos de la Liga de Campeones (hasta 1996 - 2 puntos, de 1997 a 2003 - 1 punto, de 2004 a 2008 - 3 puntos);
5 puntos en caso de que un equipo se vaya a las finales de 1/8 de la Liga de Campeones (antes de 2008 - 1 punto).
Solo se tienen en cuenta los partidos jugados (no se tienen en cuenta las pérdidas técnicas). Los partidos que terminan en una serie de penaltis, cuando se calcula el coeficiente se consideran de acuerdo con el resultado, que se fija por los resultados del juego en el tiempo principal y extra.
En esta implementación, suponemos que el club entró en la ronda del torneo si jugó al menos un partido en él. Para hacer esto, calculamos cuántos partidos jugó el club en una temporada, torneo o ronda en particular:
Ahora necesita determinar cuántos puntos anotar para el pasaje en una ronda en particular. Como depende del torneo (por ejemplo, un pasaje en la ⅛ Champions League recibe 5 puntos, pero nada en la Europa League). Para hacer esto, presentamos la propiedad primaria:
Ahora calculemos los puntos de bonificación y el número total de puntos para el club para la temporada:
Finalmente, vamos directamente al coeficiente del país.
Para calcular la calificación de la asociación, se suman todos los puntos anotados por los clubes que participan en la Champions League y la Europa League, y el resultado se divide por el número de clubes de esta asociación [2] [3].
Calculemos el número de clubes para cada asociación que participó en competiciones europeas:
Ahora consideramos el número total de puntos de asociación para la temporada y dividimos por el número de clubes:
La calificación de un país es la suma de los coeficientes del país para los 5 años anteriores.
Para hacer esto, numeramos todas las estaciones comenzando desde la última por el código interno (asumimos que estas últimas se agregaron más tarde y tienen un código más grande):
Si es necesario, puede ingresar un campo o número por nombre.
Solo queda calcular la calificación final para el país:
Arriba, anunciamos probabilidades para torneos y rondas. Agréguelos al formulario de edición del torneo, mientras filtra solo las rondas que estaban en estos torneos:
Configuración de probabilidades, por ejemplo, para la Liga de Campeones que necesita establecer de esta manera:

Dibujemos un formulario que muestre la calificación, donde se mostrarán los equipos para cada país y para cada equipo sus partidos:
La forma resultante se verá así:

El color en las mesas de los clubes muestra cuándo participó en las temporadas, y en la tabla de partidos, quién ganó.
La imagen muestra que las calificaciones para 2018 se calculan exactamente igual que en Wikipedia. Para años anteriores, como se mencionó anteriormente, Football API no proporciona toda la información.
Resumen
Creamos una pequeña aplicación que está completamente descrita por el código anterior y almacena sus datos en PostgreSQL, proporciona una interfaz web para ver y editar datos. Al mismo tiempo, funcionará eficazmente en grandes volúmenes, ya que todos los formularios leen solo la ventana visible. También están listos los filtros, la clasificación, la carga en Excel y más.
Debe notarse cuán fácilmente usando la plataforma, la tarea de calcular el coeficiente se descompuso en propiedades individuales. Cuando se ejecute, toda esta lógica se traducirá en consultas SQL y todos los cálculos se realizarán directamente en el servidor de la base de datos utilizando todas las optimizaciones de DBMS.
Puede encontrar un ejemplo de cómo funciona la aplicación con los datos cargados en ella en:
https://demo.lsfusion.org/euroleague . Inicio de sesión de invitado sin contraseña. El usuario está en modo de solo lectura.
Aquellos que lo deseen pueden
establecer todo a nivel local y, por ejemplo, modelar los coeficientes ingresando los resultados de futuras coincidencias. Todos los módulos de aplicación descritos anteriormente están alojados en
github . Después de la instalación automática, solo necesita abrir estos archivos en la carpeta correspondiente de las instrucciones y reiniciar el servidor.
Para descargar datos de Football API, debe registrarse con ellos y obtener la clave API. Requiere una tarjeta, pero si no realiza más de 50 solicitudes por día, no se deducirá nada de ella.
Además, puede ejecutar esta aplicación en línea en la
sección correspondiente del sitio. En la pestaña Plataforma, seleccione el ejemplo de Cálculo de probabilidades de la UEFA y haga clic en Jugar.
Por cierto, si alguien necesita implementar un sistema simple para el que Excel ya no sea adecuado, escriba los comentarios. Para conocer las capacidades de la plataforma, intentaremos implementarla y escribir el artículo correspondiente.