예제 #1
0
def invertir_Pila(pila_a_invertir):
    aux_Pila = Pila()

    while (not pila_a_invertir.pila_vacia()):
        aux_Pila.apilar(pila_a_invertir.desapilar())

    return aux_Pila
예제 #2
0
def insertar_El_Numero_Menor_al_Mayor_En_Pila(obj_Pila_A_Insertar_Numero,
                                              numero):

    obj_Numeros_Mayores_Pila = Pila()

    #Si se ingresa mas de 1 numero entro aqui
    if (not obj_Pila_A_Insertar_Numero.pila_vacia()):

        #Si es mayor lo inserto de una
        if (numero >= obj_Pila_A_Insertar_Numero.elemento_cima()):
            obj_Pila_A_Insertar_Numero.apilar(numero)

        else:

            # Evaluo todos los menores al numero incluyendo los iguales y los apilo
            # En la pila auxiliar obj_Numeros_Mayores_Pila
            # Despues cuando se rompa el bucle doy por hecho que llego a que
            # Numero es mayor al elemento de la cima o que no encontro ninguno

            while ((not obj_Pila_A_Insertar_Numero.pila_vacia())
                   and (numero < obj_Pila_A_Insertar_Numero.elemento_cima())):
                elemento = obj_Pila_A_Insertar_Numero.desapilar()
                obj_Numeros_Mayores_Pila.apilar(elemento)

            obj_Pila_A_Insertar_Numero.apilar(numero)

            #Coloco todos los numeros que eran mayores al numero ingresado
            while (not obj_Numeros_Mayores_Pila.pila_vacia()):
                obj_Pila_A_Insertar_Numero.apilar(
                    obj_Numeros_Mayores_Pila.desapilar())

    else:
        #Si no hay nada le inserto el primer numero esto para cuando se hace el primer bucle
        obj_Pila_A_Insertar_Numero.apilar(numero)
예제 #3
0
def ejercicio_16():
    obj_Pila = Pila()
    obj_Pila2 = Pila()
    obj_Interseccion_Pila = Pila()

    personajes_Star_Wars_EP_V = [
        'Luke Skywalker', 'Han Solo', 'Darth Vader', 'Leia Organa', 'Yoda',
        'Capitán Needan', 'Almirante Ozzel', 'Lando Calrissian'
    ]

    personajes_Star_Wars_EP_VII = [
        'Kylo Ren', 'Rey', 'Han Solo', 'Luke Skywalker', 'C3PO', 'Leia Organa',
        'Chewbacca', '	Poe Dameron'
    ]

    for i in range(0, len(personajes_Star_Wars_EP_V)):
        obj_Pila.apilar(personajes_Star_Wars_EP_V[i])

    for i in range(0, len(personajes_Star_Wars_EP_VII)):
        obj_Pila2.apilar(personajes_Star_Wars_EP_VII[i])

    obj_Interseccion_Pila = get_Interseccion_De_Pilas(obj_Pila, obj_Pila2)

    while (not obj_Interseccion_Pila.pila_vacia()):
        print('El personaje ', obj_Interseccion_Pila.desapilar(),
              ' esta en ambas peliculas')
예제 #4
0
 def dijkstra(self, ver_origen, ver_destino):
     """Algoritmo de Dijkstra para hallar el camino mas corto."""
     no_visitados = HeapMin()
     camino = Pila()
     aux = 0
     while (aux < self.tamanio()):
         vertice = self.inicio.obtener_elemento(ver_origen)
         vertice_aux = self.inicio.obtener_elemento(aux)
         vertice_aux['anterior'] = None
         if (vertice_aux['info'] == vertice['info']):
             no_visitados.arribo([vertice_aux['info'], None], 0)
         else:
             no_visitados.arribo([vertice_aux['info'], None], inf)
         aux += 1
     while (not no_visitados.vacio()):
         dato = no_visitados.atencion()
         camino.apilar(dato)
         pos_aux = self.buscar_vertice(dato[1][0])
         vertice_aux = self.inicio.obtener_elemento(pos_aux)
         aristas = 0
         while (aristas < vertice_aux['aristas'].tamanio()):
             arista = vertice_aux['aristas'].obtener_elemento(aristas)
             pos_heap = no_visitados.busqueda(arista['destino'])
             if (pos_heap is not None
                     and no_visitados.elementos[pos_heap][0] >
                     dato[0] + arista['peso']):
                 no_visitados.elementos[pos_heap][1][1] = dato[1][0]
                 nuevo_peso = dato[0] + arista['peso']
                 no_visitados.cambiar_prioridad(pos_heap, nuevo_peso)
             aristas += 1
     # print(no_visitados.elementos)
     return camino
