Ús del mòdul fractions

En programació, la manera més habitual de representar els nombres racionals és mitjançant la representació en coma flotant (float), que té l’inconvenient que només pot representar aquests nombres de forma aproximada [1]. No obstant, en Python hi ha una representació alternativa, utilitzant el mòdul fractions.

  1. Estudieu la classe Fraction del mòdul fractions i proveu-la en l’intèrpret de Python, per tal de crear nombres racionals i consultar-ne el numerador i el denominador. A part de la documentació del mòdul, podeu consultar aquesta pàgina.

  2. Al fitxer fracs.py, dissenyeu-hi la funció fraccio_reciproca que, donat un nombre racional (una instància de la classe Fraction), retorna la seva fracció recíproca. Per exemple,

    
    >>> import fractions
    >>> x  = fractions.Fraction(7, 3)
    >>> fraccio_reciproca(x)
    Fraction(3, 7)
    >>> fraccio_reciproca(fractions.Fraction(100, 1))
    Fraction(1, 100)
    >>> fraccio_reciproca(fractions.Fraction(12, 400))
    Fraction(100, 3)
    
    
  3. Al fitxer fracs.py, dissenyeu-hi la funció fraccio_mixta que, donat un nombre racional positiu (una instància de la classe Fraction), retorna la seva representació mixta com una tupla de dues components: un nombre enter (positiu) i una fracció (una Fraction) irreductible no negativa menor que 1. Per exemple,

    
    >>> x = fractions.Fraction(7, 3)
    >>> fraccio_mixta(x)
    (2, Fraction(1, 3))
    >>> fraccio_mixta(fractions.Fraction(2, 5))
    (0, Fraction(2, 5))
    >>> fraccio_mixta(fractions.Fraction(4, 2))
    (2, Fraction(0, 1))
    
    
  4. Al mateix fitxer fracs.py, dissenyeu la funció millor_aprox que, donat un float x i una llista (no buida) de nombres racionals, retorna el nombre racional de la llista més proper a x, és a dir, aquell nombre de la llista que aproxima de forma més exacta el valor x:

    
    >>> millor_aprox(0.3, [fractions.Fraction(1, 3), fractions.Fraction(2, 7)])
    Fraction(2, 7)
    >>> millor_aprox(3.1415926535897932, 
    ...  [fractions.Fraction(3, 1), fractions.Fraction(355, 113), fractions.Fraction(31416, 10000)])
    Fraction(355, 113)
    
    
  5. Al mateix fitxer fracs.py, dissenyeu la funció fr_positives que, donat un iterable de fraccions (instàncies a la classe Fraction) retorna un iterador sobre la subseqüència de fraccions donades que són positives. A l’iterador retornat, les fraccions han d’estar representades com una fracció mixta. Es recomana que s’usi la funció anterior fraccio_mixta. Exemples:

    
    >>> lfr = [(-4, 8), (9, 2), (17, 4), (5, -2), (-27, -5), (99, 7), (-60, 4), (1, 6), (-3, 4), (3, 4), (46, 11), (67, 12)]
    >>> itf = map(lambda x: fractions.Fraction(x[0], x[1]), lfr)
    >>> itm = fr_positives(itf)
    >>> next(itm)
    (4, Fraction(1, 2))
    >>> next(itm)
    (4, Fraction(1, 4))
    >>> list(itm)
    [(5, Fraction(2, 5)), (14, Fraction(1, 7)), (0, Fraction(1, 6)), (0, Fraction(3, 4)), (4, Fraction(2, 11)), (5, Fraction(7, 12))]
    
    

    Avís

    Per a resoldre aquest apartat no es poden fer servir llistes, tuples, diccionaris ni cap altra estructura de dades per a desar els elements d’un iterador.

  6. Al mateix fitxer fracs.py, dissenyeu la funció seq_fraccions que, donat un enter, n (int), retorna un iterador sobre la seqüència de fraccions (instàncies a la classe Fraction) que tenen n com a denominador i com a numerador un valor positiu inferior a n, en ordre ascendent. Exemple:

    
    >>> it = seq_fraccions(10)
    >>> iter(it) == it
    True
    >>> list(it)
    [Fraction(1, 10), Fraction(1, 5), Fraction(3, 10), Fraction(2, 5), Fraction(1, 2), Fraction(3, 5), Fraction(7, 10), Fraction(4, 5), Fraction(9, 10)]
    >>> it = seq_fraccions(100)
    >>> for i in range(80):
    ...    a = next(it)
    >>> list(it)
    [Fraction(81, 100), Fraction(41, 50), Fraction(83, 100), Fraction(21, 25), Fraction(17, 20), Fraction(43, 50), Fraction(87, 100), Fraction(22, 25), Fraction(89, 100), Fraction(9, 10), Fraction(91, 100), Fraction(23, 25), Fraction(93, 100), Fraction(47, 50), Fraction(19, 20), Fraction(24, 25), Fraction(97, 100), Fraction(49, 50), Fraction(99, 100)]
    

    Avís

    Per a resoldre aquest apartat no es poden fer servir llistes, tuples, diccionaris ni cap altra estructura de dades per a desar els elements d’un iterador.

Nota

Disposeu de jocs de proves al fitxer test-frac.txt i d’una solució al fitxer fracs.py.