No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Simulador de Playlist con FIFO en Python

22/23
Recursos

¿Cómo crear un simulador de playlist de canciones?

La programación no tiene por qué ser un mar de instrucciones sin fin. Con planificación y creatividad, podemos desarrollar soluciones divertidas y prácticas, como un simulador de playlist de canciones. Este proyecto implica el uso de colas (queues) para gestionar la reproducción de canciones. Vamos a explorar cómo puedes implementarlo y qué aprendizajes puedes extraer de ello.

¿Por qué usar una estructura queue?

En este proyecto, se nos pide específicamente utilizar una cola. Las colas son estructuras de datos que operan bajo el principio de First In, First Out (FIFO), lo cual significa que el primer elemento en entrar es el primero en salir. Este enfoque es ideal para la simulación de playlists, ya que refleja cómo normalmente consumimos música: en el orden en que las canciones fueron añadidas.

¿Cómo se implementa la clase Track?

La clase Track se crea para definir los atributos de las canciones en nuestra playlist. A continuación, se muestra un ejemplo de cómo podría estructurarse esta clase:

from random import randint

class Track:
    def __init__(self, title=None):
        self.title = title if title else "Unknown"
        self.duration = randint(5, 6)  # Duración aleatoria entre 5 y 6 segundos

En este ejemplo, cada canción tiene un título y una duración aleatoria de entre 5 y 6 segundos.

¿Qué es la clase MediaPlayerQueue?

La clase MediaPlayerQueue hereda de una estructura de cola basada en nodos. Incluye métodos para añadir y reproducir canciones:

import time

class MediaPlayerQueue(Queue):  
    def __init__(self):
        super().__init__()
        
    def add_track(self, track):
        self.enqueue(track)
    
    def play(self):
        print(f"Hay {self.count()} canciones en la cola.")
        while self.head is not None:
            current_track = self.dequeue()
            print(f"Now playing: {current_track.title}")
            time.sleep(current_track.duration)  # Simula la duración de la canción

La funcionalidad de la cola asegura que las canciones se reproduzcan en el orden de llegada.

¿Cómo instancio y pruebo el simulador de playlist?

# Importamos las clases necesarias
from music_player import Track, MediaPlayerQueue

# Creamos instancias de las canciones
track1 = Track("Highway to Hell")
track2 = Track("Bohemian Rhapsody")
track3 = Track("Like a Rolling Stone")
track4 = Track("Hotel California")
track5 = Track("Stairway to Heaven")
track6 = Track("How to Disappear Completely")

# Creamos la instancia de MediaPlayerQueue
player = MediaPlayerQueue()

# Añadimos las canciones a la cola
player.add_track(track1)
player.add_track(track2)
player.add_track(track3)
player.add_track(track4)
player.add_track(track5)
player.add_track(track6)

# Reproducimos las canciones
player.play()

Este script genera un simulador básico de reproductor de música que reproduce canciones en el orden de inserción, ilustrando el funcionamiento de una cola.

¿Qué más se puede hacer?

Aunque este ejemplo básico cumple su función, siempre puedes extender la funcionalidad del reproductor:

  1. Navegación avanzada: Implementar métodos para conocer cuál será la próxima canción.
  2. Playlists dinámicas: Permitir la adición y eliminación de canciones en tiempo real.
  3. Estadísticas de reproducción: Generar estadísticas sobre las canciones más reproducidas.

¿Qué aprendizaje puedes obtener?

Este ejercicio es una excelente oportunidad para cimentar conocimientos en estructuras de datos, programación orientada a objetos y manipulación de colas en Python. Además, te anima a ser creativo y considerar cómo las estructuras de datos pueden resolver problemas del mundo real. ¡Sigue explorando y aprendiendo, cada línea de código que escribes es un paso más hacia convertirte en un experto!

Aportes 42

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Mi solución al reto.
Utilice la estructura Queue basada en listas.
Creeu na clase MusicPlaylist con 4 métodos.
-Un método para agregar canciones mediante una tupla con su nombre, y duración(add_songs)
-Un método para reproducir solo una canción(play_song)
-Un método para reproducir todas las canciones dentro de la playlist
-Y un método para visualizar todas las canciones dentro de la playlist(all_songs)

import time

class ListQueue:
    def __init__(self):
        self.items = []
        self.size = 0

    def enqueue(self, data):
        self.items.insert(0, data)
        self.size += 1

    def dequeue(self):
        if self.size <= 0:
            return 0
        data = self.items.pop()
        self.size -= 1
        return data
        

class MusicPlaylist(ListQueue):
    def __init__(self):
        super().__init__()

    def add_songs(self, song: tuple):
        self.enqueue(song)

    def play_song(self):
        song = self.dequeue()
        if song:
            print(f'Playing: {song[0]} for {song[1]} min')
            time.sleep(song[1])
        else:
            print('There are no more songs')

    def play_songs(self):
        while self.items:
            self.play_song()

    def all_songs(self):
        if self.items:
            print('The songs in the playlist are:')
            for i, song in enumerate(self.items[::-1],start=1):
                print(f'Song {i}: {song[0]}, Time: {song[1]}')
        print(f'There are {self.size} songs')
        return self.size
        



if __name__ == '__main__':
    playlist = MusicPlaylist()

    playlist.add_songs(("REMEMBER", 5.19))
    playlist.add_songs(("comfy vibes", 3.12))
    playlist.add_songs(("Into the blue's", 4.03))
    playlist.add_songs(("E.M.A", 4.16))

    playlist.all_songs()
    print()

    playlist.play_songs()
    print()

    playlist.play_song()
    playlist.all_songs()

Outputs

The songs in the playlist are:
Song 1: REMEMBER, Time: 5.19
Song 2: comfy vibes, Time: 3.12
Song 3: Into the blue's, Time: 4.03
Song 4: E.M.A, Time: 4.16
There are 4 songs

Playing: REMEMBER for 5.19 min
Playing: comfy vibes for 3.12 min
Playing: Into the blue's for 4.03 min
Playing: E.M.A for 4.16 min

There are no more songs
There are 0 songs

Hace tiempo intenté replicar el funcionamiento de “songrequest” de los bots de Twitch y para esto tuve que usar una forma similar (aunque no hice una clase Queue), les dejo el código por si quieren checarlo https://github.com/LuisLiraC/michi-bot-twitch/blob/master/music_player.py 😬

Terminado !!!
Use una estrucutra de DoubleWayNodes para hacer el Queue, me parece que estan hechos los DoubleWayNodes para estos tipos de usos, sencillos, rápidos y fácil de usar e implementar.
Ademas del metodo de agregar y “reproducir” canciones, agrege uno para poner en random la playlist, agregando los nodos al head o al tail.

#!/usr/bin/python3

from random import randint