예제 #5
0
def apilarGenero(cola, genero):
    pila = Pila()
    while (cola.es_vacia() != True):
        pelicula = cola.desencolar()
        if (pelicula.genero == genero):
            pila.apilar(pelicula)
    return pila
예제 #6
0
def ejercicio_24():
    Mat = None
    Vector = None

    obj_Personajes_Marvel_Pila = Pila()
    # MCU = [['Black Widow', 'Avengers Confidential', 'Iron Man: Rise of Technovore', 'Avengers: Infinity War'],
    #        ['Iron Man', 'Iron Man I', 'Iron Man II','Avengers Confidential', 'Iron Man: Rise of Technovore', 'The Invincible Iron Man', 'Avengers: Infinity War'],
    #        ['Hulk', 'Avengers Confidential', 'Hulk vs Thor', 'Avengers: Infinity War'],
    #        ['Hawkeye', 'Avengers Confidential'],
    #        ['Thor', 'Hulk vs Thor', 'Avengers: Infinity War'],
    #        ['Groot', 'Infinity War']
    #        ['Rocket Raccoon', 'Infinity War']]

    MCU = [['Black Widow', 1, 3, 4, 5, 2, 4], ['Rocket Raccoon', 3, 7],
           ['Iron Man', 1, 3, 4, 5, 2, 4, 7, 9], ['Hulk', 9, 3, 4, 6],
           ['Hawkeye', 3], ['Groot', 2], ['Thor', 3, 4, 2, 1]]

    for i in range(0, len(MCU)):
        obj_Personajes_Marvel_Pila.apilar(MCU[i])

    #A
    print('\nPosicion de Groot y Rocket en la pila\n')
    print(
        get_mensaje_Posicion_De_Groot_And_Rocket(
            get_Pos_Groot_And_Roket(obj_Personajes_Marvel_Pila)))

    #B
    print('\nPersonajes que aparecen en mas de 5 peliculas')
    Mat = get_Personajes_Que_Aparecen_En_Mas_De_5_Peliculas_And_La_Cantidad(
        obj_Personajes_Marvel_Pila)

    if ((len(Mat) - 1) > 0):
        for i in range(0, (len(Mat) - 1)):
            print('\nNombre: ', Mat[i][0], '\nTotal Peliculas: ', Mat[i][1])
    else:
        print(
            '\nNingun personaje de MCU en la pila que aparezca en mas de 5 peliculas'
        )

    #C
    print('\nCantidad de peliculas en las que aparece Black Widow')
    print(
        '\n',
        get_Mensaje_Black_Widow(
            get_Cantidad_Peliculas_En_La_Que_Aparece_Black_Widow(
                obj_Personajes_Marvel_Pila)))

    #D
    print('\nPersonajes que empiecen con C, D o G')
    Vector = get_Nombres_Que_Empiezan_Con_C_D_And_G(obj_Personajes_Marvel_Pila)

    if ((len(Vector) - 1) > 0):
        for i in range(0, (len(Vector) - 1)):
            print('\nNombre: ', Vector[i])
    else:
        print(
            '\nNo hay personajes de MCU en la pila que empiecen con C, D o G')


