To make it a bit easier with the days of each month you could use the module calendar
. Using the function% co_of% whose second parameter returns the number of days of the month (such as the days of February for leap years):
>>> import calendar
>>> calendar.monthrange(month=2, year=2017)
(2, 28)
>>> calendar.monthrange(month=2, year=2020) # Bisiesto
(5, 29)
>>> calendar.monthrange(month=12, year=2020)
(1, 31)
By the way, the first parameter is the day of the week of the first day of the month (counting from 0 as Monday). With the number of days of the month you will be able to validate the correct day as you will see later.
It seems to me that you will also get complicated if you work with the months as text instead of numbers (that you can format later):
>>> dias = range(1, 32) # No se incluye el 32
>>> meses = range(1, 13) # No se incluye el 13
For holidays you can map the dates you want as tuples of type monthrange
or (mes, dia)
as you prefer:
>>> festividades = {
... (1, 1): '¡Feliz año nuevo!',
... (31, 10): '¡Feliz Halloween!',
... (25, 12): '¡Feliz Navidad!'
... }
Putting everything together in a script:
# -*- coding: utf-8 -*-
import calendar
from datetime import date, datetime
import random
def fechas(dia=None, mes=None):
mensajes_festivos = {
(1, 1): '¡Feliz año nuevo!',
(31, 10): '¡Feliz Halloween!',
(25, 12): '¡Feliz Navidad!'
}
hoy = date.today()
# Si no hemos pasado el día o el mes en la función seleccionamos un al azar
if not dia:
dia = random.choice(range(1, 32))
if not mes:
mes = random.choice(range(1, 13))
# Hay que usar el día válido, verifiquemos que no se pase del rango. No nos
# interesa por ahora el primer parámetro retornado, solo la cantidad de días
# del mes
_, dia_maximo = calendar.monthrange(year=hoy.year, month=mes)
if dia > dia_maximo:
dia = dia_maximo
# El mensaje final es una mezcla del mensaje festivo junto con el mensaje de
# la descripción del día. Si no hay día destivo mapeado simplemente no se
# imprime nada
fecha = date(hoy.year, mes, dia)
mensaje = [
fecha.strftime('%d de %B del %Y')
]
mensaje_festivo = mensajes_festivos.get((dia, mes), '')
if mensaje_festivo:
mensaje.append(mensaje_festivo)
# Mostrar mensaje
print(' '.join(mensaje))
if __name__ == '__main__':
fechas() # Sin parámetros, dia y mes al azar
fechas(dia=31, mes=10) # Probemos con Halloween
fechas()
fechas(dia=31, mes=2) # ¿31 de febrero? Hmm, no.
fechas(dia=25, mes=12) # ¿Qué tal con Navidad?
My script is called test.py, let's execute it:
$ python3 test.py
02 de May del 2017
31 de October del 2017 ¡Feliz Halloween!
20 de February del 2017
28 de Frebruary del 2017
25 de December del 2017 ¡Feliz Navidad!
It works but ¡ugh! ... is in English. You can use the wonderful (dia, mes)
to solve this problem.
$ sudo pip3 install babel
Collecting babel
Downloading Babel-2.5.1-py2.py3-none-any.whl (6.8MB)
100% |████████████████████████████████| 6.8MB 85kB/s
Requirement already satisfied: pytz>=0a in /usr/local/lib/python3.5/dist-packages (from babel)
Installing collected packages: babel
Successfully installed babel-2.5.1
$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from babel.dates import format_date
>>> from datetime import date
>>> format_date(date(2017, 10, 31), locale='es')
'31 oct. 2017'
>>> format_date(date(2017, 10, 31), format='long', locale='es')
'31 de octubre de 2017'
Excellent! Now we just have to add it to the script and we have everything ready (this time without all the comments):
# -*- coding: utf-8 -*-
import calendar
from babel.dates import format_date
from datetime import date, datetime
import random
def fechas(dia=None, mes=None):
mensajes_festivos = {
(1, 1): '¡Feliz año nuevo!',
(31, 10): '¡Feliz Halloween!',
(25, 12): '¡Feliz Navidad!'
}
hoy = date.today()
if not dia:
dia = random.choice(range(1, 32))
if not mes:
mes = random.choice(range(1, 13))
_, dia_maximo = calendar.monthrange(year=hoy.year, month=mes)
if dia > dia_maximo:
dia = dia_maximo
fecha = date(hoy.year, mes, dia)
mensaje = [
format_date(fecha, format='long', locale='es_PE')
]
mensaje_festivo = mensajes_festivos.get((dia, mes), '')
if mensaje_festivo:
mensaje.append(mensaje_festivo)
print(' '.join(mensaje))
if __name__ == '__main__':
fechas() # Sin parámetros, dia y mes al azar
fechas(dia=31, mes=10) # Probemos con Halloween
fechas()
fechas(dia=31, mes=2) # ¿31 de febrero? Hmm, no.
fechas(dia=25, mes=12) # ¿Qué tal con Navidad?
We see now:
$ python3 test.py
26 de julio de 2017
31 de octubre de 2017 ¡Feliz Halloween!
9 de mayo de 2017
28 de febrero de 2017
25 de diciembre de 2017 ¡Feliz Navidad!
Everything ready.