Untitled

mail@pastecode.io avatar
unknown
python
2 years ago
14 kB
1
Indexable
Never
import shlex
class Habilidad:
    '''Abstracción del concepto de habilidad en un asistente.'''

    def __init__(self, nombre, descripcion=None):
        self.nombre = nombre
        self.descripcion = descripcion or self.__doc__


        #raise NotImplementedError

    def invocar(self):
        print(f'Se ha invocado la habilidad {self.nombre}')

    def ayuda(self):
        texto = (self.invocar.__doc__)  or 'No hay ayuda específica'
        print(texto)

class Divisas(Habilidad):
    '''Conversión de divisas'''
    def __init__(self, *args, tasa=0.85, **kwargs):
        super().__init__(*args,**kwargs)
        self.tasa = tasa

    def invocar(self, cantidad):
        '''Convertir una cantidad la divisa original a la divisa objetivo'''
        return round(float(cantidad) * self.tasa, 2) 
        #NO SE SI PONER UN PRINT O UN RETURN

class Menu:
    '''Menú interactivo de gestión de habilidades.'''

    def __init__(self, habilidades: list[object]):
        # habilidades es una LISTA
        # habilidades es una LISTA de objetos de tipo habilidad
        # self.habilidades es un diccionario de nombre -> habilidad
        self.habilidades = {
        }

        for habilidad in habilidades:  
            self.habilidades[habilidad.nombre] = habilidad
            
    def ayuda(self, comando=None):
        '''
        Muestra ayuda del uso del menú. Si no se especifica una habilidad,
        se muestra la ayuda general. Esta ayuda general muestra la lista
        de habilidades, una por línea, y la descripción de cada habilidad.

        Si se especifica una habilidad, se muestra su ayuda específica.
        '''
        if not comando: #ayuda sin argumentos
            print('Habilidades disponibles:')
            for hab in self.habilidades.values():
                print(f'\t{hab.nombre}:\t{hab.descripcion}')
            return
        if comando not in self.habilidades: #ayuda con argumentos, 
            #argumento no válido
            print(f'Habilidad no encontrada: {comando}')
            return
        self.habilidades[comando].ayuda() #ayuda con argumentos válidos

    def lanzar(self):
        '''Recibe instrucciones del usuario en bucle.'''
        while True:
            linea = input('> ')
            if self.ejecutar(linea):
                break

    def convertir_linea(self, linea: str):
        comando, *args = shlex.split(linea)
        return comando, args

    def ejecutar(self, linea: str):
        '''
        Recibe una línea del usuario y ejecuta la acción requerida

        Devuelve True cuando se desea parar la ejecución.
        '''
        comando, args = self.convertir_linea(linea)
        if comando == 'salir':
            return True
        elif comando == 'ayuda':
            self.ayuda(*args)
            return
        ##
        print(self.habilidades[comando].invocar(*args))
       
           
        ## 
        

    def emular(self, linea: str):
        '''Ejecuta una línea, mostrando por pantalla el comando'''
        print('>', linea)
        self.ejecutar(linea)

class MenuComas(Menu):
    '''Menú interactivo de gestión de habilidades.'''

    def __init__(self, habilidades: list[object]):
        # habilidades es una LISTA
        # habilidades es una LISTA de objetos de tipo habilidad
        # self.habilidades es un diccionario de nombre -> habilidad
        self.habilidades = {
        }

        for habilidad in habilidades:  
            self.habilidades[habilidad.nombre] = habilidad
            
    def ayuda(self, comando=None):
        '''
        Muestra ayuda del uso del menú. Si no se especifica una habilidad,
        se muestra la ayuda general. Esta ayuda general muestra la lista
        de habilidades, una por línea, y la descripción de cada habilidad.

        Si se especifica una habilidad, se muestra su ayuda específica.
        '''
        if not comando: #ayuda sin argumentos
            print('Habilidades disponibles:')
            for hab in self.habilidades.values():
                print(f'\t{hab.nombre}:\t{hab.descripcion}')
            return
        if comando not in self.habilidades: #ayuda con argumentos, 
            #argumento no válido
            print(f'Habilidad no encontrada: {comando}')
            return
        self.habilidades[comando].ayuda() #ayuda con argumentos válidos

    def lanzar(self):
        '''Recibe instrucciones del usuario en bucle.'''
        while True:
            linea = input('> ')
            if self.ejecutar(linea):
                break

    def convertir_linea(self, linea: str):
        comando, *args = linea.split(",")
        return comando, args

    def ejecutar(self, linea: str):
        '''
        Recibe una línea del usuario y ejecuta la acción requerida

        Devuelve True cuando se desea parar la ejecución.
        '''
        comando, args = self.convertir_linea(linea)
        if comando == 'salir':
            return True
        elif comando == 'ayuda':
            self.ayuda(*args)
            return
        ##
        print(self.habilidades[comando].invocar(*args))
       
           
        ## 
        

    def emular(self, linea: str):
        '''Ejecuta una línea, mostrando por pantalla el comando'''
        print('>', linea)
        self.ejecutar(linea)
     