#-------------------------FIN#-------------------------
예제 #7
0
def analizar_secuencia(instrucciones, codificaciones):
    """ Recibe un string con instrucciones y un diccionario que contiene la codificación para algunas instrucciones variables. 
    Devuelve un set de trazos correspondientes al análisis del string, la distancia máxima y la distancia mínima con la que ha de crearse
    el svg.
    """
    coordenada_min = Vector()
    coordenada_max = Vector()

    pila_de_tortugas = Pila()
    pila_de_tortugas.apilar(Tortuga())

    tortuga_tope = pila_de_tortugas.ver_tope()
    profundidad = len(pila_de_tortugas)

    trazos = set()

    for c in instrucciones:
        if c == "[":
            nueva_tortuga = tortuga_tope.clonar()
            pila_de_tortugas.apilar(nueva_tortuga)

            tortuga_tope = pila_de_tortugas.ver_tope()
            profundidad = len(pila_de_tortugas)
        elif c == "]":
            pila_de_tortugas.desapilar()

            tortuga_tope = pila_de_tortugas.ver_tope()
            profundidad = len(pila_de_tortugas)
        elif c == "F":
            ultima_posicion = tortuga_tope.conseguir_posicion()

            tortuga_tope.avanzar(DISTANCIA_BASE *
                                 (FACTOR_EXPANSION**profundidad))

            nueva_posicion = tortuga_tope.conseguir_posicion()

            coordenada_min = calcular_min(coordenada_min, nueva_posicion)
            coordenada_max = calcular_max(coordenada_max, nueva_posicion)

            nuevo_trazo = Trazo(ultima_posicion, nueva_posicion,
                                tortuga_tope.conseguir_grosor(),
                                tortuga_tope.conseguir_color())

            trazos.add(nuevo_trazo)
        elif c == "f":
            tortuga_tope.levantar_pluma()
            tortuga_tope.avanzar(DISTANCIA_BASE *
                                 (FACTOR_EXPANSION**profundidad))
            tortuga_tope.bajar_pluma()
        elif c in "+-|":
            tortuga_tope.girar(codificaciones[c])
        elif c in COLORS:
            tortuga_tope.cambiar_color_pluma(COLORS[c])
        elif c in "0123456789":
            print(c)
            tortuga_tope.cambiar_grosor_pluma(c)

    return trazos, coordenada_min + Vector(-50, -50), coordenada_max + Vector(
        50, 50)
예제 #8
0
def ejercicio_3():
    obj_Pila = Pila()

    for i in range(0, 100):
        num = randint(1, 10)
        obj_Pila.apilar(num)

    obj_Pila = sacar_Ocurrencias_De_La_Pila(obj_Pila)
예제 #9
0
def ejercicio_5():
    obj_Pila = Pila()
    palabra = input('Ingrese una palabra: ')

    for letra in palabra:
        obj_Pila.apilar(letra)

    print(es_Palindromo(obj_Pila))
예제 #10
0
def ejercicio_4():
    obj_Pila = Pila()

    for i in range(0, 20):
        num = randint(1, 10)
        obj_Pila.apilar(num)

    obj_Pila.apilar(102)
    obj_Pila = invertir_Pila(obj_Pila)
예제 #11
0
파일: libros.py 프로젝트: felipedc09/libros
def main():
    libros = Pila()

    for datos in readFile('libros.csv'):
        libros.apilar(Libro(datos[0], datos[1], datos[2]))
    print(libros.items)
    print(len(libros.items))
    print(buscar(libros, 'Anna Llenas'))
    print(len(libros.items))
예제 #12
0
def sacar_Impares_De_Pila(datos_pila):
    aux_Pila = Pila()

    while (not datos_pila.pila_vacia()):
        elemento = datos_pila.desapilar()

        if (elemento % 2 == 0):
            aux_Pila.apilar(elemento)

    return aux_Pila
예제 #13
0
def ejercicio_1():
    obj_pila = Pila()

    for i in range(0, 100):
        num = randint(1, 10)
        obj_pila.apilar(num)

    numero = int(input('ingrese un numero: '))

    print(retornar_Numero_De_Ocurrencias(obj_pila, numero))
예제 #14
0
def generar_lista_partes():
    """"No recibe nada. Devuelve una lista de partes random"""
    partes = {}
    for tipo_parte in TIPOS_PARTE:
        pila_tipo_parte = Pila()
        for _ in range(CANTIDAD_PARTES):
            parte = Parte(tipo_parte)
            agregar_armas_parte(parte)
            pila_tipo_parte.apilar(parte)
        partes[tipo_parte] = pila_tipo_parte
    return partes