class DoubleNode ():
    def __init__ (self, data=None, next_node=None, prev_node=None):
        self.data = data
        self.next = next_node
        self.prev = prev_node

class Playlist ():
    def __init__ (self):
        self.head = None
        self.tail = None
        self.count = 0

    def __iter__ (self):
        current_node = self.head

        for i in range(self.count):
            node = current_node
            
            try:
                current_node = current_node.next
            except AttributeError:
                current_node = None

            yield node

    def __str__ (self):
        node_list = []

        for node in self:
            node_list.append(node.data)

        return str(node_list)

    def __init_linked_list (self, node):
        self.head = node
        self.tail = node

    def __delete_all_nodes (self):
        self.head = None
        self.tail = None
        self.count = 0

    def __add_node_to_head (self, node):
        if self.head is None:
            self.__init_linked_list(node)
            return 

        node.next = self.head
        self.head.prev = node
        self.head = node
    
    def __add_node_to_tail (self, node):
        if self.tail is None:
            self.__init_linked_list(node)
            return 

        node.prev = self.tail
        self.tail.next = node
        self.tail = node

    def __pop_node_in_head (self):
        if self.head is None or self.count <= 0:
            return None

        deleted_node = self.head

        try:
            self.head.next.prev = None
            self.head = self.head.next
        except AttributeError:
            pass

        return deleted_node

    def __pop_node_in_tail (self):
        if self.tail is None or self.count <= 0:
            return None

        deleted_node = self.tail

        try:
            self.tail.prev.next = None
            self.tail = self.tail.prev
        except AttributeError:
            pass

        return deleted_node
 
    def add_song (self, song_name):
        song_node = DoubleNode(song_name)

        self.__add_node_to_head(song_node)
        self.count += 1

    def play_next_song (self):
        self.__pop_node_in_tail()
        self.count -= 1

    def shuffle_playlist (self):
        node_list = []

        for node in self:
            node_list.append(node)
        
        self.__delete_all_nodes()

        for node in node_list:
            random_num = randint(0, 100)

            if random_num >= 50:
                self.__add_node_to_head(node)
            else:
                self.__add_node_to_tail(node)

            self.count += 1

        return self.head.data

if __name__ == "__main__":
    MusicPlaylist = Playlist()

    for i in range(10):
        MusicPlaylist.add_song(f"song_{i}")

    print(str(MusicPlaylist))

    MusicPlaylist.shuffle_playlist()

    print(str(MusicPlaylist))
  • Para resolver el reto cree una clase canción en la cual el usuario agrega el nombre, el cantante, el tiempo y en cualquier caso si canta con alguien más (ft).
  • Luego desarrolle una clase PlayList basada en nodos, ya que es mi forma de datos favorita de momento.
  • Tiene métodos para reproducir, agregar, buscar y reproducir, y reproducir toda la playlist sin eliminarla.

Mi GitHub del código: Python Playlist

No puedo creer todo lo que he aprendido en tan poco tiempo 🤩

Esta es mi solución:

class Playlist:
    def __init__(self):
        self.canciones = []
        self.lista_canciones = 0
    
    def insertar_cancion(self,data):
        self.canciones.insert(0,data)
        self.lista_canciones += 1

    def reproducir_cancion(self):
        cancion = self.canciones.pop()
        self.lista_canciones -= 1
        return cancion
    
    def lista_canciones_completas(self):
        play_list_completo = self.lista_canciones

        for item in range(play_list_completo):
            print(self.canciones[item])


lista = Playlist()
lista.insertar_cancion("Hey Jude")
lista.insertar_cancion("Yellow Submarine")
lista.insertar_cancion("Let it be")

print("Cancion que se esta reproduciendo en el momento: ")
print(lista.reproducir_cancion())
print("Canciones que quedan en la lista de reproducción ")
lista.lista_canciones_completas()

Print playlist:

Add to queue (Spotify):

If neccesary add in node_based_queue:

