Àlbum de música

En aquest exercici implementareu classes destinades a representar informació relacionada amb àlbums de música.

La classe PeçaMusical

Implementeu la classe PeçaMusical que representa una peça de música. Deseu aquesta classe al fitxer pessa_musical.py. L’especificació d’aquesta classe és la següent:

class pessa_musical.PeçaMusical(titol, durada)

Retorna una peça a partir dels paràmetres de títol i durada.

Atributs:

titol

El títol de la peça musical (classe str)

durada

La durada de la peça musical (instància de la classe datetime.timedelta)

Aquesta classe ha de suportar l’operació de comparació per igualtat. Dues peces són iguals si coincideixen els títols i les durades:

Operació

Resultat

p1 == p2

p1 és igual a p2

Per exemple:

>>> from pessa_musical import PeçaMusical
>>> from datetime import timedelta
>>> d = timedelta(minutes=2, seconds=57)
>>> p = PeçaMusical("Speak to Me", d)
>>> p.titol
'Speak to Me'
>>> p.durada
datetime.timedelta(seconds=177)
>>> p2 = PeçaMusical("Take Five", timedelta(minutes=5, seconds=14))
>>> p == p2
False
>>> p3 = PeçaMusical("Take Five", timedelta(minutes=5, seconds=14))
>>> p2 == p3
True

Trobareu més exemples d’ús d’aquesta classe al fitxer test-pessa_musical.txt i una solució al fitxer pessa_musical.py.

La classe AlbumBase

En el mòdul album_base.py dissenyeu la classe AlbumBase que permet de representar àlbums de música. La seva especificació és la següent:

class album_base.AlbumBase(titol, autor, nombre_peces)

Retorna un nou àlbum de música amb el títol i autors donats, preparat per a emmagatzemar nombre_peces cançons.

Atributs:

titol

Títol de l’àlbum (str)

autor

Nom de l’autor de l’àlbum (str)

Aquesta classe ha de suportar les operacions següents:

Operació

Resultat

len(a)

retorna el nombre de peces l’àlbum

a[i]

retorna la i-èssima peça de l’àlbum a, essent 0<=i<len(a)

a[i] = p

assigna la peça p al i-èssim element de l’àlbum, essent, 0<=i<len(a)

p in a

retorna True si la peça p pertany a l’àlbum a, False altrament

La classe ha de ser iterable sobre la seqüència de peces musicals ordenades per índex creixent.

Per implementar aquesta classe, haureu d’inicialitzar un atribut privat que contindrà nombre_peces d’instàncies de la classe pessa_musical.PeçaMusical. Inicialment, aquestes peces han de tenir com a títol l’string buit i una durada de 0 segons.

Per exemple:

>>> from pessa_musical import PeçaMusical
>>> from album_base import AlbumBase
>>> from datetime import timedelta

>>> a1 = AlbumBase('The Dark Side of the Moon', 'Pink Floyd', 10)
>>> a1.titol
'The Dark Side of the Moon'
>>> a1.autor
'Pink Floyd'
>>> len(a1)
10
>>> a1[0].titol
''
>>> a1[0].durada
datetime.timedelta(0)
>>> a1[0] = PeçaMusical('Speak to Me', timedelta(minutes=1, seconds=20))
>>> a1[0].titol
'Speak to Me'
>>> a1[0].durada
datetime.timedelta(seconds=80)
>>> a1[4] = PeçaMusical('The Great Gig in the Sky', timedelta(minutes=23, seconds=45))
>>> a1[4].titol
'The Great Gig in the Sky'
>>> a1[4].durada
datetime.timedelta(seconds=1425)

Trobareu més exemples d’ús d’aquesta classe al fitxer test-album_base.txt i una solució al fitxer album_base.py.

La funció titols_llargs

Dissenyeu la funció titols_llargs que donada una llista d’instàncies de la classe AlbumBase i una longitud mínima retorni la llista de títols de peces que superen la longitud mínima donada. Deseu la funció titols_llargs al fitxer titols_llargs.py. Podeu resoldre aquest exercici utilitzant les funcions map() i itertools.chain.from_iterable.

Vegeu, per exemple:

>>> from datetime import timedelta
>>> from pessa_musical import PeçaMusical
>>> from album_base import AlbumBase
>>> from titols_llargs import titols_llargs


>>> a1 = AlbumBase('The Dark Side of the Moon', 'Pink Floyd', 10)
>>> a1[0] = PeçaMusical('Speak to Me', timedelta(minutes=2, seconds=34))
>>> a1[1] = PeçaMusical('Breathe', timedelta(minutes=2, seconds=30))
>>> a1[2] = PeçaMusical('On the Run', timedelta(minutes=3, seconds=24))
>>> a1[3] = PeçaMusical('Time', timedelta(minutes=2, seconds=34))
>>> a1[4] = PeçaMusical('The Great Gig in the Sky', timedelta(minutes=1, seconds=14))
>>> a1[5] = PeçaMusical('Money', timedelta(minutes=5, seconds=14))
>>> a1[6] = PeçaMusical('Us and Them', timedelta(minutes=4, seconds=44))
>>> a1[7] = PeçaMusical('Any Colour You Like', timedelta(minutes=3, seconds=21))
>>> a1[8] = PeçaMusical('Brain Damage', timedelta(minutes=1, seconds=54))
>>> a1[9] = PeçaMusical('Eclipse', timedelta(minutes=2, seconds=38))

