import datetime as dt
#Condiciones para obtener el delta. Deben estar en orden de coincidencia.
#date es la fecha que se comparará
CONDICIONES = {
"Hoy": "today == date",
"Ayer": "today - date == dt.timedelta(days=1)",
"Esta semana": "today.isocalendar()[1] == date.isocalendar()[1]",
"La semana pasada": "today.isocalendar()[1] - date.isocalendar()[1] == 1",
"Este mes": "today.month == date.month",
"El mes pasado": "today.month - date.month == 1",
"Este año": "today.year == date.year",
"El año pasado": "today.year - date.year == 1",
}
def ultima_modificacion(fecha):
''' Devuelve hace cuanto fue modificado un archivo recibiendo la fecha en la cual fue modificado.
Parameters:
str fecha: Fecha en isoformat en la que fue modificado el archivo.
Returns:
str: Representación textual de hace cuanto fue modificado el archivo.
Raises:
ValueError: En caso que la fecha que se ingresa sea mayor al día actual.
'''
date = dt.datetime.fromisoformat(fecha).date()
today = dt.date.today()
if date > today:
raise ValueError("La fecha es mayor al día actual.")
for k,v in CONDICIONES.items():
if eval(v):
return k
# En caso que no se cumpla ninguna condición
return "Hace más de un año"
if __name__ == '__main__':
print(ultima_modificacion("2019-11-14"))
Continuando con el análisis de nuestro código, si observamos la línea 16 vemos que se define una función. Si bien aún no hablaremos de las funciones y sus características, a nivel general, una función es un procedimiento o rutina que se crean para cumplir un procedimiento específico.
Si observas el código, verás que a partir de la línea 17 hasta la línea 37 inclusive, el código se encuentra indentado o “sangrado”. Esto ocurre porque en Python las estructuras de control de flujo no poseen llaves que marquen dónde comienzan y terminan; el delimitador de comienzo son los dos puntos (:) y el propio indentado del código indica que dichas sentencias pertenecen al mismo bloque.
Si bien puedes indentar utilizando espacios y tabulaciones, el método de indentación más popular en Python son los espacios. Para lograr esto con mayor facilidad, puedes configurar tu editor de textos para que funcione de dicha manera, siempre que el editor lo permita.

