# Solucion examen ALS parcial 1 2018-19


def rota_izq(s, n):
    """Rota una cadena de caracteres a la izquierda.
    
        :param s: La cadena a rotar.
        :param n: El num. de veces a rotar.
    """
    
    toret = s
    
    n %= len(s)
    if n >= 1:
        toret = s[n:] + s[:n]

    return toret


def calcula_num_rotaciones_izq(s1, s2):
    """Calcula n, el num. de rotaciones a la izquierda
       necesarias para convertir s1 en s2.
       
       :param s1: La cadena de referencia.
       :param s2: La cadena resultado de rotar n veces.
       :return: n, el num. de rotaciones necesarias.
    """
    
    toret = -1
    
    if (s1 and s2
    and len(s1) == len(s2)):
        for i in range(len(s1)):
            if rota_izq(s1, i) == s2:
                toret = i
                break
            
    return toret


class Arbol:
    """Representa un arbol binario."""
    
    def __init__(self, raiz, izqdo, drcho):
        self._nodos = [raiz, izqdo, drcho]
        
    @property
    def raiz(self):
        return self._nodos[0]
    
    @property
    def izqdo(self):
        return self._nodos[1]
    
    @property
    def drcho(self):
        return self._nodos[2]
    
    def recorrido_anchura(self):
        return str(self.raiz) + " " + self._recorrido_anchura()
    
    def _recorrido_anchura(self):
        izqdo = ""
        drcho = ""
        izqdo_arbol = ""
        drcho_arbol = ""
        
        if isinstance(self.izqdo, Arbol):
            izqdo = str(self.izqdo.raiz)
            izqdo_arbol = self.izqdo._recorrido_anchura()
        elif self.izqdo:
            izqdo = str(self.izqdo)
            
        if isinstance(self.drcho, Arbol):
            drcho = str(self.drcho.raiz)
            drcho_arbol = self.drcho._recorrido_anchura()
        elif self.drcho:
            drcho = str(self.drcho)
            
        return ((izqdo.strip() if izqdo else "")
                + (" " + drcho.strip() if drcho else "")
                + (" " + izqdo_arbol.strip() if izqdo_arbol else "")
                + (" " + drcho_arbol.strip() if drcho_arbol else ""))
    
    def __len__(self):
        return max(0, len([x for x in self._nodos if x != None]) - 1)
    
    def __getitem__(self, item):
        return self._nodos[item]
    
    def __str__(self):
        return str.format("{}({}, {})", str(self.raiz), str(self.izqdo), str(self.drcho))


class Movimiento:
    """Movimiento financiero."""
    
    def __init__(self, concepto, mes, anno, num, precio):
        self._concepto = concepto
        self._mes = mes
        self._anno = anno
        self._num = num
        self._precio = precio
        
    @property
    def concepto(self):
        return self._concepto
    
    @property
    def mes(self):
        return self._mes
    
    @property
    def anno(self):
        return self._anno
    
    @property
    def num(self):
        return self._num
    
    @property
    def precio(self):
        return self._precio

    @property
    def resultado(self):
        return self.num * self.precio

    def __str__(self):
        return str.format("{:4d}/{:02d} {:15s} {:6d} x {:6d} = {:10d}",
                            self.anno,
                            self.mes,
                            self.concepto,                            
                            self.num,
                            self.precio,
                            self.resultado)


class Publicidad(Movimiento):
    def __init__(self, concepto, anno, mes, num, precio):
        super().__init__(concepto, anno, mes, num, precio)
        
    @property
    def resultado(self):
        return super().resultado * -1;
    
    def __str__(self):
        return super().__str__()


class Venta(Movimiento):
    def __init__(self, concepto, anno, mes, num, precio):
        super().__init__(concepto, anno, mes, num, precio)
     
    def __str__(self):
        return super().__str__()


class Contenedor:
    """ Contiene una lista de elementos asociados a un nombre. """
    
    def __init__(self, nombre, elementos):
        self._nombre = nombre
        self._elementos = elementos
    
    @property
    def nombre(self):
        return self._nombre
    
    @property
    def elementos(self):
        return list(self._elementos)
    
    def __str__(self):
        return ("-- " + self.nombre
                    + "\n\t"
                    + str.join("\n\t",
                               [str(x) for x in self._elementos]))


class Empresa(Contenedor):
    """ Una empresa contiene su nombre y varios movimientos. """
    
    def __init__(self, nombre, lista_movimientos):
        super().__init__(nombre, lista_movimientos)


class SeleccionEmpresas(Contenedor):
    """Las empresas seleccionadas se guardan con un concepto. """
    
    def __init__(self, nombre, lista_empresas):
        super().__init__(nombre, lista_empresas)


def prueba_ejercicio1():
    """Pruebas sobre las rotaciones de cadenas. """
    
    print("Rotaciones: abc/cab:", calcula_num_rotaciones_izq("abc", "cab"), "=? 2")
    print("Rotaciones: abc/abc:", calcula_num_rotaciones_izq("abc", "abc"), "=? 0")
    print("Rotaciones: abc/bca:", calcula_num_rotaciones_izq("abc", "bca"), "=? 1")
    print("Rotaciones: abc/cca:", calcula_num_rotaciones_izq("abc", "cca"), "=? -1")


def prueba_ejercicio2():
    """ Pruebas sobre la clase Arbol. """
    
    a1 = Arbol('a', Arbol('b', 'c', 'd'), 'e')
    
    print("Arbol('a', Arbol('b', 'c', 'd'), 'e'): ", a1, "=? a(b(c, d), e)")
    print("a1[0] == a1.raiz == a =?", a1[0], "=?", a1.raiz)
    print("a1[1].raiz == a1.izqdo.raiz == b =?", a1[1].raiz, "=?", a1.izqdo.raiz)
    print("a1[2] == a1.drcho == e =?", a1[2], "=?", a1.drcho)
    print("len(a1) == ", len(a1), "=?", 2)
    print("len(a1.izqdo) == ", len(a1.izqdo), "=?", 2)
    print("a1.recorrido_anchura == ", a1.recorrido_anchura(), "=?", "a b e c d")


def prueba_ejercicio3():
    """ Pruebas sobre la selección de movimientos de empresas. """
    
    selempresas = SeleccionEmpresas("tech", [
                        Empresa("Microsoft", [
                            Publicidad("tv", 2019, 1, 5, 1500),
                            Venta("windows", 2019, 1, 50, 500)]),
                        Empresa("Google", [
                            Publicidad("tv", 2019, 1, 15000, 1),
                            Venta("chromecast", 2019, 1, 50, 30)])]);
    print("\n")
    print(selempresas)
    print("\n=?\n")
    print("""-- tech
        -- Microsoft
           1/2019 tv                   5 x   1500 =      -7500
           1/2019 windows             50 x    500 =      25000
        -- Google
           1/2019 tv               15000 x      1 =     -15000
           1/2019 chromecast          50 x     30 =       1500""")
    
    
if __name__ == "__main__":
    prueba_ejercicio1()
    prueba_ejercicio2()
    prueba_ejercicio3()