예제 #15
0
def movimientos_pista(estado):
    '''Apila los movimientos de la solucion'''
    pistas = Pila()
    try:
        resuelto, solucion = buscar_solucion(estado)
    except:
        return pistas
    if resuelto:
        for movimiento in solucion:
            pistas.apilar(movimiento)
    return pistas
예제 #16
0
def ejercicio_2():
    obj_Pila = Pila()

    for i in range(0, 100):
        num = randint(1, 10)
        obj_Pila.apilar(num)

    obj_Pila = sacar_Impares_De_Pila(obj_Pila)

    for i in range(0, obj_Pila.tamanio()):
        print(obj_Pila.desapilar())
def generar_lista_armas():
	"""Devuelve una lista de armas random."""
	armas={}
	
	tipos_arma=(Arma.MELEE,Arma.RANGO)
	tipos_municion=(Arma.MUNICION_FISICA,Arma.MUNICION_HADRON,Arma.MUNICION_LASER)
	for tipo_arma in tipos_arma:
		pila_tipo_arma=Pila()
		for _ in range(CANTIDAD_DE_ARMAS):
			pila_tipo_arma.apilar(Arma(random.choice(CLASES_ARMA),tipo_arma,random.choice(tipos_municion)))
		armas[tipo_arma]=pila_tipo_arma
	return armas
예제 #18
0
def sacar_Ocurrencias_De_La_Pila(datos_pila):
    aux_Pila = Pila()
    aux_Conjunto = list()

    while (not datos_pila.pila_vacia()):
        elemento = datos_pila.desapilar()

        if (not (elemento in aux_Pila)):
            aux_Conjunto.append(elemento)
            aux_Pila.apilar(elemento)

    return aux_Pila
예제 #19
0
def calculadora_polaca(elementos):
    """ Dada una lista de elementos que representan las componentes de una expresion en
    notacion polaca inversa, evalua dicha expresion.
    Si la expresion esta mal formada, levanta ValueError """

    p = Pila()

    for elemento in elementos:
        print(f"\nDEBUG: entra {elemento}")

        # Intenta convertirlo a numero
        try:
            numero = float(elemento)
            p.apilar(numero)
            print(f"DEBUG: apila {numero}")

        # si no se puede convertir, deberia ser un operando
        except ValueError:
            if elemento not in ('+', '-', '/', '*'):
                raise ValueError("Operando inválido")

            # Si es un operando válido, intenta desapilar y operar
            try:
                a1 = p.desapilar()
                print(f"\nDEBUG: desapila {a1}")
                a2 = p.desapilar()
                print(f"\nDEBUG: desapila {a2}")
            except IndexError:
                raise ValueError("Faltan operandos..")

            if elemento == "+":
                resultado = a2 + a1

            if elemento == "-":
                resultado = a2 - a1

            if elemento == "/":
                resultado = a2 / a1

            if elemento == "*":
                resultado = a2 * a1

            print(f"\nDEBUG: apila {resultado}")
            p.apilar(resultado)

    # Al final el resultado debe ser lo unico en la pila
    resultado = p.desapilar()

    if not p.esta_vacia():
        raise ValueError("Sobran operandos")

    return resultado
예제 #20
0
def _min_seguimientos(grafo, origen, destino):
    distancia, padre = biblioteca.camino_minimo_bfs(grafo, origen, destino)
    if destino not in distancia: return None
    p = Pila()
    aux = destino
    while aux != origen:
        p.apilar(aux)
        aux = padre[aux]
    p.apilar(origen)
    camino = []
    while not p.esta_vacia():
        camino.append(p.desapilar())
    return camino