```js # Simulador de playlist musical # Este programa simula una cola de reproducción de canciones con títulos y duraciones aleatorias. # Importar librerías from random import randint # Para generar duraciones aleatorias de canciones from time import sleep # Para simular el tiempo de reproducción de cada canción # Clase Node: Representa un nodo individual en la cola class Node: def __init__(self, data): self.data = data # Datos almacenados en el nodo (en este caso, un objeto Track) self.next = None # Enlace al siguiente nodo en la cola # Clase Queue: Implementación básica de una cola basada en nodos class Queue: def __init__(self): self.front = None # Apuntador al inicio de la cola self.rear = None # Apuntador al final de la cola self._count = 0 # Contador interno de elementos en la cola # Método para agregar un elemento al final de la cola def enqueue(self, item): new_node = Node(item) # Crear un nuevo nodo con el item if self.rear is None: # Si la cola está vacía self.front = self.rear = new_node else: # Si ya hay elementos, añadir al final self.rear.next = new_node self.rear = new_node self._count += 1 # Incrementar el contador de elementos # Método para eliminar y devolver el elemento del inicio de la cola def dequeue(self): if self.front is None: # Si la cola está vacía, no hay nada que devolver return None temp = self.front # Guardar el nodo del inicio self.front = self.front.next # Mover el inicio al siguiente nodo if self.front is None: # Si la cola queda vacía, ajustar el final self.rear = None self._count -= 1 # Decrementar el contador de elementos return temp.data # Devolver los datos del nodo eliminado # Propiedad para obtener la cantidad de elementos en la cola @property def count(self): return self._count # Retornar el número de elementos # Método para verificar si la cola está vacía def is_empty(self): return self.front is None # True si no hay elementos # Clase Track: Representa una canción con título y duración class Track: def __init__(self, title=None): self.title = title # Título de la canción self.length = randint(5, 6) # Duración aleatoria entre 5 y 6 segundos (simulando minutos) def __str__(self): return f"{self.title}" # Representación en cadena del título de la canción # Clase MediaPlayerQueue: Cola de reproducción que hereda de Queue class MediaPlayerQueue(Queue): def __init__(self): super().__init__() # Inicializar la clase padre (Queue) # Método para agregar una canción a la cola de reproducción def add_track(self, track): self.enqueue(track) # Usar enqueue de la clase padre para agregar la canción # Método para reproducir todas las canciones en la cola def play(self): # Mostrar la cantidad de canciones en la cola antes de reproducir print(f"Total tracks in queue: {self.count}") # Reproducir mientras haya canciones en la cola while not self.is_empty(): # Seguir hasta que la cola esté vacía # Obtener la canción actual sacándola de la cola current_track = self.dequeue() # Mostrar qué canción se está reproduciendo print(f"Now playing: {current_track}") # Simular la duración de la canción con una pausa sleep(current_track.length) # Instanciar la cola de reproducción media_player = MediaPlayerQueue() # Agregar canciones a la cola de reproducción media_player.add_track(Track("The Beatles - Let It Be")) media_player.add_track(Track("Queen - Bohemian Rhapsody")) media_player.add_track(Track("Lynyrd Skynyrd - Sweet Home Alabama")) # Reproducir la cola de reproducción media_player.play() ```*# Simulador de playlist musical# Este programa simula una cola de reproducción de canciones con títulos y duraciones aleatorias.* *# Importar librerías*from random import randint  *# Para generar duraciones aleatorias de canciones*from time import sleep      *# Para simular el tiempo de reproducción de cada canción* *# Clase Node: Representa un nodo individual en la cola*class Node:    def \_\_init\_\_(self, data):        self.data = data       *# Datos almacenados en el nodo (en este caso, un objeto Track)*        self.next = None       *# Enlace al siguiente nodo en la cola* *# Clase Queue: Implementación básica de una cola basada en nodos*class Queue:    def \_\_init\_\_(self):        self.front = None      *# Apuntador al inicio de la cola*        self.rear = None       *# Apuntador al final de la cola*        self.\_count = 0        *# Contador interno de elementos en la cola*     *# Método para agregar un elemento al final de la cola*    def enqueue(self, item):        new\_node = Node(item)  *# Crear un nuevo nodo con el item*        if self.rear is None:  *# Si la cola está vacía*            self.front = self.rear = new\_node        else:                  *# Si ya hay elementos, añadir al final*            self.rear.next = new\_node            self.rear = new\_node        self.\_count += 1       *# Incrementar el contador de elementos*     *# Método para eliminar y devolver el elemento del inicio de la cola*    def dequeue(self):        if self.front is None: *# Si la cola está vacía, no hay nada que devolver*            return None        temp = self.front      *# Guardar el nodo del inicio*        self.front = self.front.next  *# Mover el inicio al siguiente nodo*        if self.front is None: *# Si la cola queda vacía, ajustar el final*            self.rear = None        self.\_count -= 1       *# Decrementar el contador de elementos*        return temp.data       *# Devolver los datos del nodo eliminado*     *# Propiedad para obtener la cantidad de elementos en la cola*    @property    def count(self):        return self.\_count     *# Retornar el número de elementos*     *# Método para verificar si la cola está vacía*    def is\_empty(self):        return self.front is None  *# True si no hay elementos* *# Clase Track: Representa una canción con título y duración*class Track:    def \_\_init\_\_(self, title=None):        self.title = title                *# Título de la canción*        self.length = randint(5, 6)       *# Duración aleatoria entre 5 y 6 segundos (simulando minutos)*     def \_\_str\_\_(self):        return f"{self.title}"            *# Representación en cadena del título de la canción* *# Clase MediaPlayerQueue: Cola de reproducción que hereda de Queue*class MediaPlayerQueue(Queue):    def \_\_init\_\_(self):        super().\_\_init\_\_()                *# Inicializar la clase padre (Queue)*     *# Método para agregar una canción a la cola de reproducción*    def add\_track(self, track):        self.enqueue(track)               *# Usar enqueue de la clase padre para agregar la canción*     *# Método para reproducir todas las canciones en la cola*    def play(self):        *# Mostrar la cantidad de canciones en la cola antes de reproducir*        print(f"Total tracks in queue: {self.count}")         *# Reproducir mientras haya canciones en la cola*        while not self.is\_empty():        *# Seguir hasta que la cola esté vacía*            *# Obtener la canción actual sacándola de la cola*            current\_track = self.dequeue()                        *# Mostrar qué canción se está reproduciendo*            print(f"Now playing: {current\_track}")                        *# Simular la duración de la canción con una pausa*            sleep(current\_track.length) *# Instanciar la cola de reproducción*media\_player = MediaPlayerQueue() *# Agregar canciones a la cola de reproducción*media\_player.add\_track(Track("The Beatles - Let It Be"))media\_player.add\_track(Track("Queen - Bohemian Rhapsody"))media\_player.add\_track(Track("Lynyrd Skynyrd - Sweet Home Alabama")) *# Reproducir la cola de reproducción*media\_player.play()
reto cumplido ```python from time import sleep class Node: def __init__(self, data, child=None, parent=None): self.data = data self.child:Node = child self.parent:Node = parent def __repr__(self): if isinstance(self.child, Node): return f"<Node({self.data}) {hex(id(self))}> -> Node({self.child.data})" else: return f"<Node({self.data}) {hex(id(self))}> -> {self.child}" def __str__(self): if isinstance(self.child, Node): return f"Node({self.data}) -> {self.child.__str__()}" else: return f"Node({self.data}) -> {self.child}" def link_child(self, node): """ tanto mi nodo hijo como tu nodo padre se relacionaran """ self.child = node node.parent = self def link_parent(self, node): """ tanto mi nodo padre como tu nodo hijo se relacionaran """ self.parent = node node.child = self def unlink_child(self): """ tanto mi nodo padre como tu nodo hijo, rompen relacion y te lo devuelvo """ child = self.child child.parent = None self.child = None return child def unlink_parent(self): """ tanto mi nodo padre como tu nodo hijo, rompen relacion y te lo devuelvo """ parent = self.parent parent.child = None self.parent = None return parent class Queue: def __init__(self): self.front:Node = None #head self.rear:Node = None #tail self.size = 0 def __repr__(self): return f"<Queue({self.size}) {hex(id(self))}>" def __str__(self): if self.front: return self.front.__str__() else: return "None" def __iter__(self): probe = self.front while probe: yield probe probe = probe.child def is_empty(self): return not(self.front and self.size > 0) def enqueue(self, data): """ agrego un nuevo elemento al final de la queue """ new_node = Node(data) if self.rear: self.rear.link_child(new_node) else: self.front = self.rear = new_node self.rear = new_node self.size += 1 def dequeue(self): """ devuelvo el primer elemento agregado """ if self.front == None: return None remove_item = self.front if remove_item.child: self.front = remove_item.unlink_child() else: self.front = self.rear = None self.size -= 1 return remove_item.data class Song: def __init__(self, name:str, time:int=0): self.name = name self.time = time def __repr__(self): return f"<Song({self.name}) {hex(id(self))}>" def __str__(self): return f"cancion: {self.name}\n tiempo: {self.time} s" def minutes(self): minutos = self.time // 60 segundos_restantes = self.time % 60 return minutos, segundos_restantes playlist = Queue() playlist.enqueue(Song('Sebastián Yatra, Dalmata - Sutra', 3*60 + 36)) playlist.enqueue(Song('Sebastián Yatra - Traicionera', 4*60 + 2)) playlist.enqueue(Song('Reik, Maluma - Amigos Con Derechos', 4*60 + 49)) playlist.enqueue(Song('Cali Y El Dandee - Por Fin Te Encontré ft. Juan Magan, Sebastian Yatra', 4*60 + 43)) playlist.enqueue(Song('Joey Montana - Moribundo ft. De La Ghetto', 4*60 + 5)) def play(): while not playlist.is_empty(): song:Song = playlist.dequeue() min, seg = song.minutes() print(f"Reproduciendo({min}m {seg}s): {song.name}") sleep(song.time) play() ```
Mi solucion al reto 🤯▶️ (Añadir en el header # -\*- coding: utf-8 -\*- para mostrar caracteres especiales como el simbolo de play cuando se esta reproduciendo una canción) ```python import time class Song(): def __init__(self, name, artist, next=None, prev=None): self.name = name self.artist = artist self.next = next self.prev = prev def show(self): title = (self.name + " - " + self.artist) return(title) class Playlist(): def __init__(self): self.head = None self.tail = None self.size = 0 def add_song(self, name, artist): song = Song(name, artist) if self.head == None: self.head = song self.tail = song else: song.prev = self.tail self.tail.next = song self.tail = song self.size += 1 def quit_song(self): current = self.head if self.size < 1: print("The playlist is empty") elif self.size == 1: self.head = None self.tail = None self.size -= 1 print(current.show() + " was deleted") return current elif self.size > 1: self.head = self.head.next self.head.prev = None self.size -= 1 print(current.show() + " was deleted") return current def play(self): i = self.size played = self.head while i > 0: print("▶ " + played.show()) played = played.next i -= 1 time.sleep(2) ```import time class Song():    def \_\_init\_\_(*self*, *name*, *artist*, *next*=None, *prev*=None):        *self*.name = *name*        *self*.artist = *artist*        *self*.next = *next*        *self*.prev = *prev*        def show(*self*):        title = (*self*.name + " - " + *self*.artist)        return(title) class Playlist():    def \_\_init\_\_(*self*):        *self*.head = None        *self*.tail = None        *self*.size = 0     def add\_song(*self*, *name*, *artist*):        song = Song(*name*, *artist*)        if *self*.head == None:            *self*.head = song            *self*.tail = song        else:            song.prev = *self*.tail            *self*.tail.next = song            *self*.tail = song                *self*.size += 1     def quit\_song(*self*):        current = *self*.head        if *self*.size < 1:            print("The playlist is empty")        elif *self*.size == 1:            *self*.head = None            *self*.tail = None            *self*.size -= 1            print(current.show() + " was deleted")            return current        elif *self*.size > 1:            *self*.head = *self*.head.next            *self*.head.prev = None            *self*.size -= 1            print(current.show() + " was deleted")            return current            def play(*self*):        i = *self*.size        played = *self*.head        while i > 0:            print("▶ " + played.show())            played = played.next            i -= 1            time.sleep(2)
Buen dia, resultado en el repositorio de GitHub. [enter link description here](https://github.com/brunomaldonado/musixmatchAPI) Gran parte del resultado fue… ![]()![](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExNTJqYzh2eTNhN28ycnF6d3Rka3I0dmRydjQybHMwa2R0amQ3amVrNyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/kDl49vBQgeMFtdhVqE/giphy.gif) ![](https://static.platzi.com/media/user_upload/Screenshot%202024-07-19%20at%2011.09.36AM-d9888402-8ce2-4abd-a094-799d5c9aaa10.jpg) ![](https://static.platzi.com/media/user_upload/Screenshot%202024-07-19%20at%2011.40.26AM-d29f8324-85fb-46a8-86df-f93a996c14c9.jpg) ![](https://static.platzi.com/media/user_upload/Screenshot%202024-07-19%20at%2011.11.45AM-754e08b5-c770-457e-8644-e415d6e89da5.jpg)

reto de crear la playlist

Mi solución al reto

from colas_queue import ListQueue

class Song:
    def __init__(self, title, artist, duration):
        self.title = title
        self.artist = artist
        self.duration = duration

    def __str__(self):
        return f"{self.title} - {self.artist}: {self.duration}"

class Playlist:
    def __init__(self):
        self.queue = ListQueue()

    def add_song(self, song):
        self.queue.enqueue(song)

    def show_playlist(self):
        print("Playlist:")
        for song in range(self.queue.size):
            print(f"{self.queue.size - song}. {self.queue.items[song]}")

    def play(self):
        while self.queue.size > 0:
            print(f"Playing: {self.queue.dequeue()}")

playlist = Playlist()

playlist.add_song(Song("Tren al Sur", "Los prisioneros", "2:51"))
playlist.add_song(Song("La voz de los 80", "Los prisioneros", "4:16"))
playlist.add_song(Song("Perfecta", "Miranda", "3:01"))
playlist.add_song(Song("Quieren Dinero", "Los prisioneros", "2:55"))
playlist.add_song(Song("Eligiendo una reina", "Los chanchos en Piedra", "3:19"))
playlist.add_song(Song("Mateo", "Tronic", "1:55"))

playlist.show_playlist()

playlist.play()

playlist.show_playlist()
Este es mi trabajo: from random import randint from time import sleep from node\_based\_queue import Queue class Track: def \_\_init\_\_(self, title=None): self.title = title self.length = randint(1, 10) class MediaPlayer(Queue): def \_\_init\_\_(self): super(MediaPlayer, self).\_\_init\_\_() def add\_track(self, track): self.enqueue(track) def play(self): print(f"count: {self.count}") while self.count > 0 and self.head is not None: current\_track\_node = self.dequeue() current\_track = current\_track\_node.title # Acceder al título de la pista print(f"Now playing: {current\_track}") sleep(current\_track\_node.length) track1 = Track("Highway to Hell") track2 = Track("go") track3 = Track("Light years") track4 = Track("The Great Gatsby") track5 = Track("Breath me") track6 = Track("Los pollitos") media\_player = MediaPlayer() media\_player.add\_track(track1) media\_player.add\_track(track2) media\_player.add\_track(track3) media\_player.add\_track(track4) media\_player.add\_track(track5) media\_player.add\_track(track6) media\_player.play() resultados count: 6 Now playing: Highway to Hell Now playing: go Now playing: Light years Now playing: The Great Gatsby Now playing: Breath me Now playing: Los pollitos \~/python103$

Hice un queue basado en listas 😬 les puse nombres a las canciones y toda la cosa. Aclaración: ya sé que es un poco raro poner tantos comentarios, los pongo para saber bien lo que estoy haciendo. Cuando tenga más práctica la idea es colocar los menos posibles. Heres the code:

Aquí mi humilde código:

songs = [
    {
        'name': 'song1',
        'duration': '3:00',
        'artist': 'artist1',
        'album': 'album1',
    },
    {
        'name': 'song2',
        'duration': '3:00',
        'artist': 'artist2',
        'album': 'album2',
    },
    {
        'name': 'song3',
        'duration': '3:00',
        'artist': 'artist3',
        'album': 'album3',
    },
    {
        'name': 'song4',
        'duration': '3:00',
        'artist': 'artist4',
        'album': 'album4',
    },
    {
        'name': 'song5',
        'duration': '3:00',
        'artist': 'artist5',
        'album': 'album5',
    }
]

class PlayList:
    def __init__(self, name):
        self.queue = []
        self.history = []
        self.name = name
        self.size = 0

    def add_song(self, song):
        self.queue.insert(0, song)
        self.size += 1

    def playing_song(self):
        if not self.queue:
            print("Queue is empty.")
            return None
        song = self.queue.pop()
        print("Now playing:", song['name'], '-', song['artist'])
        self.history.append(song)
        self.size -= 1
        return song
    
    def play_previous_song(self):
        if not self.history:
            print("History is empty.")
            return None
        song = self.history.pop()
        self.queue.append(song)
        self.size += 1
        return song
    
    def play_queue(self):
        if not self.queue:
            print("Queue is empty.")
            return
        for song in self.queue:
            print(song['name'], '-', song['artist'])
    
    def remove_song(self, song):
        if song in self.queue:
            self.queue.remove(song)
            self.size -= 1
        else:
            print("Song not found in the queue.")
class Queue:
    def __init__(self):
        self.items = []

    def is_empty(self):
        return len(self.items) == 0

    def enqueue(self, item):
        self.items.append(item)

    def dequeue(self):
        if self.is_empty():
            raise IndexError("Queue is empty")
        return self.items.pop(0)

    def front(self):
        if self.is_empty():
            raise IndexError("Queue is empty")
        return self.items[0]

    def size(self):
        return len(self.items)


class MusicPlaylist:
    def __init__(self):
        self.playlist = Queue()

    def add_songs(self, songs):
        for song in songs:
            self.playlist.enqueue(song)

    def play_song(self):
        if self.playlist.is_empty():
            print("No songs in the playlist")
        else:
            song = self.playlist.dequeue()
            print("Now playing:", song[0])

    def play_all_songs(self):
        if self.playlist.is_empty():
            print("No songs in the playlist")
        else:
            print("Playing all songs:")
            while not self.playlist.is_empty():
                song = self.playlist.dequeue()
                print(song[0])

    def all_songs(self):
        if self.playlist.is_empty():
            print("No songs in the playlist")
        else:
            print("Songs in the playlist:")
            for song in self.playlist.items:
                print(song[0])

'''
En esta implementación, la clase Queuerepresenta la estructura de cola basada en listas.
Mientras que la clase MusicPlaylist utiliza la cola para simular la lista de reproducción musical.

El método add_songs(songs)recibe una tupla de canciones y las agrega a la lista de reproducción utilizando el método enqueuede la cola.
El método play_song()reproducir la canción en la parte frontal de la lista de reproducción utilizando el método dequeuede la cola.
El método play_all_songs()para reproducir todas las canciones en la lista de reproducción utilizando un bucle whilehasta que la lista de reproducción esté vacía.
El método all_songs()muestra todas las canciones en la lista de reproducción utilizando el atributo itemsde la cola.
Ten en cuenta que las canciones se reproducen en el orden en que se agregan a la lista de reproducción, siguiendo el principio FIFO (First In, First Out).

Espero que esto te ayude a desarrollar el simulador de playlist musical utilizando la 
estructura Queue basada en listas en Python. Si tienes más preguntas, no dudes en preguntar.'''


#Implementacón 

# Crear una instancia de la clase MusicPlaylist
my_playlist = MusicPlaylist()

# Agregar canciones a la playlist
songs = [("Song 1", "3:45"), ("Song 2", "4:20"), ("Song 3", "2:55")]
my_playlist.add_songs(songs)

# Visualizar todas las canciones en la playlist
my_playlist.all_songs()

# Reproducir una canción
my_playlist.play_song()

# Reproducir todas las canciones en la playlist
my_playlist.play_all_songs()

Preferí user el tiempo para conocer el modulo Queue de Python
https://docs.python.org/3/library/queue.html
.
Este usa doubly-linked list (O(1) time).
.
Metodos agregados:

  • __len__
  • __str__
  • addSong
  • playSong
  • skipsong
  • removesong
  • sufflePlaylist

esta fue la forma en que resolví sin ver la explicación del profe

class PlayerPlaylist:
    def __init__(self):
        self.songs = []
        self.size = 0

    def enqueue(self, song):
        self.songs.insert(0, song)
        self.size += 1

    def edqueue(self):
        song = self.songs.pop()
        self.size -= 1
        return song
    
    def player_song(self):
        for song in range(self.songs):
            print(f"reproduciendo {song}")

    def clear(self):
        self.songs = []
        self.size = 0

Mi solucion al reto, basado en nodos:

class Nodes:

    def __init__(self, data, link=None, author= None, next=None, previous=None):
        self.data = data  #nombre de la canción
        self.link = link
        self.author = author
        self.next = next
        self.previous = previous
from nodes import Nodes
import time

class PlayList:
    
    def __init__(self):
        self.size = 0
        self.head = None
        self.tail = None

    def append_song(self, data, link, author):
        new_node = Nodes(data, link, author)
        if self.head == None:
            self.head = new_node
            self.tail = new_node
            self.size += 1
        else:
            new_node.previous = self.tail
            self.tail.next = new_node
            self.tail = new_node
            self.size += 1

    def play(self):
        probe = self.head
        while probe:
            print(f"Estas escuchando: \033[31m {probe.data} \033[0m del artista \033[31m{probe.author}: \033[0m\nEl link de la canción es: {probe.link}")
            probe = probe.next
            time.sleep(3)

Y el archivo de prueba:

from sim_de_playlist_musical import PlayList

def run():
    musica = PlayList()
    musica.append_song("Dime qué paso", "https://music.youtube.com/watch?v=xNVOD5MAvPo&feature=sharehttps://music.youtube.com/watch?v=xNVOD5MAvPo&feature=share", "latin brothers")
    musica.append_song("La llorona", "https://music.youtube.com/watch?v=dwc1jImPzoA&feature=share", "Carmen Goett")
    musica.append_song("Historia de amor", "https://music.youtube.com/watch?v=W-vAUvwUK2s&feature=share", "Silvio Brito y Osmel Meriño")

    musica.play()


if __name__ == "__main__":
    run()

😄 Yo lo pensé así:

# Mi solucion al reto de crear una playlist con queues
class Node():
    def __init__(self, data, next=None):
        self.data = data
        self.next = next


class Queue:
    def __init__(self, max_size = None):
        self.head = None
        self.tail = None
        self.max_size = max_size
        self.size = 0
    
    def is_empty(self):
        return self.size == 0

    def get_size(self):
        return self.size
    
    def has_space(self):
        if self.max_size != None:
            return self.max_size > self.get_size
        else:
            return True
    
    def add_song(self, song):
        if self.has_space():
            song_to_add = Node(song)
            print(f'{song} added to the playlist.')
            if self.is_empty():
                self.head = song_to_add
                self.tail = song_to_add
            else:
                self.tail.next = song_to_add
                self.tail = song_to_add
            self.size += 1
        else:
            print("Sorry, no more space.")
    
    def play_song(self):
        if self.is_empty() is False:
            song_to_play = self.head
            print(f'Playing {song_to_play.data}.')
            if self.size == 1:
                self.head = None
                self.tail = None
            else:
                self.head = self.head.next
                self.size -= 1
        else:
            print('Empty playlist')
            return 
        return song_to_play.data

        

my_playlist = Queue()
my_playlist.add_song("Salvame, RBD")
my_playlist.play_song()
class Node:
    def __init__(self, data, next, previous):
        self.data = data
        self.next = next
        self.previous = previous

class PlayList:
    def __init__(self):
        self.head = None
        self.tail = None
        self.count = 0

    def add_song(self, data):
        node = Node(data, None, None)
        
        if self.head is None:
            self.head = node
            self.tail = node
        else:
            node.previous = self.tail
            self.tail.next = node
            self.tail = node
            
        self.count += 1

    def play(self):
        current = self.head

        if self.count == 1:
            self.head = None
            self.tail = None
        elif self.count > 1:
            self.head = self.head.next
            self.head.previous = None
            
        self.count -= 1

        return current.data
'''reto simulador playlist musical'''

'''restricciones:
Utiliza Queues
añade dos metodos, uno para añadir canciones, y otro para reproducirlas
se reproducen FIFO'''


class ListQueue:
    def __init__(self):
        self.playlist = []
        self.size_playlist = 0

    def agregar_cancion(self, cancion):
        self.playlist.append(cancion)
        self.size_playlist += 1
        return f'Se agrego a la lista "{cancion}"'
    
    def eliminar_cancion(self):
        data = self.playlist.pop(0)
        self.size_playlist -= 1
        return f'Se elimino de la lista "{data}"'
    
    def reproducir_cancion(self, cancion_reproducir):
        if self.size_playlist >= cancion_reproducir:
            print(f'Se esta reproduciendo la cancion {self.playlist[cancion_reproducir - 1]}')
        else:
            print('Ejecute nuevamente y elija un numero de cancion que si este en la playlist')
        
    def reproducir_playlist(self):
        print('Ha seleccionado la opcion de reproducir todo el playlist')
        for cancion in self.playlist:
            print(f'Se esta reproduciendo "{cancion}"')
        print('Playlist finalizada')
            
        
    
if __name__ == '__main__':
    playlist = ListQueue()
    playlist.agregar_cancion('Epico - Cancerbero')
    playlist.agregar_cancion('Mundo de piedra - Cancerbero')
    playlist.agregar_cancion('De sol a sol - Salserin')
    playlist.agregar_cancion('Señora de las cuatro decadas - Ricardo arjona')
    playlist.agregar_cancion('Animals - Maroon Five')
    print(playlist.playlist)
    print(playlist.size_playlist)
    print(playlist.eliminar_cancion())
    print(playlist.size_playlist)
    print(playlist.playlist)
    playlist.reproducir_cancion(4)
    playlist.reproducir_playlist()

Utilicé node_based_queue para realizar el reto realmente solo le cambie el nombre a las clases y a los metodos 😉 si estoy mal alguien que me corrija por favor o si hizo falta algo

class Song():
    def __init__(self, data, next=None, prev=None):
        self.data = data
        self.next = next
        self.prev = prev

class Player:
    def __init__(self):
        self.head = None
        self.tail = None
        self.count = 0

    def add_song(self, data):
        new_song = Song(data, None, None)
        if self.head is None:
            self.head = new_song
            self.tail = self.head
        else:
            new_song.prev = self.tail
            self.tail.next = new_song
            self.tail = new_song

        self.count += 1

    def play_song(self):
        current = self.head
        try:
            if self.count == 1:
                self.count -= 1
                self.head = None
                self.tail = None
            elif self.count > 1:
                self.head = self.head.next
                self.tail.prev = None
                self.count -= 1
            return current.data
        except AttributeError:
            print('There are no songs in the queue')
            

from reto_playlist import Player

def run():
    music = Player()
    music.add_song('Cancion 1')
    music.add_song('Cancion 2')
    music.add_song('Cancion 3')
    music.add_song('Cancion 4')

if __name__ == '__main__':
    run()

SINGS PLAYER

class Node:
def init(self, sing=None, previous=None, next=None):
self.sing = sing
self.previous = previous
self.next = next

class Simulator():
def init(self):
self.head = None
self.tail = None
self.temas = 0

def add_sing(self, tema):
    sing = Node(tema)
    if self. head is None:
        self.head = sing
        self.tail = self.head
    else:
        sing.previous = self.tail
        self.tail.next = sing
        self.tail = sing
    self.temas += 1

def play(self):
    if self.temas > 0:
        if self.head.next != None:
            probe = self.head
            self.head = self.head.next
            self.head.previous = None
        else:
            probe = self.head
            self.head = None
            self.tail = None
        self.temas -= 1
        return probe.sing
    else:
        return "There are not more sings"

Aquí se encuentra mi implementacion del challenge, además la implementación de las estructuras de datos vistas

https://github.com/FedericoGomez00/linear_data_structures

hice un primer acercamiento dándole una función real de reproducción con el modulo playsound, la idea es pulirla mas adelante dándole interfaz gráfica y agregando los demás métodos.

#import tkinter as tk
from node_based_queue import Queue
import playsound

playlist = Queue()


class Song():
    def __init__(self,name,place):
        self.name = name
        self.place = place


def add_song(name,place):
    name = Song(name, place)
    playlist.enqueue(name)

def play_list():
    while playlist.head != None:
        print(playlist.head.data.name)
        playsound.playsound(playlist.head.data.place)
        playlist.head = playlist.head.next
        


def run():
    add_song('aries', 'sounds/1 Aries.mp3')
    add_song('tauro', 'sounds/2 Tauro.mp3')
    add_song('geminis', 'sounds/3 Géminis.mp3')
    add_song('cancer', 'sounds/4 Cáncer.mp3')
    
    play_list()




if __name__ == '__main__':
    run()
class TwoWaysNode(object):
    def __init__(self, data = None, next = None, previous = None):
        self.data = data
        self.next = next
        self.previous = previous

class Queue:
    def __init__(self):
        self.head = None
        self.tail = None
        self.count = 0

    def enqueue(self, data):
        new_node = TwoWaysNode(data,None,None)
        if self.head is None:
            self.head = new_node
            self.tail = self.head
        else:
            new_node.previous = self.tail
            self.tail.next = new_node
            self.tail = new_node
        self.count += 1
    
    def dequeue(self):
        current = self.head
        if self.count == 1:
            self.count -=1
            self.head = None
            self.tail = None
        elif self.count > 1:
            self.head = self.head.next
            self.head.previous = None
            self.count -=1
        else:
            print('The enqueue is empty')
        return current.data

    def list_queue(self):
        current = self.head
        while current != None:
            print(current.data)
            current = current.next
    def reverse_queue(self):
        current = self.tail
        while current != None:
            print(current.data)
            current = current.previous

Les comparto mi solución antes de ver la solución del profe, es muy simple pero quizá le añada otros métodos como:

  • Duración del Playlist
  • Shuffle
  • Repeat of
  • Play next

Pero por el momento esto es lo que construí

"""Module of a playlist class"""
from node_base_queue import Queue_node
import time 


class Playlist():
    """Class to create a queue based on nodes to make a 
        playlist musical.
        """
    def __init__(self):
        self.playlist = Queue_node()

    def add_song(self):
        """Function that ask for a name of a song, artist and duration"""        
        
        name = input("Song name: ")
        artist = input("Artist: ")
        duration = int(input("Duration in seconds: "))

        song_info = {'name':name, 'artist':artist, 'duration':duration}

        self.playlist.enqueue(song_info)
        print("Song added!")


    def play(self):
        """This function will play and dequeue the songs in order FIFO"""
        print("Playing Playlist")
        while self.playlist.head:
            print("----------Playing-------------")
            song_playing = self.playlist.dequeue()
            print(f"Song name: {song_playing['name']}")
            print(f"Artist: {song_playing['artist']}")
            print(f"Duration: {song_playing['duration']}")
            time.sleep(5)
        print("Playlist empty")

Este código es para testear esos 2 métodos

from playlist import Playlist

zoe_playlist = Playlist()
flag = ''
while flag != 'exit':
    zoe_playlist.add_song()
    flag = input("Enter 'exit' to stop adding songs or press 'Enter' to continue:")

zoe_playlist.play()

Y este fue el resultado en la terminal:

╰─ python3 testing_list_based_queue.py
Song name: Poli
Artist: Zoe
Duration in seconds: 180
Song added!
Enter 'exit' to stop adding songs or press 'Enter' to continue
Song name: No me destruyas
Artist: Zoe
Duration in seconds: 240
Song added!
Enter 'exit' to stop adding songs or press 'Enter' to continue
Song name: Via Lactea
Artist: Zoe
Duration in seconds: 240
Song added!
Enter 'exit' to stop adding songs or press 'Enter' to continue
Song name: Reptilectric
Artist: Zoe
Duration in seconds: 230
Song added!
Enter 'exit' to stop adding songs or press 'Enter' to continueexit
Playing Playlist
----------Playing-------------
Song name: Poli
Artist: Zoe
Duration: 180
----------Playing-------------
Song name: No me destruyas
Artist: Zoe
Duration: 240
----------Playing-------------
Song name: Via Lactea
Artist: Zoe
Duration: 240
----------Playing-------------
Song name: Reptilectric
Artist: Zoe
Duration: 230

Esta es mi solución. La clase Track hereda de la clase Nodo que es un Nodo con prev y next

import random
import time
from node import Node


class Track(Node):
    def __init__(self, data, next=None, prev=None) -> None:
        super().__init__(data, next, prev)
        self.duration = random.randint(3, 11)

    def play(self):
        print(f"Playing {self.data} {self.duration}:00 min")
        time.sleep(self.duration)


class Playlist:
    def __init__(self) -> None:
        self.front = None
        self.rear = None
        self.count = 0

    def add_track(self, song_name):
        self.enqueue(song_name)

    def enqueue(self, song_name):
        new_track = Track(song_name)
        if self.count == 0:
            self.front = new_track
            self.rear = new_track
        else:
            new_track.prev = self.rear
            self.rear.next = new_track
            self.rear = new_track
        self.count += 1

    def dequeue(self):
        next_song = self.front
        if self.count <= 1:
            self.front = None
            self.rear = None
            self.count -= 1
        else:
            self.front = self.front.next
            self.front.prev = None
            self.count -= 1
        return next_song

    def play(self):
        current_song = self.dequeue()
        while current_song:
            current_song.play()
            current_song = self.dequeue()


if __name__ == "__main__":
    pl = Playlist()
    pl.add_track("Attack!")
    pl.add_track("Sognare")
    pl.add_track("Demasiado mexicano")
    pl.play()

Holis, decidí utilizar Queue basada en listas.

Cualquier feedback se agradece 💚


Principio del código.

Método añadir una canción.

Métodos de reproducción de canciones, para una o varias canciones a la vez.

Método para mostrar la lista de canciones.

Reto:

class MusicPlayList:
    def __init__(self) -> None:
        self.list = []
        self.size = 0

    def add_song_to_playlist(self, song):
        self.list.insert(0, song)
        self.size += 1

    def play(self):
        song = self.list.pop()
        self.size -= 1
        return f'Reproduciendo {song}'
    
    def next(self):
        return self.play()

    def show_playlist(self):
        songs_count = 0
        for song in self.list:
            print(f'Song {self.size - songs_count} - {song}')
            songs_count += 1

Implementación:

from reto_playlist_queue import MusicPlayList
def run():
    music = MusicPlayList()
    music.add_song_to_playlist('New Shapes, by Charli XCX')
    music.add_song_to_playlist('No Reason by Big Thief')
    music.add_song_to_playlist('Love Me More, by Mitski')
    music.add_song_to_playlist('Tabula Rasa, by Earl Sweatshirt feat. Armand hammer')
    music.add_song_to_playlist('Tears In The Club, by FKA twigs')
    music.add_song_to_playlist('Fanny Girl, by FKA twigs')
    music.add_song_to_playlist('Taking Me Back, by Jack White')

    print('=================================')
    music.show_playlist()
    print('=================================')
    print(music.play())
    print(music.next())
    print('=================================')
    music.show_playlist()
    print(music.play())
    print(music.play())
    print(music.play())
    print('=================================')
    music.show_playlist()
    

if __name__ == '__main__':
    run()

MI solución al reto

import time
import secrets

class Playlist:
    def __init__(self):
        self.songs = []
        self.size = 0

    def validate_playlist(func):
        def wrapper(self):
            if self.size > 0:
                func(self)
            else:
                print('There is no more songs to listen on the playlist')
        return wrapper

    def add_song(self, song: str):
        if isinstance(song, str):
            self.songs.insert(0, song)
            self.size += 1
        else:
            print('Only strings accepted')

    def listen_all_playlist(self):
        while self.size > 0:
            self.listen_song()

    @validate_playlist
    def listen_song(self):
        song = self.songs.pop()
        self.size -= 1
        print(f'Listening {song}...')
        time.sleep(10)

    @validate_playlist
    def shuffle(self):
        song = secrets.choice(self.songs)
        self.songs.remove(song)
        self.size -= 1
        print(f'Listening {song}...')
        time.sleep(10)

Mi solución

class MusicQueue:
    def __init__(self):
        self.inbound_queue=[]
        self.outbound_queue=[]
        self.size=0

    def enqueue(self,song):
        self.inbound_queue.append(song)
        self.size+=1
    
    def dequeue(self):
        if not self.outbound_queue:
            while self.inbound_queue:
                self.outbound_queue.append(self.inbound_queue.pop())
        self.size-=1
        return self.outbound_queue.pop()
    
    def get_size(self):
        return self.size

if __name__ == "__main__":
    list_songs=MusicQueue()
    flag='Y'
    while flag=='Y':
        new_song=str(input("Introduce a new song: "))
        list_songs.enqueue(new_song)
        print("Song inserted successfully")
        flag=str(input("Introduce Y for continue appending songs or N to close and reproduce: "))
    
    if flag=='N':
        for i in range(list_songs.get_size()):
            print(list_songs.dequeue())
        print("Music ended, good luck!")
    else:
        print("Unexpected value, program terminated!")



Mi reto es el siguiente:

class Playlist:
    def __init__(self):
        self.items = []
        self.size = 0

    def add_to_playlist(self, data):
        """Enqueue method"""
        self.items.insert(0, data)
        self.size += 1

    def play_a_song(self):
        """Dequeue method"""
        data = self.items.pop()
        self.size -= 1
        print("Se empieza a reproducir {}".format(data))

    def show_playlist(self):
        total_items = self.size

        counter = self.size

        for song in range(total_items):
            print("{}: {}".format(counter, self.items[song]))
            counter -= 1

    def ask_song(self):
        data = input('¿Qué canción desea añadir a la playlist?')
        print("Añadiendo a la playlist")
        self.add_to_playlist(data=data) 

Código que hice antes de ver la clase:

class TwoWayNode(object):
    def __init__(self, data = None, next = None, previous = None):
        self.data = data
        self.next = next
        self.previous = previous


class Queue:
    def __init__(self):
        self.head = None
        self.tail = None
        self.count = 0


    def addSong(self, song):
        if self.head == None:
            self.head = TwoWayNode(song)
            self.tail = self.head
        else:
            current = self.head
            while current.next != None:
                current = current.next
            current.next = TwoWayNode(song)
            current.next.previous = current
            self.tail = current.next
        self.count += 1


    def playSongs(self):
        current = self.head
        while current != None:
            print(f'Song playing: {current.data} \n')
            current = current.next


La solucion mas simple que no sacrifique elegancia en la que pude pensar

from dataclasses import dataclass


@dataclass
class Song:
    artist: str
    title: str

    def __str__(self) -> str:
        return f"Artist: {self.artist}\nTitle: {self.title}\n"


class Playlist:
    def __init__(self) -> None:
        self.list = []

    def add_song(self, song: Song) -> None:
        self.list.append(song)

    def play(self) -> None:
        song = self.list.pop(0)
        print("=" * 25)
        print("Playing song...")
        print("-" * 25)
        print(song)


if __name__ == "__main__":

    player = Playlist()

    player.add_song(Song("CardiB", "Up"))
    player.add_song(Song("Olivia Rodrigo", "Good 4 U"))
    player.add_song(Song("Arooj Aftab", "Mohabbat"))

    while player.list:
        player.play()

Esta fue una evaluación tipo proyecto que tuve que hacer en mi universidad. Eran 20 puntos sobre el parcial de estructuras lineales de la materia de estructuras de datos. Lo malo es que lo tuve que hacer en C++ 😢

😃
Mi resultado del reto:
github: https://github.com/Valot3/music-player-simulator.git

Esta fue mi solucion al reto

Hice una clase para crear las canciones, estas tienen titulo, artista y album, luego una clase para las queues basadas en listas con un metodo para añadir cada cancion creada, otro metodo que las reproduce (y al reproducirlas las quita de la lista en el orden en que se añadieron, cumpliendo con FIFO)

class Song:
    def __init__(self, artist='', title='', album=''):
        self.artist = artist
        self.title = title
        self.album = album


class Queue:
    def __init__(self):
        self.songs = []
        self.size = 0

    def enqueue(self, song):
        #Se usa insert para que lo agregue al principio
        self.songs.insert(0, song)
        self.size += 1

    def play(self):
        #Al reproducirse una cancion, esta se elimina
        if self.size > 0:
            song = self.songs.pop()
            self.size -= 1
            print(f'Se esta reproduciendo {song.title} de {song.artist}, perteneciente al album {song.album}')
        else:
            print('No hay mas canciones por reproducir')

    def traverse(self):
        total_songs = self.size

        if total_songs > 0:
            print(f'El total de canciones es: {total_songs}')

            for index, song in enumerate(self.songs):
                print(f'La cancion #{index + 1} es: \nArtista:{song.artist}, titulo:{song.title}, album:{song.album}')
        else:
            print('No hay canciones en la lista')


#Asi se veia el output en la terminal

from reto_playlist import Song, Queue
>>> canciones = Queue()
>>> thriller = Song('Michael Jackson', 'Thriller', 'Thriller')
>>> malo_de_ser_bueno = Song('El Cuarteto de Nos', 'Lo Malo De Ser Bueno', 'Porfiado')
>>> in_the_end = Song('Linkin Park', 'In The End', 'Hybrid Theory')
>>> canciones.enqueue(thriller)
>>> canciones.enqueue(malo_de_ser_bueno)
>>> canciones.enqueue(in_the_end)
>>> canciones.traverse()
El total de canciones es: 3
La cancion #1 es: 
Artista:Linkin Park, titulo:In The End, album:Hybrid Theory
La cancion #2 es: 
Artista:El Cuarteto de Nos, titulo:Lo Malo De Ser Bueno, album:Porfiado
La cancion #3 es: 
Artista:Michael Jackson, titulo:Thriller, album:Thriller
>>> canciones.play()
Se esta reproduciendo Thriller de Michael Jackson, perteneciente al album Thriller
>>> canciones.traverse()
El total de canciones es: 2
La cancion #1 es: 
Artista:Linkin Park, titulo:In The End, album:Hybrid Theory
La cancion #2 es: 
Artista:El Cuarteto de Nos, titulo:Lo Malo De Ser Bueno, album:Porfiado