smart-aj 0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
smart_aj-0.3/PKG-INFO ADDED
@@ -0,0 +1,10 @@
1
+ Metadata-Version: 2.4
2
+ Name: smart-aj
3
+ Version: 0.3
4
+ Summary: Indian festivals and holidays detection using Panchang & common calendar. Hindus festivals are based on Panchang & holidays are based on common month and day.
5
+ Author: Ajay Sah
6
+ Requires-Dist: pandas
7
+ Requires-Dist: skyfield
8
+ Dynamic: author
9
+ Dynamic: requires-dist
10
+ Dynamic: summary
smart_aj-0.3/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # Smart PyPI Module
2
+
3
+ Detect Indian festivals and holidays using date.
4
+
5
+ ## Usage
6
+
7
+ '''python
8
+ from smart import Indian_Calendar
9
+
10
+ ic = Indian_Calendar()
11
+ df = ic.get_festival(df, date_col_name)
@@ -0,0 +1,3 @@
1
+ [build-system]
2
+ requires = ["setuptools", "wheel", "cython"]
3
+ build-backend = "setuptools.build_meta"
smart_aj-0.3/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
smart_aj-0.3/setup.py ADDED
@@ -0,0 +1,31 @@
1
+ from setuptools import setup
2
+ from Cython.Build import cythonize
3
+
4
+ setup(
5
+ name="smart-aj",
6
+ version="0.3",
7
+ # ext_modules=cythonize("indian_calendar/core.py"),
8
+ packages=["smart"],
9
+
10
+ # # Eska use eda.py ko .pyd me krne ke liye, jb .pyd create ho jaaye tb comment kro.
11
+ # ext_modules=cythonize(
12
+ # "smart/Indian_Calendar.py",
13
+ # compiler_directives={
14
+ # 'language_level': "3"
15
+ # }
16
+ # ),
17
+
18
+ install_requires=[
19
+ "pandas",
20
+ "skyfield"
21
+ ],
22
+
23
+ package_data={
24
+ "smart": ["*.pyd"]
25
+ },
26
+
27
+ include_package_data=True,
28
+
29
+ author="Ajay Sah",
30
+ description="Indian festivals and holidays detection using Panchang & common calendar. Hindus festivals are based on Panchang & holidays are based on common month and day.",
31
+ )
@@ -0,0 +1,269 @@
1
+ try:
2
+ from skyfield.api import load, Topos
3
+ from skyfield import almanac
4
+ import pandas as pd
5
+
6
+ class Indian_Calendar:
7
+ def __get_accurate_panchang(self, year, month, day, hour, minute, purnimanta):
8
+ eph = load('de421.bsp')
9
+ ts = load.timescale()
10
+ t = ts.utc(year, month, day, hour - 5, minute - 30)
11
+
12
+ # eph = load('de421.bsp')
13
+ sun, moon, earth = eph['sun'], eph['moon'], eph['earth']
14
+
15
+ # 1. अयनांश और निरयण गणना
16
+ def __get_nirayana_lon(target, time_obj):
17
+ T = (time_obj.tt - 2451545.0) / 36525
18
+ ayanamsha = (84404.78 + 5028.7965 * T + 1.111 * T**2) / 3600.0
19
+ astrometric = earth.at(time_obj).observe(target)
20
+ _, lon, _ = astrometric.ecliptic_latlon()
21
+ return (lon.degrees - ayanamsha) % 360
22
+
23
+ sun_nir = __get_nirayana_lon(sun, t)
24
+ moon_nir = __get_nirayana_lon(moon, t)
25
+
26
+ nakshatras = [
27
+ 'Ashwini', 'Bharani', 'Krittika', 'Rohini', 'Mrigashira',
28
+ 'Ardra', 'Punarvasu', 'Pushya', 'Ashlesha', 'Magha',
29
+ 'Purva_Phalguni', 'Uttara_Phalguni', 'Hasta', 'Chitra',
30
+ 'Swati', 'Vishakha', 'Anuradha', 'Jyeshta', 'Mula',
31
+ 'Purva_Ashadha', 'Uttara_Ashadha', 'Shravan',
32
+ 'Dhanishta', 'Shatabhisha', 'Purva_Bhadrapada',
33
+ 'Uttara_Bhadrapada', 'Revati'
34
+ ]
35
+ nakshatra = nakshatras[int(moon_nir / (360 / 27))]
36
+
37
+ # 2. मास (Month) गणना का सही नियम
38
+ # अमांत मास पिछली अमावस्या के सूर्य पर निर्भर करता है
39
+ t_start = ts.utc(year, month, day - 45)
40
+ f = almanac.moon_phases(eph)
41
+ times, phases = almanac.find_discrete(t_start, t, f)
42
+
43
+ last_nm_t = times[phases == 0][-1] # पिछली अमावस्या
44
+ sun_at_nm = __get_nirayana_lon(sun, last_nm_t)
45
+
46
+ hindu_months = ["Chaitra", "Vaishakha", "Jyeshtha", "Ashadha", "Shravana", "Bhadrapada",
47
+ "Ashvina", "Kartika", "Margashirsha", "Pausha", "Magha", "Phalguna"]
48
+
49
+ # Amanta Month Index
50
+ amanta_idx = (int(sun_at_nm / 30) + 1) % 12
51
+
52
+ # तिथि और पक्ष
53
+ diff = (moon_nir - sun_nir) % 360
54
+ tithi_no = int(diff / 12) + 1
55
+ paksha = "Shukla" if diff < 180 else "Krishna"
56
+
57
+ # Purnimanta सुधार: कृष्ण पक्ष में मास अगला हो जाता है
58
+ if purnimanta and paksha == "Krishna":
59
+ final_maas = hindu_months[(amanta_idx + 1) % 12]
60
+ else:
61
+ final_maas = hindu_months[amanta_idx]
62
+
63
+ rashis = [
64
+ 'Mesh', 'Vrishabh', 'Mithun', 'Kark',
65
+ 'Sinha', 'Kanya', 'Tula', 'Vrishchik',
66
+ 'Dhanu', 'Makar', 'Kumbh', 'Meen'
67
+ ]
68
+
69
+ sun_rashi_idx = int(sun_nir / 30)
70
+ moon_rashi_idx = int(moon_nir / 30)
71
+
72
+ sun_rashi_name = rashis[sun_rashi_idx]
73
+ moon_rashi_name = rashis[moon_rashi_idx]
74
+
75
+ return {
76
+ "date": f"{day}-{month}-{year} {hour}:{minute}",
77
+ "method": "Purnimanta (North India)" if purnimanta else "Amanta (South/West)",
78
+ "maas": final_maas,
79
+ "paksha": paksha,
80
+ "tithi": tithi_no if tithi_no <= 15 else tithi_no - 15,
81
+ "nakshatra": nakshatra,
82
+ "sun_rashi": sun_rashi_name,
83
+ "moon_rashi": moon_rashi_name
84
+ }
85
+
86
+ def __get_festivals(self, result:dict) -> str | None:
87
+ maas = result['maas']
88
+ paksha = result['paksha']
89
+ tithi = result['tithi']
90
+ nakshatra = result['nakshatra']
91
+ sun_rashi = result['sun_rashi']
92
+
93
+ _festivals = {
94
+ # Chaitra
95
+ ('Chaitra', 'Shukla', 1): 'Hindu_Nav_Varsh/Gudi_Padwa/Ugadi',
96
+ ('Chaitra', 'Shukla', 9): 'Shree_Ram_Navami',
97
+ ('Chaitra', 'Shukla', 15): 'Shree_Hanuman_Janmotsav',
98
+
99
+ # Vaishakh
100
+ ('Vaishakha', 'Shukla', 3): 'Akshaya_Tritiya',
101
+ ('Vaishakha', 'Shukla', 15): 'Buddha_Purnima',
102
+
103
+ # Jyeshtha
104
+ # ('Jyeshtha', 'Krishna', 15): 'Shree_Shani_Janmotsav',
105
+
106
+ # Ashadha
107
+ ('Ashadha', 'Shukla', 11): 'Devshayani_Ekadashi',
108
+ ('Ashadha', 'Shukla', 15): 'Guru_Purnima',
109
+
110
+ # Shravan
111
+ ('Shravan', 'Krishna', 8): 'Shree_Krishna_Janmashtami',
112
+ ('Shravan', 'Shukla', 15): 'Raksha_Bandhan',
113
+
114
+ # Bhadrapada
115
+ ('Bhadrapapda', 'Shukla', 4): 'Ganesh_Chaturthi',
116
+ ('Bhadrapada', 'Krishna', 8): 'Shree_Radha_Ashtami',
117
+
118
+ # Ashwina
119
+ ('Ashwina', 'Shukla', 1): 'Navratri_Start',
120
+ ('Ashwina', 'Shukla', 8): 'Durga_Ashtami',
121
+ ('Ashwina', 'Shukla', 9): 'Maha_Navami',
122
+ ('Ashwina', 'Shukla', 10): 'Dassehra',
123
+
124
+ # Kartika
125
+ ('Kartika', 'Krishna', 13): 'Dhanteras',
126
+ ('Kartika', 'Krishna', 14): 'Narak_Chaturdashi',
127
+ ('Kartika', 'Krishna', 15): 'Dipawali',
128
+ ('Kartika', 'Shukla', 1): 'Gowardhan_Pooja',
129
+ ('Kartika', 'Shukla', 2): 'Bhai_Dooj',
130
+ ('Kartika', 'Shukla', 6): 'Chhath_Pooja',
131
+
132
+ # Margashirsha
133
+ ('Margashirsha', 'Shukla', 11): 'Mokshada_Ekadashi',
134
+
135
+ # Pausha
136
+ ('Pausha', 'Shukla', 15): 'Pausha_Purnima',
137
+
138
+ # Magha
139
+ ('Magha', 'Shukla', 5): 'Basant_Panchami/Saraswati_Pooja',
140
+ ('Magha', 'Krishna', 14): 'Maha_Shiv_Ratri',
141
+
142
+ # Phalguna
143
+ ('Phalguna', 'Shukla', 15): 'Holi',
144
+ ('Phalguna', 'Krishna', 1): 'Holika_Dahan',
145
+ }
146
+
147
+ # Normal Festivals
148
+ festival = _festivals.get((maas, paksha, tithi))
149
+
150
+ # Janmashtami - Extra nakshatra condition
151
+ if maas == 'Shravan' and tithi == 'Krishna_Ashtami' and nakshatra == 'Rohini':
152
+ festival = 'Shree_Krishna_Janmashtami'
153
+
154
+ # Makar Sankranti - Sun rashi condition
155
+ # if sun_rashi == 'Makar':
156
+ # festival = 'Makar_Sankaranti'
157
+
158
+ return festival
159
+
160
+ def __get_festival_holiday(self, year, month, day, hour, minute, purnimanta):
161
+ __result = self.__get_accurate_panchang(year, month, day, hour, minute, purnimanta)
162
+ __result['festival'] = self.__get_festivals(__result)
163
+
164
+ __holidays = {
165
+ # January
166
+ (1, 1): 'New_Year',
167
+ (1, 12): 'National_Youth_Day',
168
+ (1, 15): 'Indian_Army_Day',
169
+ (1, 23): 'Netaji_Subhash_Chandra_Bose_Jayanti',
170
+ (1, 26): 'Republic_Day',
171
+ (1, 30): 'Martyrs_Day',
172
+
173
+ # Febuary
174
+ (2, 14): 'Valentines_Day/Black_Day',
175
+ (2, 28): 'National_Science_Day',
176
+
177
+ # March
178
+ (3, 8): 'International_Womens_Day',
179
+ (3, 23): 'Shaheed_Diwas_Veer_Bhagat_Singh',
180
+
181
+ # April
182
+ (4, 1): 'April_Fool_Day',
183
+ (4, 7): 'World_Health_Day',
184
+ (4, 17): 'Baba_Shaheb_Ambedkar_Jayanti',
185
+ (4, 22): 'Earth_Day',
186
+
187
+ # May
188
+ (5, 1): 'Labour_Day',
189
+ (5, 8): 'World_Red_Cross_Day',
190
+ (5, 11): 'National_Technology_Day',
191
+ (5, 21): 'Anti_Terrorism_Day',
192
+ (5, 31): 'No_Tobacco_Day',
193
+
194
+ # June
195
+ (6, 5): 'World_Environment_Day',
196
+ (6, 21): 'International_Yoga_Day',
197
+
198
+ # July
199
+ (7, 1): 'Doctors_Day',
200
+ (7, 26): 'Kargil_Vijay_Diwas',
201
+
202
+ # August
203
+ (8, 15): 'Independence_Day',
204
+ (8, 29): 'National_Sports_Day',
205
+
206
+ # September
207
+ (9, 5): 'Teachers_Day',
208
+ (9, 14): 'Hindi_Diwas',
209
+
210
+ # October
211
+ (10, 2): 'Mahatma_Gandhi_Jayanti',
212
+ (10, 8): 'Indian_Air_Force_Day',
213
+ (10, 31): 'National_Unit_Day',
214
+
215
+ # November
216
+ (11, 14): 'Childrens_Day',
217
+ (11, 26): 'Constitution_Day',
218
+
219
+ # December
220
+ (12, 4): 'Indian_Navy_Day',
221
+ (12, 25): 'Christmas'
222
+ }
223
+
224
+ __holiday = __holidays.get((month, day))
225
+
226
+ if __result['festival'] == None:
227
+ __result['festival'] = __holiday
228
+ else:
229
+ # __temp = __result['festival']
230
+ __result['festival'] = __result['festival'] + "/"+ __holiday
231
+
232
+ return __result['festival']
233
+
234
+ def get_festival(self, df: pd.DataFrame, date_col_name: str):
235
+ df[date_col_name] = pd.to_datetime(df[date_col_name], dayfirst=False, format="mixed", errors='coerce')
236
+
237
+ df[date_col_name] = df[date_col_name].apply(lambda x: x.replace(hour=12) if pd.notna(x) and x.hour == 0 else x)
238
+
239
+ df['festival'] = df[date_col_name].apply(lambda date: self.__get_festival_holiday(date.year, date.month, date.day, date.hour, date.minute, purnimanta=True) if pd.notna(date) else None)
240
+
241
+ return df
242
+
243
+
244
+
245
+
246
+ # 9 April 2026 के लिए रन करें
247
+ df = pd.DataFrame({
248
+ "date": [
249
+ '2026-01-26', '2026-05-01 10:30:00',
250
+ '15-08-2026',
251
+ '2026/10/02',
252
+ '2026-12-25 00:00:00',
253
+ None,
254
+ 'invalid_date',
255
+ '2026-11-12',
256
+ '2026-04-01 18:45',
257
+ '2026-03-08',
258
+ '2026-07-26 05:00:00',
259
+ '2026-09-05'
260
+ ]
261
+ })
262
+ # print(df)
263
+
264
+ # hc = Indian_Calendar()
265
+ # df = hc.get_festival(df, 'date')
266
+
267
+ # print(df)
268
+ except Exception as e:
269
+ print(f"Unexpected Error: {e}")
Binary file
@@ -0,0 +1,5 @@
1
+ from .Indian_Calendar import Indian_Calendar
2
+
3
+ # Easy function for users
4
+ def get_festival(df, date_col_name):
5
+ return Indian_Calendar.get_festival(df)
@@ -0,0 +1,10 @@
1
+ Metadata-Version: 2.4
2
+ Name: smart-aj
3
+ Version: 0.3
4
+ Summary: Indian festivals and holidays detection using Panchang & common calendar. Hindus festivals are based on Panchang & holidays are based on common month and day.
5
+ Author: Ajay Sah
6
+ Requires-Dist: pandas
7
+ Requires-Dist: skyfield
8
+ Dynamic: author
9
+ Dynamic: requires-dist
10
+ Dynamic: summary
@@ -0,0 +1,11 @@
1
+ README.md
2
+ pyproject.toml
3
+ setup.py
4
+ smart/Indian_Calendar.py
5
+ smart/Indian_Calendar.pyd
6
+ smart/__init__.py
7
+ smart_aj.egg-info/PKG-INFO
8
+ smart_aj.egg-info/SOURCES.txt
9
+ smart_aj.egg-info/dependency_links.txt
10
+ smart_aj.egg-info/requires.txt
11
+ smart_aj.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ pandas
2
+ skyfield
@@ -0,0 +1 @@
1
+ smart