예제 #21
0
def main():
    niveles = cargar_niveles()
    nivel = 1
    teclas = cargar_teclas()
    juego = setear_juego(niveles, nivel)
    movimientos = Pila()
    soluciones = Pila()
    mensaje = ""
    while gamelib.is_alive():
        gamelib.draw_begin()
        dibujar(juego)
        gamelib.draw_end()
        gamelib.draw_text(mensaje,15,15,anchor="w")
        ev = gamelib.wait(gamelib.EventType.KeyPress)
        if not ev: break

        tecla = ev.key
        
        if tecla in teclas:
            if teclas[tecla] == "REINICIAR":
                juego = reiniciar(juego, niveles, nivel, soluciones)
            elif teclas[tecla] == "SALIR":
                break
            elif teclas[tecla] == "DESHACER": 
                if movimientos.tope:
                    juego = deshacer(movimientos, juego)
            elif teclas[tecla] == "AYUDA":
                if soluciones.esta_vacia():
                    gamelib.draw_text("Pensando...", 15, 15, anchor="w")
                    gamelib.get_events() #Utilizo .get_events() como una especie de mutex para evitar que el usuario interactúe
                    solucion_encontrada, soluciones = solver.buscar_solucion(juego, DIRECCIONES)
                    gamelib.get_events()
                    if solucion_encontrada:
                        mensaje = "Hay pista disponible"
                    else:
                        mensaje = "No hay chance"
                else:
                    movimientos.apilar(juego)
                    juego = soko.mover(juego, soluciones.desapilar())
            else:
                movimientos.apilar(juego)
                juego = soko.mover(juego, DIRECCIONES[teclas[tecla]])

            if tecla and not teclas[tecla] == "AYUDA":
                soluciones = Pila()
                mensaje = ""

            if soko.juego_ganado(juego):
                nivel = nivel + 1
                juego = setear_juego(niveles, nivel)
                movimientos = Pila()
예제 #22
0
def get_Dinero_Total(obj_Pila):
    obj_Aux_Pila = Pila()
    Vector = None
    total = 0.0

    while (not obj_Pila.pila_vacia()):
        Vector = obj_Pila.desapilar()
        obj_Aux_Pila.apilar(Vector)
        total += Vector[1]

    while (not obj_Aux_Pila.pila_vacia()):
        obj_Pila.apilar(obj_Aux_Pila.desapilar())

    return total
예제 #23
0
def get_Total_Personas_Capturadas(obj_Pila):
    obj_Aux_Pila = Pila()
    contador = 0

    while (not obj_Pila.pila_vacia()):
        obj_Aux_Pila.apilar(obj_Pila.desapilar())

        if (obj_Aux_Pila.elemento_cima()[2] != 'Fallo'):
            contador += 1

    while (not obj_Aux_Pila.pila_vacia()):
        obj_Pila.apilar(obj_Aux_Pila.desapilar())

    return contador
def sumar_pilas(pila1, pila2):
    """
    DOC: Completar
    """
    pila1_invertida = Pila()
    pila2_invertida = Pila()
    pila_final = Pila()
    while not pila1.esta_vacia() or not pila2.esta_vacia():
        n1 = pila1.desapilar() if not pila1.esta_vacia() else 0
        n2 = pila2.desapilar() if not pila2.esta_vacia() else 0
        pila1_invertida.apilar(n1) if not n1 == 0 else None
        pila2_invertida.apilar(n2) if not n2 == 0 else None
    while not pila1_invertida.esta_vacia or not pila2_invertida.esta_vacia():
        numero_anterior = pila_final.desapilar(
        ) if not pila_final.esta_vacia() else 0
        n1 = pila1_invertida.desapilar(
        ) if not pila1_invertida.esta_vacia() else 0
        n2 = pila2_invertida.desapilar(
        ) if not pila2_invertida.esta_vacia() else 0
        print(n1, n2)
        suma = n1 + n2
        suma += numero_anterior
        proximo_numero = suma // 10
        suma = suma % 10
        pila_final.apilar(suma)
        pila_final.apilar(proximo_numero) if not proximo_numero == 0 else None

    return pila_final
예제 #25
0
def invertir_Pila_Sin_Perder_Elementos(pila_a_invertir):
    pila_Inversa = Pila()
    aux_Pila = Pila()

    #me da la pila invertida
    while (not pila_a_invertir.pila_vacia()):
        elemento = pila_a_invertir.desapilar()
        pila_Inversa.apilar(elemento)
        aux_Pila.apilar(elemento)

    #le devuelvo los elementos que desapile a la pila original
    while (not aux_Pila.pila_vacia()):
        pila_a_invertir.apilar(aux_Pila.desapilar())

    return pila_Inversa