Python posee controles de flujo tradicionales como if, while y for. Además posee try/except para el manejo de excepciones y with para el manejo de excepciones más limpio y legible a la hora de trabajar con archivos.
Antes de continuar analizando nuestro código, analicemos estas declaraciones.
Declaración if/elif/else:
La sentencia de control de flujo más conocida en un lenguaje de programación es el if. Esta declaración sirve para evaluar condiciones y ejecutar instrucciones si estas condiciones se cumplen. Por ejemplo…
>>> hoy = "Sábado"
>>> if hoy == "Sábado":
... print("Es fin de semana!")
...
Es fin de semana!
Es fin de semana!
Creamos la variable hoy con el valor
“Sábado”.
Luego evaluamos que el contenido de la
variable hoy sea igual a Sábado.
Presionamos TAB e indicamos que, de
ser así, imprimimos “Es fin de semana!”.
Para finalizar el bloque dentro del
if, simplemente volvemos a presionar ENTER.
Como era de esperar, se imprime la
leyenda “Es fin de semana!”.
Operadores de comparación
En el ejemplo anterior utilizamos el comparador ==, pero existen varios operadores de comparación; demos un vistazo.
== (igual): Si ambos operandos son iguales, entonces la
condición es verdadera.
!= (distinto): Si ambos operandos son distintos, entonces la
condición es verdadera.
<> (distinto): Existe otro modo de comparar si un valor
es distinto, y es el operador de menor/mayor.
> (mayor): Si el valor del primer operando es mayor al
segundo, entonces la condición es verdadera.
< (menor): Si el valor del primer operando es menor al
segundo, la condición es verdadera.
>= (mayor o igual): Si el valor del primer operando es
mayor o igual al segundo, entonces la condición es verdadera.
<= (menor o igual): Si el valor del primer operando es
menor o igual al segundo, entonces la condición es verdadera.
Vale aclarar que puedes combinar condiciones con los operadores booleanos and y or o puedes negar una condición con el operador not.
En caso de que la condición del if sea False, se comprobarán todos los siguientes elif (en caso de que existan) y de no cumplirse ninguna de estas condiciones, se ejecutará el contenido de else. Por ejemplo…
>>> anyo = 2019
>>> if anyo >= 1990 and anyo < 2000:
... print("Es la década del 90")
... elif anyo >= 2000 and anyo < 2010:
... print("Es la década del 00")
... elif 2010 <= anyo < 2020:
... print("Es la década del 10")
... else:
... print("Solo analizamos pocas décadas")
...
Es la década del 10
Creamos una variable anyo con el valor
2019.
Utilizamos anyo dado a que no podemos
utilizar la letra ñ en nombres de variables.
En primera instancia, comparamos si el
año es mayor o igual a 1990 y menor a 2000.
De ser así, imprimimos que es la
década del 90.
En caso de que no se cumpla esta
condición, evaluamos otra con elif.
En este caso, comparamos Que el año
sea mayor o igual a 2000 y menor a 2010 para imprimir que es la
década del 00.
En caso que no se cumpla, evaluamos si
el año es mayor o igual a 2010 y menor a 2020, pero con una
notación simplificada.
De ser así, imprimimos que es la
década del 10.
En caso de que no se cumpla ninguna
condición, imprimimos que solo analizamos pocas décadas.
Y Tal como se esperaba, se imprime que
es la década del 10
Declaración try/except:
La declaración try es utilizada para el manejo de excepciones. El bloque dentro del try es ejecutado y en caso de que se eleve alguna excepción, se comprueban todos los except en el orden que fueron indicados y en caso de que no ocurra ninguna coincidencia, se ejecuta el bloque dentro de la etiqueta except final.
La declaración try más básica es la siguiente:
>>> try:
... print('as' * 'df')
... except TypeError:
... print('Error multiplicando cadenas')
... except:
... print('Error desconocido')
...
Error multiplicando cadenas
Error multiplicando cadenas
En primera instancia, utilizamos la
palabra reservada try y dos puntos.
Seguido, intentamos realiza una
operación que elevará una excepción.
En este caso, intentamos multiplicar
dos cadenas.
Luego, utilizamos la declaración
except TypeError para comprobar si se elevó una excepción de tipo
TypeError.
De ser así, imprimimos que ocurrió
un error multiplicando las cadenas.
Luego de esto, utilizamos la palabra
reservada except y dos puntos.
Y dentro de except, indicamos que hay
un error pero que no sabemos cual es.
Tal como se esperaba, se imprime que
hubo un error multiplicando cadenas.
Además de este uso básico, también es posible agregar las cláusulas else y finally. El bloque else se ejecuta si no se generó ninguna excepción y no se ejecutó ningún return, continue o break, cuyo funcionamiento descubriremos en los ciclos iterativos. Mientras que el bloque finally se ejecuta independientemente del resultado de los bloques try/except/else.
Estructuras de control iterativas
Ciclo while
La sentencia while se utiliza para ejecutar acciones repetidamente siempre que una condición sea verdadera. A este concepto también se lo conoce como loop.
Por ejemplo, si queremos imprimir los números del 1 al 10 con while, deberíamos realizar lo siguiente:
>>> tmp = 1
>>> while tmp <= 10:
... print(tmp)
... tmp += 1
...
1
2
3
4
5
6
7
8
9
10
Primero creamos una variable temporal
con el nombre tmp de valor 1.
Luego, creamos el bucle while
evaluando que tmp sea menor o igual a 10.
Si esto se cumple, imprimimos el valor
de tmp y luego incrementemos en 1el valor de tmp.
A diferencia de la sentencia if, el
bucle while vuelve a evaluar la condición una vez que se finalizan
todas las instrucciones dentro del mismo.
Si la condición vuelve a ser
verdadera, se vuelven a ejecutar todas las instrucciones dentro del
mismo.
Por dicho motivo, el código se
detiene cuando tmp llega al valor 11 (no se imprime este valor).
A diferencia de otros lenguajes, el bucle while en Python soporta la expresión else, que es ejecutada si la evaluación de while es False. Por ejemplo…
>>> tmp = 0
>>> while tmp <= 3:
... print(tmp)
... tmp += 1
... else:
... print("Se finalizó el ciclo.")
...
0
1
2
3
Se finalizó el ciclo.
Creamos la variable temporal
Creamos un bucle while evaluando que
tmp sea menor o igual a 3
En caso que sea correcto, imprimimos e
incrementamos el valor de tmp
En caso de que la evaluación sea
False, imprimimos que se finalizó el ciclo.
Además, un bucle while puede ser detenido manualmente con la sentencia break. En dicho caso, el bloque else no es ejecutado. Por ejemplo…
>>> tmp = 0
>>> while tmp <= 5:
... print(tmp)
... if tmp == 3:
... break
... tmp += 1
... else:
... print("Se finalizó correctamente.")
...
0
1
2
3
Volvemos a asignar tmp a 0
Volvemos a crear el bucle while pero
evaluando a 5
Imprimimos el valor y evaluamos si tmp
es igual a 3
En dicho caso, ejecutamos la sentencia
break que se encargará de forzar la finalización del bucle.
Incrementamos el valor de tmp
Creamos el else para cuando la
evaluación de while no se cumpla
Y en tal caso, imprimimos que se
finalizó correctamente.
Como se esperaba, cuando tmp alcanza
el valor 3, se ejecuta la sentencia break, el ciclo se rompe y no se
ejecuta el código dentro del else.
Ciclo for
A diferencia de otros lenguajes, el ciclo for en Python se utiliza para iterar sobre los elementos de una secuencia como una cadena, lista, tupla o cualquier iterable. Por ejemplo…
>>> dias = ["Lunes", "Martes", "Miércoles"]
>>> for dia in dias:
... print (dia)
...
Lunes
Martes
Miércoles
Creamos una lista con 3 días de la
semana
Creamos un bucle for que itere sobre
la variable días
El bucle for comenzará en la posición
0 de la variable días en la primera iteración e irá cambiando de
posición conforme se vaya ejecutando el código dentro de sí
mismo.
En caso de que vengas de otro lenguaje de programación -o no- y precises iterar de la manera más conocida, puedes utilizar la función range. Por ejemplo…
>>> for i in range(3):
... print(i)
...
0
1
2
Creamos un ciclo for utilizando la
función range
Range devuelve un objeto iterable de
enteros desde 0 hasta el número indicado como parámetro (sin
incluir el mismo).
Una vez dentro del for, imprimimos el
valor de i.
Como podemos observar, se imprimen los
valores del 0 al 2 (no incluyendo el 3).
Para más información sobre la función range, puedes consultar la documentación oficial.