Boles de colors

Una urna conté boles de mateixes dimensions i mateix material però de colors diferents. S’extreu un nombre determinat de boles de l’urna sense reposició i es vol calcular la probabilitat de que totes les boles extretes siguin del mateix color. Es pretén fer una anàlisi exhaustiva dels casos que es poden presentar i comparar els resultats obtinguts amb els que s’obtindrien aplicant les fórmules de la teoria de probabilitats de les distribucions hipergeomètriques 1.

Una urna es representa amb un diccionari que té com a claus un color (un string, com per exemple “vermell” o “groc”) i com a valors associats el nombre de boles d’aquest color que hi ha a l’urna. Per exemple, el diccionari {“vermell”: 4, “blau”: 3, “verd”: 1} representa una urna amb quatre boles vermelles, tres de blaves i una de verda.

L’espai dels resultats de les extraccions es representa també amb un diccionari que té com a claus una tupla que expressa una combinació de colors de boles ordenada alfabèticament i com a valors associats el nombre de casos d’aquesta combinació. Pel diccionari que representa l’urna d’exemple, i suposant que s’extreuen 3 boles, l’espai de resultats seria: {(“blau”, “blau”, “blau”): 1 , (“blau”, “blau”, “verd”): 3, (“blau”, “blau”, “vermell”): 12, (“blau”, “vermell”, “verd”): 12, (“blau”, “vermell”, “vermell”): 18, (“verd”, “vermell”, “vermell”): 6, (“vermell”, “vermell”, “vermell”): 4}.

Deseu les funcions següents al fitxer boles.py.

  1. Dissenyeu la funció seguent:

    boles.iter_boles(d)

    Donat un diccionari que representa una urna, tal com s’ha descrit, retorni un iterador que lliuri tants elements com boles hi ha a l’urna. Aquets elements han de ser el color de cada bola i s’han de lliurar en ordre lexicogràfic . No es pot utilitzar cap composició iterativa (for o while). Podeu utilitzar el mètode dict.items() dels diccionaris, la funció map() i el mètode itertools.chain.from_iterable()

    >>> import boles
    >>> d = {'vermell': 4, 'blau': 3, 'verd': 1}
    >>> it1 = boles.iter_boles(d)
    >>> next(it1)
    'blau'
    >>> next(it1)
    'blau'
    >>> next(it1)
    'blau'
    >>> next(it1)
    'verd'
    >>> next(it1)
    'vermell'
    >>> next(it1)
    'vermell'
    >>> next(it1)
    'vermell'
    >>> next(it1)
    'vermell'
    >>> next(it1)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    
  2. Dissenyeu la funció seguent:

    boles.iter_combinacions(it, nboles)

    Donat un iterador de colors de boles com el retornat per la funció iter_boles() i del nombre de boles que s’extreuen, nboles, retorni un iterador que lliuri totes les tuples possibles que siguin resultats de l’extracció. No es pot utilitzar cap composició iterativa (for o while). Utilitzeu la funció que us sembli més adient del mòdul itertools.

    >>> import boles
    >>> d = {'vermell': 4, 'blau': 3, 'verd': 1}
    >>> it1 = boles.iter_boles(d)
    >>> it2= boles.iter_combinacions(it1, 2)
    >>> l2 = list(it2)
    >>> len(l2)
    28
    >>> l2
    [('blau', 'blau'), ('blau', 'blau'), ('blau', 'verd'), ('blau', 'vermell'), ('blau', 'vermell'), ('blau', 'vermell'), ('blau', 'vermell'), ('blau', 'blau'), ('blau', 'verd'), ('blau', 'vermell'), ('blau', 'vermell'), ('blau', 'vermell'), ('blau', 'vermell'), ('blau', 'verd'), ('blau', 'vermell'), ('blau', 'vermell'), ('blau', 'vermell'), ('blau', 'vermell'), ('verd', 'vermell'), ('verd', 'vermell'), ('verd', 'vermell'), ('verd', 'vermell'), ('vermell', 'vermell'), ('vermell', 'vermell'), ('vermell', 'vermell'), ('vermell', 'vermell'), ('vermell', 'vermell'), ('vermell', 'vermell')]
    
    >>> it1 = boles.iter_boles(d)
    >>> it2= boles.iter_combinacions(it1, 3)
    >>> next(it2)
    ('blau', 'blau', 'blau')
    >>> next(it2)
    ('blau', 'blau', 'verd')
    >>> next(it2)
    ('blau', 'blau', 'vermell')
    >>> next(it2)
    ('blau', 'blau', 'vermell')
    
  3. Dissenyeu la funció següent:

    boles.combinacions(dic, nboles)

    A partir d’un diccionari que representa una urna, dic, i el nombre de boles, nboles, retorni un diccionari que representi l’espai de resultats. Aquesta funció ha d’utilitzar els iteradors obtinguts en les funcions iter_boles() i iter_combinacions(). Les claus del diccionari han de ser les tuples ordenades alfabèticament.

    >>> import boles
    >>> d = {'vermell': 4, 'blau': 3, 'verd': 1}
    >>> d1 = boles.combinacions(d, 3)
    >>> if d1!= {('blau', 'blau', 'verd'): 3, ('blau', 'vermell', 'vermell'): 18, ('blau', 'verd', 'vermell'): 12, ('blau', 'blau', 'vermell'): 12, ('verd', 'vermell', 'vermell'): 6, ('blau', 'blau', 'blau'): 1, ('vermell', 'vermell', 'vermell'): 4}:
    ...    print(d1)
    
  4. Dissenyeu la funció

    boles.calculaProbabilitat(urna, nboles)

    A partir del nombre de boles que s’extreuen i de la representació d’una urna amb un diccionari com el descrit, calculi la probabilitat de que totes les boles extretes siguin del mateix color. Cal utilitzar la funció combinacions().

    >>> import boles
    >>> d = {'vermell': 4, 'blau': 3, 'verd': 1}
    >>> print ('{:4.3f}'.format(boles.calculaProbabilitat(d, 3)))
    8.929
    

Disposeu de jocs de prova al fitxer boles.txt.

Solució

Disposeu d’una solució a boles.py.