예제 #26
0
def get_Numero_Mision_Boba_Capturo_A_Han(obj_Pila):
    obj_Aux_Pila = Pila()
    Vector = None
    Mision = 1

    while ((not obj_Pila.pila_vacia())
           and (obj_Pila.elemento_cima()[2] != 'Han Solo')):
        Mision += 1
        Vector = obj_Pila.desapilar()
        obj_Aux_Pila.apilar(Vector)

    while (not obj_Aux_Pila.pila_vacia()):
        obj_Pila.apilar(obj_Aux_Pila.desapilar())

    return Mision
예제 #27
0
def get_Cantidad_Peliculas_En_La_Que_Aparece_Black_Widow(obj_Pila):
    obj_Aux_Pila = Pila()
    cant_peliculas = 0

    while ((not obj_Pila.pila_vacia())
           and (obj_Pila.elemento_cima()[0] != 'Black Widow')):
        obj_Aux_Pila.apilar(obj_Pila.desapilar())

    if (obj_Pila.elemento_cima()[0] == 'Black Widow'):
        cant_peliculas = len(obj_Pila.elemento_cima()) - 1

    while (not obj_Aux_Pila.pila_vacia()):
        obj_Pila.apilar(obj_Aux_Pila.desapilar())

    return cant_peliculas
def reemplazar(pila, valor_nuevo, valor_viejo):

    pila_aux = Pila()

    while not pila.esta_vacia():

        elemento = pila.desapilar()

        if elemento == valor_viejo:
            elemento = valor_nuevo

        pila_aux.apilar(elemento)

    while not pila_aux.esta_vacia():

        pila.apilar(pila_aux.desapilar())
예제 #29
0
def get_Nombres_Que_Empiezan_Con_C_D_And_G(obj_Pila):
    obj_Aux_Pila = Pila()
    indice = 0
    Vector = []

    while (not obj_Pila.pila_vacia()):
        obj_Aux_Pila.apilar(obj_Pila.desapilar())

        if (obj_Aux_Pila.elemento_cima()[0][0] in ['C', 'D', 'G']):
            Vector.insert(indice, obj_Aux_Pila.elemento_cima()[0])
            indice += 1

    while (not obj_Aux_Pila.pila_vacia()):
        obj_Pila.apilar(obj_Aux_Pila.desapilar())

    return Vector
def es_Palindromo(palabra):
    obj_Cola = Cola()
    obj_Pila = Pila()
    letra = None

    for i in range(0, len(palabra)):
        letra = palabra[i].lower()
        obj_Cola.arribo(letra)
        obj_Pila.apilar(letra)

    mitad = len(palabra)//2

    for i in range(0, mitad):
        if(obj_Pila.desapilar() != obj_Cola.atencion()):
            return False

    return True