>>> a2 = AlbumBase('Let It Be', 'The Beatles', 12)
>>> a2[0] = PeçaMusical('Two of Us', timedelta(minutes=2, seconds=34))
>>> a2[1] = PeçaMusical('Dig a Pony', timedelta(minutes=2, seconds=34))
>>> a2[2] = PeçaMusical('Across the Universe', timedelta(minutes=2, seconds=34))
>>> a2[3] = PeçaMusical('I Me Mine', timedelta(minutes=2, seconds=34))
>>> a2[4] = PeçaMusical( 'Dig It', timedelta(minutes=2, seconds=34))
>>> a2[5] = PeçaMusical('Let It Be', timedelta(minutes=2, seconds=34))
>>> a2[6] = PeçaMusical('Maggie Mae', timedelta(minutes=2, seconds=34))
>>> a2[7] = PeçaMusical('I’ve Got a Feeling', timedelta(minutes=2, seconds=34))
>>> a2[8] = PeçaMusical('One After 909', timedelta(minutes=2, seconds=34))
>>> a2[9] = PeçaMusical('The Long and Winding Road', timedelta(minutes=2, seconds=34))
>>> a2[10] = PeçaMusical('For You Blue', timedelta(minutes=2, seconds=34))
>>> a2[11] = PeçaMusical('Get Back', timedelta(minutes=2, seconds=34))

>>> l = [a1, a2]

>>> lt = titols_llargs(l, 20)
>>> print(sorted(lt))
['The Great Gig in the Sky', 'The Long and Winding Road']

Trobareu més exemples d’ús d’aquesta classe al fitxer test-titols_llargs.txt i una solució al fitxer titols_llargs.py.

La classe Album

Al fitxer album.py, dissenyeu la classe Album que es deriva per herència de la classe AlbumBase i que l’estén afegint-li informació de l’any de publicació. A més a més, li afegeix també el mètode durada():

class album.Album(titol, autor, any_publicacio, nombre_peces)

Atributs:

any_publicacio

Any de publicació de l’àlbum

Mètodes:

durada()

Retorna la durada total de l’àlbum

Per dissenyar aquesta classe heu de tenir en compte les observacions següents:

  1. L’atribut any_publicacio s’inicialitza en construir la instància a partir del nom del paràmetre de mateix nom.

  2. Per a implementar el mètode durada(), cal sumar la durada de totes les cançons de l’àlbum. Recomanem fer les funcions predefinidies dels iteradors, fent ús del paràmetre opcional :start de la funció sum().

Per exemple:

>>> from datetime import timedelta
>>> from pessa_musical import PeçaMusical
>>> from album import Album


>>> a1 = Album('The Dark Side of the Moon', 'Pink Floyd', 1973, 10)
>>> print(a1.titol)
The Dark Side of the Moon
>>> print(a1.autor)
Pink Floyd
>>> print(a1.any_publicacio)
1973
>>> print(len(a1))
10
>>> a1[0] = PeçaMusical('Speak to Me', timedelta(minutes=1, seconds=8))
>>> print(a1[0].titol, a1[0].durada)
Speak to Me 0:01:08
>>> a1[1] = PeçaMusical('Breathe', timedelta(minutes=2, seconds=49))
>>> print(a1[1].titol, a1[1].durada)
Breathe 0:02:49
>>> a1[2] = PeçaMusical('On the Run', timedelta(minutes=3, seconds=51))
>>> print(a1[2].titol, a1[2].durada)
On the Run 0:03:51
>>> a1[3] = PeçaMusical('Time', timedelta(minutes=6, seconds=50))
>>> print(a1[3].titol, a1[3].durada)
Time 0:06:50
>>> a1[4] = PeçaMusical('The Great Gig in the Sky', timedelta(minutes=4, seconds=44))
>>> print(a1[4].titol, a1[4].durada)
The Great Gig in the Sky 0:04:44
>>> a1[5] = PeçaMusical('Money', timedelta(minutes=6, seconds=23))
>>> print(a1[5].titol, a1[5].durada)
Money 0:06:23
>>> a1[6] = PeçaMusical('Us and Them', timedelta(minutes=7, seconds=50))
>>> print(a1[6].titol, a1[6].durada)
Us and Them 0:07:50
>>> a1[7] = PeçaMusical('Any Colour You Like', timedelta(minutes=3, seconds=26))
>>> print(a1[7].titol, a1[7].durada)
Any Colour You Like 0:03:26
>>> a1[8] = PeçaMusical('Brain Damage', timedelta(minutes=3, seconds=47))
>>> print(a1[8].titol, a1[8].durada)
Brain Damage 0:03:47
>>> a1[9] = PeçaMusical('Eclipse', timedelta(minutes=2, seconds=12))
>>> print(a1[9].titol, a1[9].durada)
Eclipse 0:02:12

>>> print(a1.durada())
0:43:00

Trobareu més exemples d’ús d’aquesta classe al fitxer test-album.txt i una solució a album.py.