#SIMPLEMENTE CAMBIAR EL SHLEX SPLIT DEL MENU NORMAL PARA QUE SEPARE POR
#COMAS EN VEZ DE SEPARAR POR ESPACIOS
class MenuPrompt(Menu):
    def __init__(self, habilidades: list[object]):
        # habilidades es una LISTA
        # habilidades es una LISTA de objetos de tipo habilidad
        # self.habilidades es un diccionario de nombre -> habilidad
        self.habilidades = {
        }

        for habilidad in habilidades:  
            self.habilidades[habilidad.nombre] = habilidad
            
    def ayuda(self, prompt = '>', comando=None):
        '''
        Muestra ayuda del uso del menú. Si no se especifica una habilidad,
        se muestra la ayuda general. Esta ayuda general muestra la lista
        de habilidades, una por línea, y la descripción de cada habilidad.

        Si se especifica una habilidad, se muestra su ayuda específica.
        '''
        if not comando: #ayuda sin argumentos
            print('Habilidades disponibles:')
            for hab in self.habilidades.values():
                print(f'\t{hab.nombre}:\t{hab.descripcion}')
            return
        if comando not in self.habilidades: #ayuda con argumentos, 
            #argumento no válido
            print(f'Habilidad no encontrada: {comando}')
            return
        self.habilidades[comando].ayuda() #ayuda con argumentos válidos
        self.prompt = prompt

    def lanzar(self):
        '''Recibe instrucciones del usuario en bucle.'''
        while True:
            linea = input(self.prompt)
            if self.ejecutar(linea):
                break

    def convertir_linea(self, linea: str):
        comando, *args = shlex.split(linea)
        return comando, args

    def ejecutar(self, linea: str):
        '''
        Recibe una línea del usuario y ejecuta la acción requerida

        Devuelve True cuando se desea parar la ejecución.
        '''
        comando, args = self.convertir_linea(linea)
        if comando == 'salir':
            return True
        elif comando == 'ayuda':
            self.ayuda(*args)
            return
        ##
        print(self.habilidades[comando].invocar(*args))    
        ## 
    def emular(self, linea: str):
        '''Ejecuta una línea, mostrando por pantalla el comando'''
        print(self.prompt, linea)
        self.ejecutar(linea)
    

class MenuPreguntas(Menu):
    '''Menú interactivo de gestión de habilidades.'''

    def __init__(self, habilidades: list[object]):
        # habilidades es una LISTA
        # habilidades es una LISTA de objetos de tipo habilidad
        # self.habilidades es un diccionario de nombre -> habilidad
        self.habilidades = {
        }

        for habilidad in habilidades:  
            self.habilidades[habilidad.nombre] = habilidad
            
    def ayuda(self, comando=None):
        '''
        Muestra ayuda del uso del menú. Si no se especifica una habilidad,
        se muestra la ayuda general. Esta ayuda general muestra la lista
        de habilidades, una por línea, y la descripción de cada habilidad.

        Si se especifica una habilidad, se muestra su ayuda específica.
        '''
        if not comando: #ayuda sin argumentos
            print('Habilidades disponibles:')
            for hab in self.habilidades.values():
                print(f'\t{hab.nombre}:\t{hab.descripcion}')
            return
        if comando not in self.habilidades: #ayuda con argumentos, 
            #argumento no válido
            print(f'Habilidad no encontrada: {comando}')
            return
        self.habilidades[comando].ayuda() #ayuda con argumentos válidos

    def lanzar(self):
        '''Recibe instrucciones del usuario en bucle.'''
        while True:
            n = 0
            linea = []
            while True:
                if n == 0:
                    req = "Comando: "
                else: req = "Argumento " + n + ":"
                if not linea.append(input(req)): #Si el usuario introduce nada (None)
                    #Si el usuario introduce nada (None), salir del while
                    break
            if self.ejecutar(linea):
                break
                
    def convertir_linea(self, linea: str):
        comando, *args = shlex.split(linea)
        return comando, args

    def ejecutar(self, linea: str):
        '''
        Recibe una línea del usuario y ejecuta la acción requerida

        Devuelve True cuando se desea parar la ejecución.
        '''
        comando, args = self.convertir_linea(linea)
        if comando == 'salir':
            return True
        elif comando == 'ayuda':
            self.ayuda(*args)
            return
        ##
        print(self.habilidades[comando].invocar(*args))
        ## 
        

    def emular(self, linea: str):
        '''Ejecuta una línea, mostrando por pantalla el comando'''
        print('>', linea)
        self.ejecutar(linea)

    '''Menú interactivo de gestión de habilidades.'''

    
     
