Python Forum

Full Version: math formula does not give the same result as bash script [SOLVED]
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello everybody,

I was working on a script which gets the current date of the islamic calendar. I know there is a pip-module which converts a Georgian date to islamic date but it's only defined until 2077. I found there is a script on GitHub (https://github.com/gojigeje/hijri.sh) which gets the current date and it works far later than 2077.

The problem I have is that the bash script outputs the different results than when I "converted" the bash script to python. For example, this is the bash script for the current day (2 April 2023):

adjust=1

date=$(date +%d -d "$adjust day" | sed 's/^0*//')
month=$(date +%m | sed 's/^0*//')
year=$(date +%Y)

a=$(( $(( $month-14)) / 12 ))
b=$(( $(( $year+4900+$a )) / 100 ))
c=$(( $(( 1461 * $(( $year+4800+$a )) )) / 4 ))
d=$(( $(( 367 * $(( $month-2-12*$a )) )) / 12 ))
This is the output for the bash script when I echo the results:

3
4
2023
0
69
2492100
61
This is my python script:

#!/usr/bin/env Python3

#Imports
from datetime import datetime
import sys

#Get Date
day = datetime.now().day + 1 #Why adjust one date
month = datetime.now().month
year = datetime.now().year

#Formula
a = ((month-14) / 12)
b = ((year+4900+math.trunc(a)) / 100)
c = ((1461*(year+4800+a)) / 4)
d = ((367 * (month-2-12*a)) / 4)
And this is the output I get for day, month and year and a, b, c and d:

3
4
2023
-0.8333333333333334
69.23
2491796.375
1101.0
Does anybody why the results of my python script differ so much to the ones from the bash script?
This should divide by 12, not 4.
d = ((367 * (month-2-12*a)) / 4)
The other differences are caused by Python doing floating point math and bash doing integer math. The first pass at fixing your equations I tried this:
a = ((month-14) // 12)
b = ((year+4900+a) // 100)
c = ((1461*(year+4800+a)) // 4)
d = ((367 * (month-2-12*a)) // 12)
This was a little off. a was -1 instead of 0. When doing integer division, // does floor division, not truncating. Use int() to truncate.

Second pass.
a = int((month-14) / 12)
b = int((year+4900+a) / 100)
c = int((1461*(year+4800+a)) / 4)
d = int((367 * (month-2-12*a)) / 12)
I see no reason for adding 1 to the day. This is my version of your converter. I hard coded date to match your example.
from datetime import datetime


now = datetime.strptime("3 4 2023", "%d %m %Y")
# Remove comment to convert current date
# now = datetime.now()
day = now.day
month = now.month
year = now.year
print(day, month, year)

a = int((month-14) / 12)
b = int((year+4900+a) / 100)
c = int((1461*(year+4800+a)) / 4)
d = int((367 * (month-2-12*a)) / 12)
print(a, b, c, d)
Output:
3 4 2023 0 69 2492100 61
Maybe (for my benefit, least ways) you should explain your formulas.

Also, you have four objects (a,b,c and d) but you have seven lines of output, so it's not altogether clear which object relates to which output.

A good example of the way to show that, would be print(f"a = {a}")

About the above example (which seem to be line four of your output) right now we're in month 4, so 4-14 = -10 and -10 / 12 = -0.8333333333333334
(Apr-02-2023, 11:38 AM)deanhystad Wrote: [ -> ]This should divide by 12, not 4.
d = ((367 * (month-2-12*a)) / 4)
The other differences are caused by Python doing floating point math and bash doing integer math. The first pass at fixing your equations I tried this:
a = ((month-14) // 12)
b = ((year+4900+a) // 100)
c = ((1461*(year+4800+a)) // 4)
d = ((367 * (month-2-12*a)) // 12)
This was a little off. a was -1 instead of 0. When doing integer division, // does floor division, not truncating. Use int() to truncate.

Second pass.
a = int((month-14) / 12)
b = int((year+4900+a) / 100)
c = int((1461*(year+4800+a)) / 4)
d = int((367 * (month-2-12*a)) / 12)
I see no reason for adding 1 to the day. This is my version of your converter. I hard coded date to match your example.
from datetime import datetime


now = datetime.strptime("3 4 2023", "%d %m %Y")
# Remove comment to convert current date
# now = datetime.now()
day = now.day
month = now.month
year = now.year
print(day, month, year)

a = int((month-14) / 12)
b = int((year+4900+a) / 100)
c = int((1461*(year+4800+a)) / 4)
d = int((367 * (month-2-12*a)) / 12)
print(a, b, c, d)
Output:
3 4 2023 0 69 2492100 61

Ahh thank you. Didn't thought of that. But it worked :)