Hello fellow Pythonist!
I’ve put together a solution proposal for your problem.
Decndium Function
I believe that you have chosen a suitable path, create a function that calculates the decndium. And for this function, the best input argument is from date (date) and the best output variable, a integer representing the decndium (n_decendio).
def decendio(date):
day = date.day
month = date.month
if day >= 21:
index = 3
n_decendio = month * index + (month * 0 - 0)
elif day >= 11:
index = 2
n_decendio = month * index + (month * 1 - 1)
else:
index = 1
n_decendio = month * index + (month * 2 - 2)
return n_decendio
Depending on the day of the month there is the correct way to calculate the Decndium. For example, if the day is greater than or equal to 21, it would be enough to multiply the month by the index, in this case 3. But for you to follow the logic of formation, I kept the additive expression (Month * 0 - 0), totally dispensable, expression that accompanies the other conditionals with the appropriate variations.
Testing the Function
As stated earlier, the input argument is a date, so we will use a standard python library, the datetime, and from this library we will use the object date, where you should spend day, month and year. Follows example of use:
import datetime
#Aproveitando a função today de datetime.date para avaliarmos qual decêndio é hoje (31/03/2019)
today = datetime.date.today()
today
#saída
datetime.date(2019, 3, 31) #64 nunca mais.
n_decendio = decendio(today)
n_decendio
#saída
9
#Você também pode avaliar uma nova data dessa forma, passando dia, mês e ano.
other_date = datetime.date(year=1987, month=12, day=1)
n_decendio = decendio(other_date)
n_decendio
#saída
34
(Bonus) Optimizing the Decal Function
A good practice in python as in any other language is to perform what we call exception control, that is, evaluate and control possible bugs. In the function we create, we need the function input argument to be a date object. We would have problems if we passed a date like this: '2019-03-31'. Thus, we used the flow control feature: Try/except/Else.
def new_decendio(date):
try:
#Avalia se o argumento date NÂO é do tipo datetime.date, levantando um erro.
if not isinstance(date, datetime.date):
raise Exception('TypeError: date is not a datetime.date type.')
except Exception as e:
print('Error: ' + str(e))
return None
else:
day = date.day
month = date.month
if day >= 21:
index = 3
n_decendio = month * index
elif day >= 11:
index = 2
n_decendio = month * index + (month - 1)
else:
index = 1
n_decendio = month * index + (month * 2 - 2)
return n_decendio
In Try we evaluate if date is NOT an object of type datetime.date, if not we raise an error that is captured by except, if so, we continue the flow in Else.
Last Test
Let’s test our optimization.
n_decendio = new_decendio('2019-05-14')
n_decendio
#saída
Error: TypeError: date is not a datetime.date type.
n_decendio = new_decendio(today)
n_decendio
#saída
9
Completion
Encapsulating code that will often be reused in functions is a great idea, but don’t forget to control exceptions and document your code (not performed here). You could choose to use day and month directly as arguments for your function, this way def decendio(day, Month) and work with these variables in the same way. But I particularly prefer datetime.date because it comes with batteries included for date handling in case you need to perform some kind of operation. For more information about the datetime library, see link.
A hug, good studies. That’s all Folks!