#Este programa calcula la edad de alguien, dados tres valores para día, mes y año
#de nacimiento. El año de nacimiento tiene que estar comprendido entre 1921 y
#el año anterior al actual.

#El programa comprueba que los datos introducidos son números enteros y son valores
#válidos para una fecha.



from datetime import datetime


#La función bisiesto devuelve True si el año que recibe como parámetro es bisiesto
#y devuelve False si no lo es. Un año dado es bisiesto si:
#es divisible entre cuatro y (no es divisible entre 100 o es divisible entre 400).
def bisiesto (aa):
    if (aa % 4 == 0) and ((aa % 100 != 0) or (aa % 400 == 0)) :
        return True
    else:
        return False

#La función Fecha_mes comprueba que el día está dentro del rango
#de días de cada mes. También comprueba si el puede ser el 29 de febrero porque
#el año es bisiesto. Devuelve True (Fecha válida) o False (Fecha inválida)
def Fecha_mes (d,m,a):
    Dias_meses=(31,29,31,30,31,30,31,31,30,31,30,31)
    if d > Dias_meses[m-1] :   # El día está fuera de rango
        return False
    elif m == 2 and d ==29 and not bisiesto(a) :
        return False    #El año no es bisiesto. No hay 29 de febrero
    else :
        return True

#La función pidedato solicita un número entero y comprueba que es un valor correcto.
#La función sigue pidiendo valores hasta que el introducido es un número entero.
def pidedato (num,nom): 
    while True:
        try:
            print(f"Introduce un número entero para el {nom}: ",end="")
            num=int(input())
            return num
            break
        except ValueError:
            print("El valor introducido no es válido. Por favor, introduce un número entero")


print ("Escribe los datos de tu fecha de nacimiento y te digo cuántos años tienes")      

#Comienza la solicitud de valores para día, mes y anho
#Esta solicitud se repite hasta que se introduzcan valores
#de una fecha válida
Fecha_bien=False
while not Fecha_bien :
    #Pedimos un valor para el día
    numero = 0
    nombre = "dia"
    Dia_nac = pidedato(numero,nombre)
    while Dia_nac < 1 or Dia_nac > 31 :
        numero = 0
        nombre = "dia"
        print ("El valor es incorrecto. Escribe un número entero entre 1 y 31")
        Dia_nac = pidedato(numero,nombre)   

    #Pedimos un valor para el mes
    numero = 0
    nombre = "mes"
    Mes_nac = pidedato(numero,nombre)
    while Mes_nac < 1 or Mes_nac > 12 :
        numero = 0
        nombre = "mes"
        print ("El valor es incorrecto. Escribe un número entero entre 1 y 12")
        Mes_nac = pidedato(numero,nombre)   

    #Obtenemos el valor del año anterior al actual. Este será el último año válido para la fecha de nacimiento
    Hoy = datetime.now()
    anho_actual = int(Hoy.strftime('%Y'))
    anho_ant = anho_actual - 1

    #Solicitamos el valor para el año
    numero = 0
    nombre = "año"
    Anho_nac = pidedato(numero,nombre)
    while Anho_nac < 1921 or Anho_nac > anho_ant :
        numero = 0
        nombre = "año"
        print (f"El valor es incorrecto. Escribe un número entero entre 1921 y {anho_ant}")
        Anho_nac = pidedato(numero,nombre)

    Fecha_bien=Fecha_mes(Dia_nac,Mes_nac,Anho_nac)
    if not Fecha_bien :
        print ("La fecha es incorrecta. vuelva a introducir los datos")


#La fecha introducida es válida y comienza la parte de cálculo de la edad

Cumple = 1 #Esta variable indica si hoy es o no el cumpleaños.
           #En principio, tiene valor 1, no es el cumpleaños
Edad = int(Hoy.year - Anho_nac) # Se calculan los años "en bruto"
if Mes_nac > Hoy.month :  #Se cumplen años en un mes posterior
    Edad = Edad - 1       #Hay que restar un año
elif (Mes_nac == Hoy.month) and (Dia_nac > Hoy.day) : #Se cumplen años este mes,
                                                      #pero en un día posterior
    Edad = Edad - 1       #Hay que restar un año
elif (Mes_nac == Hoy.month) and (Dia_nac == Hoy.day) : #Hoy es el cumpleaños
    Cumple = 0  #La variable cambia a valor 0, es el día del cumpleaños

#Se escribe la edad
#Se felicita a los que cumplen años hoy
#Se distingue a los que todavía no han cumplido un año y
#a los que tienen solo un año
if Cumple == 0 :
    if Edad == 1 :
        print ("Felicidades! Hoy es tu cumpleaños y cumples",Edad,"año") #Solo se cumple 1 año
    else :
        print ("Felicidades! Hoy es tu cumpleaños y cumples",Edad,"años") #Se cumplen varios años
else :
    if Edad == 0:
        print ("Todavía no has cumplido un año")
    elif Edad == 1:
        print ("Solo tienes un añito")
    else :
        print ("Tienes",Edad,"años")