예제 #31
0
class ColaDeReproduccion:
    """Clase que representa la cola de reproduccion del reproductor. Permite agregar y remover 
    canciones, ademas de poder hacer y deshacer estas acciones. Las canciones se guardan en la 
    cola como objetos de clase Cancion."""

    AGREGADA = 1
    REMOVIDA = 0

    def __init__(self, lista_canciones=[]):
        """ Recibe una lista de objetos de clase Cancion con las canciones que se quieren 
        reproducir."""
        lista = ListaEnlazada()
        for cancion in lista_canciones:
            lista.insert(cancion)
        self.lista_canciones = lista
        self.acciones_tomadas = Pila()
        self.acciones_deshechas = Pila()
        self.actual = 0

    def cancion_actual(self):
        """ Devuelve un objeto de clase Cancion que corresponde a la cancion actual, o None si no 
        hay canciones cargadas en la cola."""
        if self.lista_canciones.esta_vacia():
            return None
        try:
            cancion = self.lista_canciones.get_elemento(self.actual)
        except IndexError:
            return
        return cancion

    def cancion_siguiente(self):
        """ Devuelve un objeto de clase Cancion que corresponde a la cancion siguiente en la cola, 
        o None si no hay mas canciones."""
        if len(self.lista_canciones) < 1:
            return None
        try:
            cancion = self.lista_canciones.get_elemento(self.actual + 1)
            self.actual += 1
        except IndexError:
            return
        return cancion

    def cancion_anterior(self):
        """ Devuelve un objeto de clase Cancion que corresponde a la cancion anterior en la cola, 
        o None si no hay canciones en la misma o la actual es la primera de la cola."""
        if len(self.lista_canciones) < 1:
            return None
        try:
            cancion = self.lista_canciones.get_elemento(self.actual - 1)
            self.actual -= 1
        except IndexError:      #No hay cancion anterior
            return
        return cancion

    def agregar_cancion(self, ruta_cancion):
        """ Agrega una Cancion a la cola a partir de su ruta. Devuelve True si se agrego 
        correctamente, False en caso contrario. Esta accion puede deshacerse y rehacerse."""
        try:
            self.agregar_cancion_sin_guardar(ruta_cancion)
            self.guardar_accion(ruta_cancion, self.AGREGADA)
            return True
        except (TinyTagException, LookupError, OSError):
            return False

    def remover_cancion(self, ruta_cancion):
        """ Remueve una Cancion de la cola a partir de su ruta. Devuelve True si se removio 
        correctamente, False en caso contrario. Esta accion puede deshacerse y rehacerse."""
        try:
            resultado = self.remover_cancion_sin_guardar(ruta_cancion)
            self.guardar_accion(ruta_cancion, self.REMOVIDA)
            return resultado
        except (TinyTagException, LookupError, OSError):
            return False

    def deshacer_modificacion(self):
        """ Deshace la ultima accion realizada. Devuelve True si pudo deshacerse, False en caso 
        contrario."""
        try:
            ruta_ultima_cancion, ultima_accion = self.acciones_tomadas.desapilar()
            if ultima_accion == self.AGREGADA:
                self.remover_cancion_sin_guardar(ruta_ultima_cancion)
                self.acciones_deshechas.apilar((ruta_ultima_cancion, self.AGREGADA))
                return True
            self.agregar_cancion_sin_guardar(ruta_ultima_cancion)
            self.acciones_deshechas.apilar((ruta_ultima_cancion, self.REMOVIDA))
            return True
        except (ValueError, IndexError):
            return False

    def rehacer_modificacion(self):
        """ Rehace la ultima accion que se deshizo. Devuelve True si pudo rehacerse, False en caso 
        contrario."""
        try:
            ruta_ultima_cancion, ultima_accion = self.acciones_deshechas.desapilar()
            if ultima_accion == self.AGREGADA:
                self.agregar_cancion_sin_guardar(ruta_ultima_cancion)
                self.acciones_tomadas.apilar((ruta_ultima_cancion, self.AGREGADA))
                return True
            self.remover_cancion_sin_guardar(ruta_ultima_cancion)
            self.acciones_tomadas.apilar((ruta_ultima_cancion, self.REMOVIDA))
            return True
        except (ValueError, IndexError):
            return False

    def obtener_n_siguientes(self, n_canciones):
        """ Devuelve una lista con las siguientes n canciones. Si en la cola de reproduccion 
        quedan menos canciones que las pedidas, la lista contendra menos elementos que los 
        pedidos."""
        if self.lista_canciones.esta_vacia():
            return None
        lista = []
        for i in range(n_canciones):
            try:
                lista.append(self.lista_canciones.get_elemento(self.actual + 1 + i))
            except IndexError:
                return lista
        return lista

    def __str__(self):
        return str(self.lista_canciones)

    def guardar_accion(self, ruta_cancion, accion):
        """Guarda la accion como una tupla (ruta_cancion, accion)."""
        self.acciones_tomadas.apilar((ruta_cancion, accion))

    def agregar_cancion_sin_guardar(self, ruta_cancion):
        """Agrega la cancion a la lista de reproduccion."""
        cancion = Cancion(ruta_cancion)
        self.lista_canciones.insert(cancion)

    def remover_cancion_sin_guardar(self, ruta_cancion):
        """Remueve la cancion de la lista de reproduccion.
        Devuelve True en caso que sea exitoso y False en caso contrario."""
        cancion = Cancion(ruta_cancion)
        posicion = self.lista_canciones.index(cancion)
        if posicion:
            self.lista_canciones.pop(posicion)
            return True
        return False