Il existe deux tournois populaires dans le football: la Ligue des champions et la Ligue Europa. Sur la base de leurs résultats, la soi-disant
notation des associations de football est calculée. Sur la base de cette note, il est également déterminé combien d'équipes de chaque pays participeront aux tournois suivants.
Dans cet article, je vais créer une application basée sur la plateforme
lsFusion ouverte et gratuite qui calculera cette note. Il stockera toutes ses données dans PostgreSQL, fournira une interface Web pour les modifier et les afficher avec des capacités de filtrage et de tri, ainsi que d'importer les résultats des correspondances à l'aide d'une API spéciale.
Tout le code pour implémenter cette application sera composé d'environ 300 lignes significatives.
Logique de domaine
La création de tout système d'information commence par la tâche de la logique du domaine.
Tout d'abord, il est logique de distinguer les répertoires les plus simples qui n'ont qu'un code et un nom:
- Tournoi Ligue des Champions ou Ligue Europa.
- Saison . 2018-2019 / 2017-2018 etc.
- Ronde . Finale, demi-finale, phase de groupes, etc. Il peut être considéré comme une composition pour le tournoi, mais dans cette mise en œuvre, je l'ai choisi comme une entité distincte.
- Pays Cette application est utilisée comme association de football. Par exemple, le club de Monaco est situé dans le pays de Monaco, mais joue en championnat de France.
- Club Barcelone, Real Madrid, Manchester United, etc.
Puisque lsFusion utilise le même type de logique pour les déclarer, nous déclarerons un métacode (ou modèle de code) qui générera la logique correspondante:
Métacode de déclaration de répertoire Il annoncera:
- Classe avec prénom
- Propriétés avec code et nom pour la nouvelle classe
- Trois formulaires: l'édition d'un objet, un formulaire avec une liste de tous les objets, qui est ensuite ajouté au navigateur, une boîte de dialogue pour sélectionner cet objet. En tant que dialogue, vous pouvez utiliser le deuxième formulaire, mais l'utilisateur aura alors la possibilité de modifier les objets lors de son choix, ce qui peut entraîner des erreurs de la part des utilisateurs.
Quatre paramètres sont transmis au métacode:
- Identifiant (objet) . Avec ce nom, des classes et des formulaires seront créés. La construction ### est utilisée pour rendre la première lettre de l'identifiant en majuscule dans le code résultant.
- Nom au singulier . Utilisé pour le titre de la classe et du formulaire.
- Le nom est au pluriel . Utilisé pour la zone de liste déroulante et la boîte de dialogue.
- Longueur du nom . Dans les noms des différents objets, différentes longueurs sont attendues, ce qui est important lors de la construction de l'interface.
À l'aide du métacode créé, ajoutez les cinq entités décrites ci-dessus:
Le code généré, par exemple, pour un tournoi ressemblera à ceci:
Ajoutez le lien vers le pays à la logique de club générée. Pour ce faire, créez d'abord la propriété correspondante, puis placez-la sur les formulaires d'édition et de visualisation du club:
Nous mettons toute la logique créée dans un module Master séparé (fichier Master.lsf).
Créez maintenant une entité
League . Elle déterminera le tournoi d'une saison particulière. Par exemple, Champions League 2017-18 ou Europa League 2018-19. La ligue n'aura pas de nom, mais seulement des liens vers le tournoi et la saison. Par conséquent, nous n'utiliserons pas le métacode précédent, mais nous ferons la même logique et le placerons dans le nouveau module League:
Et enfin, ajoutez la logique des matchs. Pour ce faire, créez la classe
Match , qui fera référence à la ligue et au tour. Pour lui, les clubs qui y ont participé, et le résultat sera également demandé. Nous mettons tout cela dans un module Match séparé:
Importation de données
Malheureusement, j'ai réussi à trouver une seule API publique et gratuite qui prend en charge toutes les Eurocups. Il s'agit de
l'API Football . Cependant, il y a des problèmes:
- Il n'y a pas de résultats avant 2016.
- Il n'y a pas de qualification pour la Ligue Europa jusqu'en 2018.
- Il y a certaines erreurs dans les données. Par exemple, Irtysh Pavlodar est affecté à la Russie, bien que ce club représente le Kazakhstan. En outre, Europa Fc, pour une raison quelconque, fait référence à l'Espagne au lieu de Gibraltar.
Les erreurs de données peuvent être corrigées manuellement à l'aide de formulaires créés précédemment. Cependant, puisque le calcul du coefficient total est basé sur les cinq dernières années, malheureusement, cela ne fonctionnera pas pour calculer le coefficient total à partir des données de l'API Football. Si quelqu'un dans les commentaires suggère où obtenir les données nécessaires dans n'importe quel format des années précédentes, je serai très reconnaissant. Mais, comme il existe des données complètes pour 2018, il sera possible de vérifier l'exactitude du calcul pendant au moins cette année.
L'API dont nous avons besoin est implémentée sous la forme de requêtes HTTP, où les paramètres sont transmis via l'URL, et une clé d'accès spéciale est indiquée dans l'en-tête. Déclarez la logique correspondante:
Toutes les actions d'importation de données seront placées sur le formulaire de
ligues créé précédemment. Là, nous placerons la clé d'accès dans la barre d'outils du tableau avec la liste des ligues:
Tout d'abord, nous mettons en œuvre la liste des ligues. Pour cela, l'API Football a une URL spéciale: / ligues. Une requête GET lui renvoie JSON du formulaire:
La réponse { "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 } ] } }
Pour générer une demande GET et enregistrer le corps de réponse, la construction suivante est utilisée:
Il écrit le résultat dans la propriété de
résultat local sans paramètres de type FILE.
Pour analyser un fichier au format JSON, un formulaire est construit dont la structure correspond à la structure JSON. Vous pouvez le générer dans l'EDI en utilisant l'élément de menu:

Pour le JSON ci-dessus, le formulaire ressemblera à ceci (en prenant en compte uniquement les valeurs qui seront importées):
Pour importer directement à partir de la propriété de
résultat JSON au format du formulaire
importLeagues, utilisez la commande suivante:
Après son exécution, les valeurs correspondantes du fichier JSON seront placées dans les propriétés
tournoiName ,
seasonName et
leagueId :

Autrement dit, la valeur de
tournoiName (0) sera «Coupe du monde» et, dans
tournoiName (1), ce sera «Premier League».
Malheureusement, API Football n'a pas du tout d'entité de tournoi. La seule façon de lier toutes les ligues est d'avoir un nom qui correspond aux ligues d'un même tournoi de saisons différentes. Pour ce faire, lors de l'importation, nous regroupons d'abord tous les noms des ligues importées et, sinon dans la base de données, créons de nouveaux tournois:
Il n'y a pas non plus de codes pour les saisons, donc lors de l'importation de ligues, ils sont créés de la même manière. Une fois les objets manquants créés, les ligues sont importées directement. Les tournois et les saisons sont recherchés par nom en utilisant les propriétés construites précédemment via
GROUP AGGR :
Par défaut, les données seront chargées, mais ne seront enregistrées dans la base de données que lorsque l'utilisateur cliquera sur le bouton Enregistrer du formulaire. Si nécessaire, vous pouvez ajouter la commande
APPLY à la fin de l'action afin qu'elle soit immédiatement enregistrée dans la base de données sans aperçu.
Et enfin, ajoutez l'action d'importation au formulaire de liste de ligue:
De même, nous importons des clubs et des matchs. Cependant, comme l'API offre la possibilité de les importer uniquement pour une ligue spécifique, l'action doit prendre la ligue en entrée:
Importer des clubs et des matchsIl y a une particularité pour les matchs: les codes d'équipe vont dans des
balises homeTeam et
awayTeam supplémentaires. Des groupes correspondants sont créés pour eux par analogie avec l'API. De plus, à l'intérieur, ils ont les mêmes balises
team_id . Étant donné que les propriétés portant le même nom ne peuvent pas être ajoutées au formulaire, le mot clé spécial
EXTID est
utilisé , qui définit le nom de la balise dans le JSON importé.
Pour que toutes les importations soient sous la même forme, et comme elles sont liées aux ligues, nous les prenons toutes sous la même forme. De plus, nous ajoutons des équipes et des matchs au formulaire afin de pouvoir voir ce qui est importé avant de sauvegarder:
Le formulaire résultant ressemblera à ceci:

Toutes les importations seront placées dans un module APIFootball séparé.
Calcul du coefficient
Nous procédons directement au calcul du coefficient de pays de l'UEFA. Pour cela, il est logique de mettre tout le code dans un module UEFA spécialement installé.
Tout d'abord, gardez à l'esprit que l'API Football fournit une interface pour importer tous les matchs, et pas seulement les Eurocups. Par conséquent, nous séparons les matchs d'Eurocup en fonction du nom du tournoi (il est plus correct d'avoir une propriété principale distincte pour cela, mais la mise en œuvre des propriétés peut toujours être modifiée sans modifier le reste de la logique):
Tout d'abord, calculons les points que chaque club reçoit au cours d'une saison pour les résultats de matchs spécifiques.
Pendant cette période, chaque équipe reçoit:
2 points en cas de victoire;
1 point en cas d'égalité.
Depuis 1999, ces points sont divisés en deux s'ils sont gagnés lors des tours de qualification, soit:
1 point en cas de victoire;
0,5 point pour une égalité.
Créez des propriétés auxiliaires qui déterminent la relation entre le match et le club:
Pour déterminer le nombre de points marqués dans chaque match, nous ajoutons la propriété principale du type numérique pour le tour, qui par défaut sera égale à un:
Ensuite, nous comptons les points pour les victoires et les nuls et additionnons:
Les points pour les matchs sont marqués comme MATÉRIALISÉS afin qu'ils soient enregistrés dans le tableau et non calculés à chaque fois.
Maintenant, vous devez compter les points bonus:
De plus, des points bonus sont accordés:
1 point est accordé si l'équipe atteint les quarts de finale, les demi-finales et les finales dans les coupes européennes;
4 points pour atteindre la phase de groupes de la Ligue des champions (jusqu'en 1996 - 2 points, de 1997 à 2003 - 1 point, de 2004 à 2008 - 3 points);
5 points en cas de départ d'une équipe pour les 1/8 de finale de la Ligue des champions (avant 2008 - 1 point).
Seuls les matchs joués sont pris en compte (les pertes techniques ne sont pas prises en compte). Les matchs se terminant par une série de tirs au but, lors du calcul du coefficient, sont considérés en fonction du résultat, qui est fixé par les résultats du match dans le temps principal et le temps supplémentaire.
Dans cette mise en œuvre, nous supposons que le club a participé au tour du tournoi s'il y a joué au moins un match. Pour ce faire, nous calculons le nombre de matches joués par le club au cours d'une saison, d'un tournoi ou d'une manche en particulier:
Vous devez maintenant déterminer le nombre de points à marquer pour le passage dans un tour particulier. Comme cela dépend du tournoi (par exemple, un passage en ⅛ Ligue des Champions se voit attribuer 5 points, mais rien en Ligue Europa). Pour ce faire, nous introduisons la propriété primaire:
Calculons maintenant les points bonus et le nombre total de points pour le club pour la saison:
Enfin, nous passons directement au coefficient pays.
Pour calculer la note de l'association, tous les points marqués par les clubs participant à la Ligue des Champions et à la Ligue Europa sont additionnés, et le résultat est divisé par le nombre de clubs de cette association [2] [3].
Calculons le nombre de clubs de chaque association ayant participé à des compétitions européennes:
Maintenant, nous considérons le nombre total de points d'association pour la saison et divisons par le nombre de clubs:
La note d'un pays est la somme des coefficients du pays pour les 5 années précédentes.
Pour ce faire, nous numérotons toutes les saisons à partir de la dernière par le code interne (nous supposons que ces dernières ont été ajoutées plus tard et ont un code plus grand):
Si nécessaire, vous pouvez saisir un champ ou un numéro distinct par nom.
Il ne reste plus qu'à calculer la note finale du pays:
Ci-dessus, nous avons annoncé des cotes pour les tournois et les tours. Ajoutez-les au formulaire d'édition de tournoi, tout en filtrant uniquement les tours qui se trouvaient dans ces tournois:
Les paramètres de cotes, par exemple, pour la Ligue des champions, vous devez définir comme ceci:

Tirons un formulaire qui affichera le classement, où les équipes seront affichées pour chaque pays, et pour chaque équipe ses matchs:
Le formulaire résultant ressemblera à ceci:

La couleur dans les tableaux des clubs montre quand il a participé aux saisons, et dans le tableau des matchs - qui a gagné.
L'image montre que les notes pour 2018 sont calculées exactement de la même manière que sur Wikipedia. Pour les années précédentes, comme mentionné ci-dessus, l'API Football ne fournit pas toutes les informations.
Résumé
Nous avons construit une petite application qui est entièrement décrite par le code ci-dessus et stocke ses données dans PostgreSQL, fournit une interface Web pour visualiser et éditer les données. Dans le même temps, il fonctionnera efficacement sur de gros volumes, car tous les formulaires lisent uniquement la fenêtre visible. Les filtres, le tri, le téléchargement vers Excel, etc. sont également prêts à l'emploi.
Il convient de noter la facilité avec laquelle la tâche de calcul du coefficient a été décomposée en propriétés individuelles. Une fois exécutée, toute cette logique sera traduite en requêtes SQL et tous les calculs seront effectués directement sur le serveur de base de données en utilisant toutes les optimisations du SGBD.
Un exemple du fonctionnement de l'application avec les données qui y sont chargées peut être trouvé à l'
adresse :
https://demo.lsfusion.org/euroleague . Connexion invité sans mot de passe. L'utilisateur est en mode lecture seule.
Ceux qui le souhaitent peuvent tout
régler eux-mêmes localement et, par exemple, modéliser les coefficients en entrant les résultats des futurs matchs. Tous les modules d'application décrits ci-dessus sont hébergés sur
github . Après l'installation automatique, il vous suffit de faire apparaître ces fichiers dans le dossier approprié à partir des instructions et de redémarrer le serveur.
Pour télécharger des données à partir de l'API Football, vous devez vous inscrire auprès d'eux et obtenir la clé API. Cela nécessite une carte, mais si vous ne faites pas plus de 50 demandes par jour, rien ne sera déduit de celle-ci.
De plus, vous pouvez exécuter cette application en ligne dans la
section appropriée du site. Dans l'onglet Plate-forme, sélectionnez l'exemple de calcul des cotes de l'UEFA et cliquez sur Jouer.
Soit dit en passant, si quelqu'un a besoin d'implémenter un système simple pour lequel Excel ne convient plus, écrivez dans les commentaires. Afin d'apprendre les capacités de la plateforme, nous allons essayer de l'implémenter et écrire l'article correspondant.