import estructura
from lista import *

#P1

estructura.crear("Tiempo", "horas minutos")

t1 = Tiempo(1,0)
t2 = Tiempo(2,30)
t3 = Tiempo(12,5)
t4 = Tiempo(12,30)

#aString: Tiempo -> string
#Transforma un tiempo a formado HH:MM
#Ej: aString(t2) == "02:30"
def aString(T):
    h = T.horas
    m = T.minutos
    if h < 10 and m < 10:
        return "0" + str(h) + ":0" + str(m)
    elif h < 10:
        return "0" + str(h) + ":" + str(m)
    elif m < 10:
        return str(h) + ":0" + str(m)
    else:
        return str(h) + ":" + str(m)

assert aString(t1) == "01:00"
assert aString(t2) == "02:30"
assert aString(t3) == "12:05"
assert aString(t4) == "12:30"

#enMinutos: Tiempo -> int
#Transforma un tiempo a sus minutos
#Ej: enMinutos(t2) == 150
def enMinutos(T):
    h = T.horas
    m = T.minutos
    return h*60 + m

assert enMinutos(t2) == 150

#sumar: Tiempo Tiempo -> Tiempo
#Suma dos tiempos
#Ej: sumar(t1,t2) == Tiempo(3,30)
def sumar(T1,T2):
    h1 = T1.horas
    h2 = T2.horas
    m1 = T1.minutos
    m2 = T2.minutos
    sh = h1 + h2
    sm = m1 + m2
    if sm > 60:
        sh = sh + sm/60
        sm = sm + sm%60
    return Tiempo(sh%24, sm)

assert sumar(t1,t2) == Tiempo(3,30)
assert sumar(t3,t4) == Tiempo(0,35)

#comparar: Tiempo Tiempo -> int
#Compara dos tiempos
#Ej: comparar(t1,t2) == -1
def comparar(T1, T2):
    h1 = T1.horas
    h2 = T2.horas
    m1 = T1.minutos
    m2 = T2.minutos
    if h1 < h2:
        return -1
    elif h1 > h2:
        return 1
    else:
        if m1 < m2:
            return -1
        elif m1 > m2:
            return 1
        else:
            return 0

assert comparar(t1,t2) == -1
assert comparar(t1,t1) == 0
assert comparar(t2,t1) == 1

def programa(mayor = Tiempo(0,0), suma = Tiempo(0,0), total = 0):
    t = int(input('Tiempo?'))
    if t  == 0:
        print "Mayor tiempo:", aString(mayor)
        print "Suma:", aString(suma)
        if total != 0:
            promedio_minutos = enMinutos(suma)/total
            promedio_tiempo = Tiempo(promedio_minutos/60, promedio_minutos%60)
            print "Promedio:", aString(promedio_tiempo)
        else:
            print "Promedio: No existe"
        return
    horas = t/100
    minutos = t%100
    t = Tiempo(horas, minutos)
    if comparar(t, mayor) > 0:
        mayor = t
    programa(mayor, sumar(suma,t), total+1)

programa()

lista1 = lista(t1, lista(t2, lista(t3, lista(t4, None))))

#mayorTiempo: lista -> Tiempo
#Entrega el mayor tiempo de una lista
#Ej: mayorTiempo(lista1) == t4
def mayorTiempo(L, mayor = Tiempo(0,0)):
    if L == None:
        return mayor
    T = cabeza(L)
    if comparar(T, mayor) > 0:
        mayor = T
    return mayorTiempo(cola(L), mayor)

assert mayorTiempo(cola(lista1)) == t4

#promedioTiempos: lista -> Tiempo
#Entrega el promedio de los tiempos
#Ej: promedioTiempo(lista1) == Tiempo(1,17)
def promedioTiempo(L, suma = Tiempo(0,0), total = 0):
    if L == None:
        promedio_minutos = enMinutos(suma)/total
        promedio_tiempo = Tiempo(promedio_minutos/60, promedio_minutos%60)
        return promedio_tiempo
    T = cabeza(L)
    return promedioTiempo(cola(L), sumar(suma, T), total+1)

assert promedioTiempo(lista1) == Tiempo(1,17)

#cuentaMenores: lista Tiempo -> int
#Cuenta los numeros menores a uno en una lista
#Ej: cuentaMenores(lista1, t3) == 2
def cuentaMenores(L, T_menor, menores = 0):
    if L == None:
        return menores
    T = cabeza(L)
    if comparar(T, T_menor) < 0:
        menores += 1
    return cuentaMenores(cola(L),T_menor, menores)

assert cuentaMenores(lista1, t3) == 2

#listaMenores: lista Tiempos -> lista
#Entrega una lista con los tiempos menores
#Ej: listaMenores(lista1, t3) == lista(t2, lista(t1, None))
def listaMenores(L, T_menor, menores = None):
    if L == None:
        return menores
    T = cabeza(L)
    if comparar(T, T_menor) < 0:
        menores = lista(T, menores)
    return listaMenores(cola(L),T_menor, menores)

assert listaMenores(lista1, t3) == lista(t2, lista(t1, None))

#P3

lista2 = lista(3, lista(0, lista(7, None)))
lista3 = lista(3, lista(0, lista(3, None)))

#lugar: lista any -> int
#Entrega el lugar en que un valor esta en una lista
#Ej: lugar(lista2, 0) == 2
def lugar(L, x, indice = 1):
    if L == None:
        return 0
    T = cabeza(L)
    if T == x:
        return indice
    else:
        return lugar(cola(L), x, indice + 1)

assert lugar(lista2, 0) == 2
assert lugar(lista2, 8) == 0

#listaLugares: lista any -> lista
#Entrega la lista con los lugares de un valor
#Ej: 
def listaLugares(L, x, indice = 1):
    if L == None:
        return None
    T = cabeza(L)
    if T == x:
        return lista(indice, listaLugares(cola(L), x, indice + 1))
    else:
        return listaLugares(cola(L), x, indice + 1)

assert listaLugares(lista2, 0) == lista(2, None)
assert listaLugares(lista3, 3) == lista(1, lista(3, None))
assert listaLugares(lista2, 8) == None

