Lliga de futbol

La resultats que es produeixen en una lliga de futbol es guarden en una llista on cada element representa un partit disputat. Cada partit és a la seva vegada una llista de quatre elements: un string amb el nom de l’equip local, un enter amb els gols marcats per l’equip local, un string amb el nom de l’equip visitant i un enter amb els gols marcats per l’equip visitant. Un exemple d’un partit de la lliga podria ser la llista: [‘LasPalmas’, 3, ‘AthBilbao’, 1].

Obtenir la classificació

Es vol fer una funció classif_equips(lPartits) que a partir de la llista lPartits amb la informació dels partits disputats per uns equips de futbol retorni un diccionari amb la classificació final. La clau del diccionari serà el nom de l’equip i el valor el seu número de punts. Tots els equips tindran 0 punts abans de disputar la llista de partits.

La funció recorre la llista lPartits i va actualitzant el diccionari de la classificació en funció del resultat: l’equip que guanya es porta 3 punts, el que perd cap, i si empaten 1 punt cadascú.

Nota

Aquest és un exemple amb els partits disputats fins al 23 de novembre del 2016 a la Fase de Grups de la Champions 2016 al grup C, format per: FC Barcelona, Manchester City, Borússia Monchengladbach i Celtic de Glasgow. Els resultats estan extrets de la pàgina web de la UEFA.

>>> lP = [ [ 'Barcelona', 7, 'CelticGlasgow', 0 ],
...        [ 'ManchesterCity', 4, 'BorussiaMG', 0 ],
...        [ 'BorussiaMG', 1, 'Barcelona', 2 ],
...        [ 'CelticGlasgow', 3, 'ManchesterCity', 3 ],
...        [ 'Barcelona', 4, 'ManchesterCity', 0 ],
...        [ 'CelticGlasgow', 0, 'BorussiaMG', 2 ],
...        [ 'ManchesterCity', 3, 'Barcelona', 1 ],
...        [ 'BorussiaMG', 1, 'CelticGlasgow', 1 ],
...        [ 'BorussiaMG', 1, 'ManchesterCity', 1 ],
...        [ 'CelticGlasgow', 0, 'Barcelona', 2 ]
...      ]
>>> dC = classif_equips(lP)
>>> dC == { 'BorussiaMG': 5, 'Barcelona': 12, 'ManchesterCity': 8, 'CelticGlasgow': 2 }
True

Completa el codi de la funció que tens a continuació:

def classif_equips(lPartits):
    # La classificació (diccionari) inicial és buida:
    dClassif = {}
    for partit in lPartits:
        # [A]. Extreure nom_local, gols_local, nom_visit i gols_visit de partit:
        # [B]. Es busca l'equip local al dicionari dClassif:
        if nom_local not in dClassif:    # si no hi és
            # S'afegeix al dicionari amb 0 punts
        # [C]. Es busca l'equip visitant al diccionari dClassif:
        if nom_visit not in dClassif:    # si no hi és
            # S'afegeix al diccionari amb 0 punts
        # [D]. Se sumen els punts que corresponen a cada equip:
        if gols_local > gols_visit:
            # Guanya l'equip local
        elif gols_local < gols_visit:
            # Guanya l'equip visitant
        else:
            # Hi ha empat
    # Retorna el diccionari amb la classificaio final:
    return dClassif

Ordenar la classificació

La funció ordenaClassif(dClassif) donat un diccionari dClassif com el retornat per la funció classif_equips, calcula i retorna una llista de parelles/tuples (nomEquip, punts) amb la classificació dels equips ordenada en ordre decreixent del número de punts. Quan hi ha igualtat de punts es farà servir l’ordre creixent dels noms per desfer l’empat. Un exemple de una classificació ordenada de equips és: [ [21, Celta], [15, Betis], [15, Rayo] ]

>>> dClassif = { 'BorussiaMG': 5, 'ManchesterCity': 8, 'Barcelona': 12, 'CelticGlasgow': 2 }
>>> sortedClassif(dClassif)
[('Barcelona', 12), ('ManchesterCity', 8), ('BorussiaMG', 5), ('CelticGlasgow', 2)]

A continuació hi ha una posible solució:

import operator