#SIMPLEMENTE CAMBIAR EL SHLEX SPLIT DEL MENU NORMAL PARA QUE SEPARE POR
#COMAS EN VEZ DE SEPARAR POR ESPACIOS
    
def prueba_menu_simple():
    habilidades = [
        Divisas(
            'bitcoin2euro', 
            tasa=49929.38, 
            descripcion='Conversión de bitcoins a euros'
            ),
        Divisas(
            'euro2bitcoin', 
            tasa=1/49929.38, 
            descripcion='Conversión de euros a bitcoins'
            ),
    ]
    m = Menu(habilidades)
    m.emular('ayuda')
    m.emular('bitcoin2euro 100')
    m.emular('euro2bitcoin 100')
    m.emular('ayuda noexiste')
    m.emular('ayuda bitcoin2euro')

class HabilidadCompleja(Habilidad):
    '''Un tipo de habilidad que permite invocar varios sub-comandos'''

    def subcomandos(self, subcomandos):
        '''
        Devuelve un diccionario de subcomandos a funciones.
        
        p.e.:
            {
            'insertar': self.insertar_producto,
            'borrar': self.borrar_producto,
            }
        '''
        
        return {}

    def invocar(self, subcomando, *args):
        pass
    def ayuda(self):
        print('Comando:\t', self.nombre)
        print('Descripción:\t', self.descripcion)
        print('Subcomandos:')
        # Muestra información de cada uno de los subcomandos
        raise NotImplementedError


class ListaDeLaCompra(HabilidadCompleja):
  '''Gestión muy simple de lista de la compra'''

  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    super().subcomandos = self.subcomandos()
    self.productos = []

  def subcomandos(self):
    return {
      'insertar': self.insertar,
      'borrar': self.borrar,
      'listar': self.listar,
      'cantidad': self.cantidad,
      }

  def insertar(self, producto):
    '''Insertar un producto nuevo'''
    self.productos.append(producto)

  def listar(self):
    '''Mostrar el listado de productos'''
    for ix, producto in enumerate(self.productos):
      print(f'{ix}: {producto}')

  def borrar(self, numero):
    '''Borrar un producto'''
    self.productos.pop(int(numero))

  def cantidad(self):
    '''Mostrar el número de productos en la lista'''
    return len(self.productos)

def prueba_menu_complejas():
    pass
    habilidades = [
        Divisas('bitcoin2euro', tasa=49929.38),
        Divisas('euro2bitcoin', tasa=1/49929.38),
        ListaDeLaCompra('listadelacompra', 'Gestión de la lista de la compra')
    ]
    m = Menu(habilidades)
    m.emular('ayuda')
    m.emular('ayuda listadelacompra')
    m.emular('listadelacompra insertar "1 kg de plátanos canarios"')
    m.emular('listadelacompra insertar "Pimientos"')
    m.emular('listadelacompra listar')
    m.emular('listadelacompra borrar 0')
    m.emular('listadelacompra listar')

if __name__ == '__main__':
    print('#' * 10, 'Prueba menú simple')
    prueba_menu_simple()
    print('#' * 10, 'Prueba menú complejas')
    prueba_menu_complejas()