def ordenaClassif(dClassif):
    # Obté una llista dels parelles (clau, valor) que conté el diccionari:
    lClassif = dClassif.items()    # llista de (nomEquip, punts)
    # Per ordenar per punts (decreixent) i, en cas d'empat, per nom (creixent):
    # [A]. Ordena per nom en ordre creixent
    #      itemgetter(0) obté la primera component de la parella (nomEquip)
    lClassif2 = sorted(lClassif, key=operator.itemgetter(0))
    # [B]. Ordena per punts en ordre decreixent (reverse=True)
    #      itemgetter(1) obté la segona component de la parella (punts)
    lClassif3 = sorted(lClassif2, key=operator.itemgetter(1), reverse=True)
    return lClassif3    # retorna la llista amb la classificació final

Escriure la classificació

La funció mostraClassif(lClassif) donada una llista amb la classificació ordenada tal com la obtinguda per la funció ordenaClassif, escriu per pantalla, línia a línia, el seu contingut.

>>> lC = [ ('Barcelona', 12), ('ManchesterCity', 8),
...        ('BorussiaMG', 5), ('CelticGlasgow', 2) ]
>>> mostraClassif(lC)    
 1. Barcelona            12 punts
 2. ManchesterCity        8 punts
 3. BorussiaMG            5 punts
 4. CelticGlasgow         2 punts

A continuació hi ha una posible solució:

def mostraClassif(lClassif):
    for i in range(len(lClassif)):
         nom, punts = lClassif[i]    # lClassif[i] és una tupla (nom, punts)
         print('{:2n}. {}\t\t{:2n} punts'.format(i+1, nom, punts))

Llegir els partits d’un fitxer

La funció llegeixPartits(nomFitxer) donat un string nomFitxer amb el nom d’un fitxer de text que conté resultats dels partits d’una lliga de futbol, llegeix el fitxer línia a línia i obté i retorna la llista dels resultats en el format especificat al començament del problema.

Nota

A continuació veieu el continugut def fitxer grupC.txt amb els resultats dels partits de la fase de grups de la Champions d’aquest 2016.

Barcelona       7 - 0  CelticGlasgow
ManchesterCity  4 - 0  BorussiaMG
BorussiaMG      1 - 2  Barcelona
CelticGlasgow   3 - 3  ManchesterCity
Barcelona       4 - 0  ManchesterCity
CelticGlasgow   0 - 2  BorussiaMG
ManchesterCity  3 - 1  Barcelona
BorussiaMG      1 - 1  CelticGlasgow
BorussiaMG      1 - 1  ManchesterCity
CelticGlasgow   0 - 2  Barcelona
>>> llegeixPartits('grupC.txt')
[['Barcelona', 7, 'CelticGlasgow', 0], ['ManchesterCity', 4, 'BorussiaMG', 0], ['BorussiaMG', 1, 'Barcelona', 2], ['CelticGlasgow', 3, 'ManchesterCity', 3], ['Barcelona', 4, 'ManchesterCity', 0], ['CelticGlasgow', 0, 'BorussiaMG', 2], ['ManchesterCity', 3, 'Barcelona', 1], ['BorussiaMG', 1, 'CelticGlasgow', 1], ['BorussiaMG', 1, 'ManchesterCity', 1], ['CelticGlasgow', 0, 'Barcelona', 2]]

A continuació hi ha una posible solució:

def llegeixPartits(nomFitxer):
    # La llista de partits és buida al començament:
    lP = []
    # Obre el fitxer de texte amb els partits:
    with open(nomFitxer) as f:
        # Recorre el fitxer línia a línia:
        for line in f:
            l = line.split()    # Separa les paraules (són 5 amb el guió)
            # Extreu nom_local, nom_visit, guio, gols_local i gols_visit de l:
            nom_local, gols_local, guio, gols_visit, nom_visit = l
            # Monta un partit amb els noms d'equips i gols marcats (enters):
            partit = [nom_local, int(gols_local), nom_visit, int(gols_visit)]
            # Afegeix el partit d'aquesta línia a la llista lP:
            lP.append(partit)
    # Retorna la llista de partits que s'ha creat:
    return lP

Programa principal

El següent programa demana el nom d’un fitxer amb partits de futbol i escriu per pantalla la classificació final. Per tal de fer-ho es fan crides a les 3 funcions anteriors.

if __name__ == '__main__':
    # Demana el nom del fitxer de partits:
    nomF = input('Escriu el nom d\'un fitxer de partits: ')
    # Llegeix el fitxer i obte la llista de partits:
    lParts = llegeixPartits(nomF)
    # S'obté la classificació (diccionari) después dels partits:
    dClass = classif_equips(lParts)
    # S'obté una llista ordenadda amb la classificació:
    lClass = ordenaClassif(dClass)
    # S'escriu la classificació línia a línia:
    mostraClassif(lClass)