libaditya 0.3.4__py2.py3-none-any.whl
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.
- libaditya/__init__.py +46 -0
- libaditya/_version.py +29 -0
- libaditya/calc/__init__.py +9 -0
- libaditya/calc/api.py +30 -0
- libaditya/calc/avasthas.py +346 -0
- libaditya/calc/docs/jaimini-get-arch.md +95 -0
- libaditya/calc/hellenistic.py +37 -0
- libaditya/calc/jaimini.py +335 -0
- libaditya/calc/jaimini_get.py +240 -0
- libaditya/calc/kala.py +73 -0
- libaditya/calc/panchanga.py +422 -0
- libaditya/calc/rashi.py +612 -0
- libaditya/calc/returns.py +50 -0
- libaditya/calc/swe_functions.py +118 -0
- libaditya/calc/varga.py +287 -0
- libaditya/calc/vimshottari.py +431 -0
- libaditya/cards/__init__.py +5 -0
- libaditya/cards/card.py +90 -0
- libaditya/cards/cards_constants.py +115 -0
- libaditya/cards/cards_of_truth.py +323 -0
- libaditya/cards/cot.py +142 -0
- libaditya/cards/deck.py +52 -0
- libaditya/charts/__init__.py +6 -0
- libaditya/charts/api.py +36 -0
- libaditya/charts/bodygraph.py +80 -0
- libaditya/charts/chart.py +286 -0
- libaditya/charts/jaimini.py +83 -0
- libaditya/charts/tajika.py +36 -0
- libaditya/constants.py +1776 -0
- libaditya/draw/__init__.py +20 -0
- libaditya/draw/draw_bodygraph.py +489 -0
- libaditya/draw/draw_sbc.py +712 -0
- libaditya/draw/themes/default-theme.hd +53 -0
- libaditya/ephe/ast0/se00010s.se1 +0 -0
- libaditya/ephe/seas_00.se1 +0 -0
- libaditya/ephe/seas_06.se1 +0 -0
- libaditya/ephe/seas_12.se1 +0 -0
- libaditya/ephe/seas_18.se1 +0 -0
- libaditya/ephe/seas_24.se1 +0 -0
- libaditya/ephe/seas_30.se1 +0 -0
- libaditya/ephe/seas_36.se1 +0 -0
- libaditya/ephe/seas_42.se1 +0 -0
- libaditya/ephe/seas_48.se1 +0 -0
- libaditya/ephe/seasm06.se1 +0 -0
- libaditya/ephe/seasm12.se1 +0 -0
- libaditya/ephe/seasm18.se1 +0 -0
- libaditya/ephe/seasm24.se1 +0 -0
- libaditya/ephe/seasm30.se1 +0 -0
- libaditya/ephe/seasm36.se1 +0 -0
- libaditya/ephe/seasm42.se1 +0 -0
- libaditya/ephe/seasm48.se1 +0 -0
- libaditya/ephe/seasm54.se1 +0 -0
- libaditya/ephe/sefstars.txt +4245 -0
- libaditya/ephe/semo_00.se1 +0 -0
- libaditya/ephe/semo_06.se1 +0 -0
- libaditya/ephe/semo_12.se1 +0 -0
- libaditya/ephe/semo_18.se1 +0 -0
- libaditya/ephe/semo_24.se1 +0 -0
- libaditya/ephe/semo_30.se1 +0 -0
- libaditya/ephe/semo_36.se1 +0 -0
- libaditya/ephe/semo_42.se1 +0 -0
- libaditya/ephe/semo_48.se1 +0 -0
- libaditya/ephe/semom06.se1 +0 -0
- libaditya/ephe/semom12.se1 +0 -0
- libaditya/ephe/semom18.se1 +0 -0
- libaditya/ephe/semom24.se1 +0 -0
- libaditya/ephe/semom30.se1 +0 -0
- libaditya/ephe/semom36.se1 +0 -0
- libaditya/ephe/semom42.se1 +0 -0
- libaditya/ephe/semom48.se1 +0 -0
- libaditya/ephe/semom54.se1 +0 -0
- libaditya/ephe/sepl_00.se1 +0 -0
- libaditya/ephe/sepl_06.se1 +0 -0
- libaditya/ephe/sepl_12.se1 +0 -0
- libaditya/ephe/sepl_18.se1 +0 -0
- libaditya/ephe/sepl_24.se1 +0 -0
- libaditya/ephe/sepl_30.se1 +0 -0
- libaditya/ephe/sepl_36.se1 +0 -0
- libaditya/ephe/sepl_42.se1 +0 -0
- libaditya/ephe/sepl_48.se1 +0 -0
- libaditya/ephe/seplm06.se1 +0 -0
- libaditya/ephe/seplm12.se1 +0 -0
- libaditya/ephe/seplm18.se1 +0 -0
- libaditya/ephe/seplm24.se1 +0 -0
- libaditya/ephe/seplm30.se1 +0 -0
- libaditya/ephe/seplm36.se1 +0 -0
- libaditya/ephe/seplm42.se1 +0 -0
- libaditya/ephe/seplm48.se1 +0 -0
- libaditya/ephe/seplm54.se1 +0 -0
- libaditya/hd/__init__.py +8 -0
- libaditya/hd/calc.py +55 -0
- libaditya/hd/constants.py +127 -0
- libaditya/hd/longitude.py +271 -0
- libaditya/objects/__init__.py +19 -0
- libaditya/objects/celestial_object.py +206 -0
- libaditya/objects/context.py +133 -0
- libaditya/objects/cusps.py +259 -0
- libaditya/objects/julian_day.py +265 -0
- libaditya/objects/location.py +167 -0
- libaditya/objects/longitude.py +987 -0
- libaditya/objects/nakshatras.py +285 -0
- libaditya/objects/planets.py +2059 -0
- libaditya/objects/shadbala.py +398 -0
- libaditya/objects/signs.py +690 -0
- libaditya/objects/swe_functions.py +75 -0
- libaditya/print_functions.py +548 -0
- libaditya/read.py +665 -0
- libaditya/stars/__init__.py +4 -0
- libaditya/stars/fixed_star.py +216 -0
- libaditya/stars/make_swe_stars.py +407 -0
- libaditya/stars/star-sign-boundaries +44 -0
- libaditya/stars/stellarium/__init__.py +6 -0
- libaditya/stars/stellarium/remote_control/__init__.py +22 -0
- libaditya/stars/stellarium/remote_control/location.py +82 -0
- libaditya/stars/stellarium/remote_control/locationsearch.py +35 -0
- libaditya/stars/stellarium/remote_control/main.py +165 -0
- libaditya/stars/stellarium/remote_control/objects.py +63 -0
- libaditya/stars/stellarium/remote_control/scripts.py +81 -0
- libaditya/stars/stellarium/remote_control/simbad.py +20 -0
- libaditya/stars/stellarium/remote_control/stelaction.py +31 -0
- libaditya/stars/stellarium/remote_control/stelproperty.py +30 -0
- libaditya/stars/stellarium/remote_control/view.py +85 -0
- libaditya/stars/stellarium/stellarium.py +92 -0
- libaditya/stars/the_stars.py +522 -0
- libaditya/stars/utilities.py +539 -0
- libaditya/utils.py +431 -0
- libaditya/write.py +67 -0
- libaditya-0.3.4.dist-info/METADATA +588 -0
- libaditya-0.3.4.dist-info/RECORD +131 -0
- libaditya-0.3.4.dist-info/WHEEL +5 -0
- libaditya-0.3.4.dist-info/licenses/LICENSE +661 -0
|
@@ -0,0 +1,690 @@
|
|
|
1
|
+
# This file is part of libaditya.
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2025 Josh Harper <humanhaven@substack.com>
|
|
4
|
+
#
|
|
5
|
+
# libaditya is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU Affero General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
#
|
|
10
|
+
# libaditya is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU Affero General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
16
|
+
# along with libaditya. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
import swisseph as swe
|
|
19
|
+
from prettytable import PrettyTable
|
|
20
|
+
from typing import Self
|
|
21
|
+
|
|
22
|
+
from rich import box
|
|
23
|
+
from rich.table import Table
|
|
24
|
+
from rich.console import Console
|
|
25
|
+
|
|
26
|
+
from libaditya import constants as const
|
|
27
|
+
from libaditya import utils
|
|
28
|
+
|
|
29
|
+
from .planets import *
|
|
30
|
+
from .cusps import Cusp, Cusps
|
|
31
|
+
from .context import EphContext
|
|
32
|
+
|
|
33
|
+
class Sign:
|
|
34
|
+
|
|
35
|
+
def __init__(self, number, planets, cusps, context, master):
|
|
36
|
+
self.context = context
|
|
37
|
+
self._planets = planets
|
|
38
|
+
self._cusps = cusps
|
|
39
|
+
self._objects = self.init_objects()
|
|
40
|
+
self._sign_index = (number-1)%12
|
|
41
|
+
self._sign_name = const.names[self.context.names_type][self.context.sign_names][self.sign_index()]
|
|
42
|
+
self._id = number
|
|
43
|
+
self.master = master
|
|
44
|
+
self._lajjitaadi_avasthas = {}
|
|
45
|
+
# a dictionary that defines our rashi aspects, {int: (int,int,int)}
|
|
46
|
+
|
|
47
|
+
def sign_index(self):
|
|
48
|
+
return self._sign_index
|
|
49
|
+
|
|
50
|
+
def sign_name(self):
|
|
51
|
+
return self._sign_name
|
|
52
|
+
|
|
53
|
+
def name(self):
|
|
54
|
+
return self.sign_name()
|
|
55
|
+
|
|
56
|
+
def sign(self):
|
|
57
|
+
return self._id
|
|
58
|
+
|
|
59
|
+
def Self(self):
|
|
60
|
+
return self
|
|
61
|
+
|
|
62
|
+
def planets(self) -> [Planet]:
|
|
63
|
+
"""
|
|
64
|
+
Planet is anything that can possibly be a Planet
|
|
65
|
+
return a list of Planets that are in this sign
|
|
66
|
+
"""
|
|
67
|
+
return self._planets
|
|
68
|
+
|
|
69
|
+
def cusps(self):
|
|
70
|
+
return self._cusps
|
|
71
|
+
|
|
72
|
+
def lajjitaadi_avasthas(self):
|
|
73
|
+
return self._lajjitaadi_avasthas
|
|
74
|
+
|
|
75
|
+
def lord(self) -> str:
|
|
76
|
+
return const.lords[self.sign()]
|
|
77
|
+
|
|
78
|
+
def gender(self):
|
|
79
|
+
if utils.odd(self.sign()):
|
|
80
|
+
return "M"
|
|
81
|
+
if utils.even(self.sign()):
|
|
82
|
+
return "F"
|
|
83
|
+
|
|
84
|
+
def rashis_from_lagna(self):
|
|
85
|
+
"""
|
|
86
|
+
lagna can be a Sign class or a sign number
|
|
87
|
+
how many signs apart are this one sign and other_sign
|
|
88
|
+
if self=12 and other=1 -> (1-12)%12 = 1
|
|
89
|
+
used for temporary relationships
|
|
90
|
+
"""
|
|
91
|
+
lagna = self.master.lagna().sign()
|
|
92
|
+
return ((self.sign() - lagna)%12)+1
|
|
93
|
+
|
|
94
|
+
def house_type(self):
|
|
95
|
+
"""
|
|
96
|
+
is this an Angle, Panaphara, or Apoklima
|
|
97
|
+
this uses signs from lagna to determine this
|
|
98
|
+
"""
|
|
99
|
+
lagna = self.master.lagna()
|
|
100
|
+
signs_from_lagna = self.rashis_from_lagna()
|
|
101
|
+
match signs_from_lagna:
|
|
102
|
+
case 1 | 4 | 7 | 10:
|
|
103
|
+
return "Angle"
|
|
104
|
+
case 2 | 5 | 8 | 11:
|
|
105
|
+
return "Panaphara"
|
|
106
|
+
case 3 | 6 | 9 | 12:
|
|
107
|
+
return "Apoklima"
|
|
108
|
+
|
|
109
|
+
def karakas(self) -> [Planet]:
|
|
110
|
+
"""
|
|
111
|
+
return a list of Planet classes of the karakas in this sign
|
|
112
|
+
karakas are sun-sat
|
|
113
|
+
"""
|
|
114
|
+
ks = []
|
|
115
|
+
for planet in self.planets():
|
|
116
|
+
if planet.is_karaka():
|
|
117
|
+
ks.append(planet)
|
|
118
|
+
return ks
|
|
119
|
+
|
|
120
|
+
def grahas(self) -> [Planet]:
|
|
121
|
+
"""
|
|
122
|
+
return a list of Planet classes of the grahas in this sign
|
|
123
|
+
grahas are sun-ketu
|
|
124
|
+
"""
|
|
125
|
+
gs = []
|
|
126
|
+
for planet in self.planets():
|
|
127
|
+
if planet.is_graha():
|
|
128
|
+
gs.append(planet)
|
|
129
|
+
return gs
|
|
130
|
+
|
|
131
|
+
def how_many_objects(self):
|
|
132
|
+
return len(self._objects)
|
|
133
|
+
|
|
134
|
+
def how_many_karakas(self):
|
|
135
|
+
return len(self.karakas())
|
|
136
|
+
|
|
137
|
+
def how_many_grahas(self):
|
|
138
|
+
return len(self.grahas())
|
|
139
|
+
|
|
140
|
+
def objects(self):
|
|
141
|
+
return self._objects
|
|
142
|
+
|
|
143
|
+
def objects_within_one_degree(self):
|
|
144
|
+
objects = []
|
|
145
|
+
for object_chosen in self.objects():
|
|
146
|
+
for object_line in self.objects():
|
|
147
|
+
if object_chosen == object_line:
|
|
148
|
+
continue
|
|
149
|
+
if abs(object_chosen.amsha_longitude()-object_line.amsha_longitude()) < 1:
|
|
150
|
+
objects.append((object_chosen,object_line))
|
|
151
|
+
return objects
|
|
152
|
+
|
|
153
|
+
def init_objects(self):
|
|
154
|
+
if self.context.sysflg == const.BARY or self.context.sysflg == const.HELIO:
|
|
155
|
+
return self._planets
|
|
156
|
+
else:
|
|
157
|
+
return self._planets + self._cusps
|
|
158
|
+
|
|
159
|
+
def astrological_signs_forward(self,n) -> int:
|
|
160
|
+
"""
|
|
161
|
+
go forward n signs
|
|
162
|
+
this means in the astrologically sense
|
|
163
|
+
so this sign is 1 and then we count
|
|
164
|
+
e.g., if this sign is sign 8 and we go forward 4 signs ->
|
|
165
|
+
8,9,10,11, so 4 signs forwards from Scorpio is Aquarius
|
|
166
|
+
so self.astrological_signs_forward(1) = self
|
|
167
|
+
|
|
168
|
+
but in terms of sign numbers, we add n-1 to the sign number
|
|
169
|
+
and have to deal with how it wraps around
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
"""
|
|
173
|
+
if n == 0 or n == -1:
|
|
174
|
+
return self.sign()
|
|
175
|
+
if n < 0:
|
|
176
|
+
# go backwards
|
|
177
|
+
almost = (self.sign() - (abs(n)-1))%12
|
|
178
|
+
if almost == 0:
|
|
179
|
+
return 12
|
|
180
|
+
else:
|
|
181
|
+
return almost
|
|
182
|
+
forward = self.sign() + (n-1)
|
|
183
|
+
if forward > 0 and forward <= 12:
|
|
184
|
+
return forward
|
|
185
|
+
else:
|
|
186
|
+
return forward % 12
|
|
187
|
+
|
|
188
|
+
def astrological_signs_backward(self, n: int):
|
|
189
|
+
"""
|
|
190
|
+
go backwards n signs in the astrological sense
|
|
191
|
+
this just calls astrological_signs_forward with -n
|
|
192
|
+
"""
|
|
193
|
+
return self.astrological_signs_forward(-n)
|
|
194
|
+
|
|
195
|
+
def astrological_signs_apart(self, other_sign: int) -> int:
|
|
196
|
+
"""
|
|
197
|
+
how many signs apart are this one sign and other_sign
|
|
198
|
+
if self=12 and other=1 -> (1-12)%12 = 1
|
|
199
|
+
astrological means counting in an astrological way
|
|
200
|
+
i.e., signs 10 and 1 are 4 signs apart
|
|
201
|
+
other_sign is the sign number of the other sign
|
|
202
|
+
"""
|
|
203
|
+
return ((other_sign - self.sign())%12)+1
|
|
204
|
+
|
|
205
|
+
def modality(self):
|
|
206
|
+
"""
|
|
207
|
+
return modality "Moveable", "Fixed", "Dual"
|
|
208
|
+
"""
|
|
209
|
+
match self.sign():
|
|
210
|
+
case 1 | 4 | 7 | 10:
|
|
211
|
+
return "Moveable"
|
|
212
|
+
case 2 | 5 | 8 | 11:
|
|
213
|
+
return "Fixed"
|
|
214
|
+
case 3 | 6 | 9 | 12:
|
|
215
|
+
return "Dual"
|
|
216
|
+
|
|
217
|
+
def ordered_cusps(self, reverse=False):
|
|
218
|
+
return sorted(self.cusps(),key = (lambda cusp: cusp.ecliptic_longitude()), reverse=reverse)
|
|
219
|
+
|
|
220
|
+
def ordered_planets(self, reverse=False):
|
|
221
|
+
return sorted(self.planets(),key = (lambda cusp: cusp.ecliptic_longitude()), reverse=reverse)
|
|
222
|
+
|
|
223
|
+
def ordered_objects(self, reverse=False):
|
|
224
|
+
return sorted(self.ordered_cusps() + self.ordered_planets(),key = (lambda obj: obj.amsha_longitude()), reverse=reverse)
|
|
225
|
+
|
|
226
|
+
def __str__(self):
|
|
227
|
+
"""
|
|
228
|
+
a string representation that is used for printing charts
|
|
229
|
+
each objects is listed:
|
|
230
|
+
name
|
|
231
|
+
longitude
|
|
232
|
+
"""
|
|
233
|
+
ret = ""
|
|
234
|
+
|
|
235
|
+
for obj in self.ordered_objects():
|
|
236
|
+
if not self.context.print_outer_planets and obj.object_type()=="Planet" and obj.is_outer_planet():
|
|
237
|
+
# dont print outer objs
|
|
238
|
+
continue
|
|
239
|
+
if obj.identity() == "Sun" and self.context.sysflg == const.HELIO:
|
|
240
|
+
# dont print sun with heliocentric coordinates
|
|
241
|
+
continue
|
|
242
|
+
if (obj.identity() == "Rahu" or obj.identity() == "Ketu") and (self.context.sysflg == const.HELIO or self.context.sysflg == const.BARY):
|
|
243
|
+
# dont print Rahu or Ketu for helio/barycentric
|
|
244
|
+
continue
|
|
245
|
+
if isinstance(obj,Cusp) and (self.context.sysflg == const.HELIO or self.context.sysflg == const.BARY):
|
|
246
|
+
# dont print cusps in heliocentric or barycentric
|
|
247
|
+
continue
|
|
248
|
+
ret += f"{obj.name()} "
|
|
249
|
+
if self.context.signize:
|
|
250
|
+
ret += f"{obj.longitude().split(" ")[0]}\n" # remove the sign name here since we are printing in a south indian chart
|
|
251
|
+
else:
|
|
252
|
+
ret += f"{obj.raw_longitude()}\n" # remove the sign name here since we are printing in a south indian chart
|
|
253
|
+
if self.context.print_nakshatras and (self.context.sysflg != const.BARY and self.context.sysflg != const.HELIO):
|
|
254
|
+
ret += f"{obj.nakshatra_name()} "
|
|
255
|
+
ret += f"{obj.nakshatra().elapsed()}\n"
|
|
256
|
+
ret += "\n"
|
|
257
|
+
|
|
258
|
+
# remove final \n when returning
|
|
259
|
+
return ret[:-1]
|
|
260
|
+
|
|
261
|
+
def __repr__(self):
|
|
262
|
+
header = ""
|
|
263
|
+
header += f"\n{self.sign()=} {self.sign_name()}\t{self.context.amsha}\n"
|
|
264
|
+
output = PrettyTable()
|
|
265
|
+
output.field_names = ["Object", "In Amsha Longitude", "Ecliptic Longitude"]
|
|
266
|
+
output.align["Object"] = "l"
|
|
267
|
+
output.align["In Sign Longitude"] = "r"
|
|
268
|
+
output.align["Ecliptic Longitude"] = "r"
|
|
269
|
+
|
|
270
|
+
for p in self._planets:
|
|
271
|
+
output.add_row([p.name(),p.amsha_in_sign_longitude(),p.raw_longitude()])
|
|
272
|
+
for c in self._cusps:
|
|
273
|
+
output.add_row([c.name(),c.amsha_in_sign_longitude(),c.raw_longitude()])
|
|
274
|
+
|
|
275
|
+
ret = output.get_string(fields=["Object", "In Amsha Longitude", "Ecliptic Longitude"])
|
|
276
|
+
|
|
277
|
+
return header + ret
|
|
278
|
+
|
|
279
|
+
def richDrawing(self, header_style="#6b00ff", info_style="#00ff00"):
|
|
280
|
+
sign = Table(box=box.ROUNDED, style=header_style)
|
|
281
|
+
|
|
282
|
+
# add a "header_style=" argument to change color of this header itself
|
|
283
|
+
sign.add_column(f"{self.sign()} {self.name()}",justify="center",style=info_style)
|
|
284
|
+
|
|
285
|
+
# add objects in rows
|
|
286
|
+
sign_str = self.__str__()
|
|
287
|
+
lines = sign_str.split("\n")
|
|
288
|
+
for line in lines:
|
|
289
|
+
sign.add_row(line)
|
|
290
|
+
|
|
291
|
+
return sign
|
|
292
|
+
|
|
293
|
+
def rich(self):
|
|
294
|
+
console = Console()
|
|
295
|
+
console.print(self.richDrawing())
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
class One(Sign):
|
|
299
|
+
|
|
300
|
+
def __init__(self,planets,cusps,context,master):
|
|
301
|
+
super().__init__(1,planets,cusps,context,master)
|
|
302
|
+
|
|
303
|
+
def modality(self) -> str:
|
|
304
|
+
return "Moveable"
|
|
305
|
+
|
|
306
|
+
def element(self):
|
|
307
|
+
return "Fire"
|
|
308
|
+
|
|
309
|
+
def glyph(self):
|
|
310
|
+
return "♈"
|
|
311
|
+
|
|
312
|
+
class Two(Sign):
|
|
313
|
+
|
|
314
|
+
def __init__(self,planets,cusps,context,master):
|
|
315
|
+
super().__init__(2,planets,cusps,context,master)
|
|
316
|
+
|
|
317
|
+
def modality(self) -> str:
|
|
318
|
+
return "Fixed"
|
|
319
|
+
|
|
320
|
+
def element(self):
|
|
321
|
+
return "Earth"
|
|
322
|
+
|
|
323
|
+
def glyph(self):
|
|
324
|
+
return "♉"
|
|
325
|
+
|
|
326
|
+
class Three(Sign):
|
|
327
|
+
|
|
328
|
+
def __init__(self,planets,cusps,context,master):
|
|
329
|
+
super().__init__(3,planets,cusps,context,master)
|
|
330
|
+
|
|
331
|
+
def modality(self) -> str:
|
|
332
|
+
return "Dual"
|
|
333
|
+
|
|
334
|
+
def element(self):
|
|
335
|
+
return "Air"
|
|
336
|
+
|
|
337
|
+
def glyph(self):
|
|
338
|
+
return "♊"
|
|
339
|
+
|
|
340
|
+
class Four(Sign):
|
|
341
|
+
|
|
342
|
+
def __init__(self,planets,cusps,context,master):
|
|
343
|
+
super().__init__(4,planets,cusps,context,master)
|
|
344
|
+
|
|
345
|
+
def modality(self) -> str:
|
|
346
|
+
return "Moveable"
|
|
347
|
+
|
|
348
|
+
def element(self):
|
|
349
|
+
return "Water"
|
|
350
|
+
|
|
351
|
+
def glyph(self):
|
|
352
|
+
return "♋"
|
|
353
|
+
|
|
354
|
+
class Five(Sign):
|
|
355
|
+
|
|
356
|
+
def __init__(self,planets,cusps,context,master):
|
|
357
|
+
super().__init__(5,planets,cusps,context,master)
|
|
358
|
+
|
|
359
|
+
def modality(self) -> str:
|
|
360
|
+
return "Fixed"
|
|
361
|
+
|
|
362
|
+
def element(self):
|
|
363
|
+
return "Fire"
|
|
364
|
+
|
|
365
|
+
def glyph(self):
|
|
366
|
+
return "♌️"
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
class Six(Sign):
|
|
370
|
+
|
|
371
|
+
def __init__(self,planets,cusps,context,master):
|
|
372
|
+
super().__init__(6,planets,cusps,context,master)
|
|
373
|
+
|
|
374
|
+
def modality(self) -> str:
|
|
375
|
+
return "Dual"
|
|
376
|
+
|
|
377
|
+
def element(self):
|
|
378
|
+
return "Earth"
|
|
379
|
+
|
|
380
|
+
def glyph(self):
|
|
381
|
+
return "♍"
|
|
382
|
+
|
|
383
|
+
class Seven(Sign):
|
|
384
|
+
|
|
385
|
+
def __init__(self,planets,cusps,context,master):
|
|
386
|
+
super().__init__(7,planets,cusps,context,master)
|
|
387
|
+
|
|
388
|
+
def modality(self) -> str:
|
|
389
|
+
return "Moveable"
|
|
390
|
+
|
|
391
|
+
def element(self):
|
|
392
|
+
return "Air"
|
|
393
|
+
|
|
394
|
+
def glyph(self):
|
|
395
|
+
return "♎"
|
|
396
|
+
|
|
397
|
+
class Eight(Sign):
|
|
398
|
+
|
|
399
|
+
def __init__(self,planets,cusps,context,master):
|
|
400
|
+
super().__init__(8,planets,cusps,context,master)
|
|
401
|
+
|
|
402
|
+
def modality(self) -> str:
|
|
403
|
+
return "Fixed"
|
|
404
|
+
|
|
405
|
+
def element(self):
|
|
406
|
+
return "Water"
|
|
407
|
+
|
|
408
|
+
def glyph(self):
|
|
409
|
+
return "♏"
|
|
410
|
+
|
|
411
|
+
class Nine(Sign):
|
|
412
|
+
|
|
413
|
+
def __init__(self,planets,cusps,context,master):
|
|
414
|
+
super().__init__(9,planets,cusps,context,master)
|
|
415
|
+
|
|
416
|
+
def modality(self) -> str:
|
|
417
|
+
return "Dual"
|
|
418
|
+
|
|
419
|
+
def element(self):
|
|
420
|
+
return "Fire"
|
|
421
|
+
|
|
422
|
+
def glyph(self):
|
|
423
|
+
return "♐"
|
|
424
|
+
|
|
425
|
+
class Ten(Sign):
|
|
426
|
+
|
|
427
|
+
def __init__(self,planets,cusps,context,master):
|
|
428
|
+
super().__init__(10,planets,cusps,context,master)
|
|
429
|
+
|
|
430
|
+
def modality(self) -> str:
|
|
431
|
+
return "Moveable"
|
|
432
|
+
|
|
433
|
+
def element(self):
|
|
434
|
+
return "Earth"
|
|
435
|
+
|
|
436
|
+
def glyph(self):
|
|
437
|
+
return "♑"
|
|
438
|
+
|
|
439
|
+
class Eleven(Sign):
|
|
440
|
+
|
|
441
|
+
def __init__(self,planets,cusps,context,master):
|
|
442
|
+
super().__init__(11,planets,cusps,context,master)
|
|
443
|
+
|
|
444
|
+
def modality(self) -> str:
|
|
445
|
+
return "Fixed"
|
|
446
|
+
|
|
447
|
+
def element(self):
|
|
448
|
+
return "Air"
|
|
449
|
+
|
|
450
|
+
def glyph(self):
|
|
451
|
+
return "♒"
|
|
452
|
+
|
|
453
|
+
class Twelve(Sign):
|
|
454
|
+
|
|
455
|
+
def __init__(self,planets,cusps,context,master):
|
|
456
|
+
super().__init__(12,planets,cusps,context,master)
|
|
457
|
+
|
|
458
|
+
def modality(self) -> str:
|
|
459
|
+
return "Dual"
|
|
460
|
+
|
|
461
|
+
def element(self):
|
|
462
|
+
return "Water"
|
|
463
|
+
|
|
464
|
+
def glyph(self):
|
|
465
|
+
return "♓"
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
local_Signs = {
|
|
469
|
+
1: One,
|
|
470
|
+
2: Two,
|
|
471
|
+
3: Three,
|
|
472
|
+
4: Four,
|
|
473
|
+
5: Five,
|
|
474
|
+
6: Six,
|
|
475
|
+
7: Seven,
|
|
476
|
+
8: Eight,
|
|
477
|
+
9: Nine,
|
|
478
|
+
10: Ten,
|
|
479
|
+
11: Eleven,
|
|
480
|
+
12: Twelve
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
class Signs:
|
|
484
|
+
|
|
485
|
+
def __init__(self, planets=Planets(), cusps=Cusps(), context=EphContext()):
|
|
486
|
+
self.context = context
|
|
487
|
+
self._planets = planets
|
|
488
|
+
self._cusps = cusps
|
|
489
|
+
self.circle = self.context.circle
|
|
490
|
+
self.aspects = const.rashi_aspects[self.context.rashi_aspects]
|
|
491
|
+
self._signs = self.init_Signs()
|
|
492
|
+
self.sysflgstr = const.sysflgstr(context.sysflg)
|
|
493
|
+
|
|
494
|
+
def __iter__(self):
|
|
495
|
+
return iter(self._signs.values())
|
|
496
|
+
|
|
497
|
+
def __getitem__(self,n: int) -> Self:
|
|
498
|
+
"""
|
|
499
|
+
s=Signs(), then you can write
|
|
500
|
+
then you can write s[key] with key between 1 and 12 inclusive
|
|
501
|
+
modified so you can use negatives to go backwards
|
|
502
|
+
astrologal then means that
|
|
503
|
+
"""
|
|
504
|
+
|
|
505
|
+
return self._signs[n]
|
|
506
|
+
|
|
507
|
+
def keys(self):
|
|
508
|
+
"""
|
|
509
|
+
say s=Signs()
|
|
510
|
+
without this method, i have to do s.signs().keys()
|
|
511
|
+
s.signs() is the dictionary of signs
|
|
512
|
+
with this, i can just write s.keys()
|
|
513
|
+
"""
|
|
514
|
+
return self._signs.keys()
|
|
515
|
+
|
|
516
|
+
def amsha(self):
|
|
517
|
+
return self.context.amsha
|
|
518
|
+
|
|
519
|
+
def __str__(self):
|
|
520
|
+
ret = ""
|
|
521
|
+
ret += self.mkheader()
|
|
522
|
+
|
|
523
|
+
for number,sign in self._signs.items():
|
|
524
|
+
ret += f"{number}: {sign}\n"
|
|
525
|
+
ret += "\n"
|
|
526
|
+
|
|
527
|
+
return ret
|
|
528
|
+
|
|
529
|
+
def init_Signs(self):
|
|
530
|
+
"""
|
|
531
|
+
initialize signs
|
|
532
|
+
first go through all the planets and cusps
|
|
533
|
+
and put them in the right holding place in "signs", then
|
|
534
|
+
initialize a list of Sign classes
|
|
535
|
+
"""
|
|
536
|
+
stmp = [[[],[]] for x in range(0,12)]
|
|
537
|
+
# do planets first, inner index = 0
|
|
538
|
+
inner_index = 0
|
|
539
|
+
for p in self._planets:
|
|
540
|
+
stmp[p.amsha_sign_index()][inner_index].append(p)
|
|
541
|
+
# now do cusps
|
|
542
|
+
inner_index = 1
|
|
543
|
+
for c in self._cusps:
|
|
544
|
+
stmp[c.amsha_sign_index()][inner_index].append(c)
|
|
545
|
+
retsigns={}
|
|
546
|
+
for n, sign in enumerate(stmp):
|
|
547
|
+
retsigns[n+1] = local_Signs[n+1](planets=sign[0],cusps=sign[1],context=self.context,master=self)
|
|
548
|
+
return retsigns
|
|
549
|
+
|
|
550
|
+
def signs(self):
|
|
551
|
+
return self._signs
|
|
552
|
+
|
|
553
|
+
def rashi_aspect_between(self, sign1: Sign, sign2: Sign):
|
|
554
|
+
"""
|
|
555
|
+
tells if there are rashi aspects between sign1 and sign2
|
|
556
|
+
0 - none either way
|
|
557
|
+
1 - sign1 aspects sign2
|
|
558
|
+
2 - sign2 aspects sign1
|
|
559
|
+
3 - both aspect each other
|
|
560
|
+
i.e., sign1 aspects means that there is at least one graha in sign1 caring its aspect to sign2
|
|
561
|
+
"""
|
|
562
|
+
ltr = self.rashi_aspect_from_to(sign1,sign2)
|
|
563
|
+
rtl = self.rashi_aspect_from_to(sign2,sign1)
|
|
564
|
+
match (ltr,rtl):
|
|
565
|
+
case (0,0):
|
|
566
|
+
return 0
|
|
567
|
+
case (1,0):
|
|
568
|
+
return 1
|
|
569
|
+
case (0,1):
|
|
570
|
+
return 2
|
|
571
|
+
case (1,1):
|
|
572
|
+
return 3
|
|
573
|
+
|
|
574
|
+
def rashi_aspect_from_to(self, sign1: Sign, sign2: Sign):
|
|
575
|
+
"""
|
|
576
|
+
tells if there are rashi aspects between sign1 and sign2
|
|
577
|
+
0 - none either way
|
|
578
|
+
1 - sign1 aspects sign2
|
|
579
|
+
i.e., sign1 aspects means that there is at least one graha in sign1 caring its aspect to sign2
|
|
580
|
+
"""
|
|
581
|
+
if not (sign2.sign() in self.aspects[sign1.sign()]):
|
|
582
|
+
# sign1 is the key to the aspects dictionary
|
|
583
|
+
# the value is a tuple of integers, the signs which sign1 aspects
|
|
584
|
+
# if sign2 is one of those signs, then sign1 can aspect, depending
|
|
585
|
+
# on planets in a sign
|
|
586
|
+
# so if not, return 0, meaning no aspect
|
|
587
|
+
return 0
|
|
588
|
+
# else: sign1 can aspect sign2; if sign1 does have a graha, it aspects, so return 1
|
|
589
|
+
# needs to be grahas; not .planets(), that includes Uranus, etc.
|
|
590
|
+
if sign1.grahas():
|
|
591
|
+
return 1
|
|
592
|
+
else:
|
|
593
|
+
# 0 means there is no aspect. there could be if there were a planet, but there isnt so no planet
|
|
594
|
+
return 0
|
|
595
|
+
|
|
596
|
+
def rashi_aspects_given_by(self, sign: Sign) -> [Sign]:
|
|
597
|
+
"""
|
|
598
|
+
get Signs that rashi aspect Sign sign
|
|
599
|
+
"""
|
|
600
|
+
# sign aspects 3 signs
|
|
601
|
+
# those 3 signs aspect this sign
|
|
602
|
+
# for practical purposes, we want to know which of these 3 signs has grahas in them
|
|
603
|
+
# for this purpose, only the Sign-s of those three that grahas are returned
|
|
604
|
+
aspected_signs = self.aspects[sign.sign()]
|
|
605
|
+
ret = []
|
|
606
|
+
for aspected_sign in [self.signs()[each] for each in aspected_signs]:
|
|
607
|
+
if self.rashi_aspect_from_to(aspected_sign,sign):
|
|
608
|
+
ret.append(aspected_sign)
|
|
609
|
+
return ret
|
|
610
|
+
|
|
611
|
+
def rashi_aspects_given_to(self, sign: Sign) -> [Sign]:
|
|
612
|
+
"""
|
|
613
|
+
get Signs that rashi aspect Sign sign
|
|
614
|
+
"""
|
|
615
|
+
# sign aspects 3 signs
|
|
616
|
+
# those 3 signs aspect this sign
|
|
617
|
+
# for practical purposes, we want to know which of these 3 signs has grahas in them
|
|
618
|
+
# for this purpose, only the Sign-s of those three that grahas are returned
|
|
619
|
+
aspecting_signs = self.aspects[sign.sign()]
|
|
620
|
+
ret = []
|
|
621
|
+
for aspecting_sign in [self.signs()[each] for each in aspecting_signs]:
|
|
622
|
+
if self.rashi_aspect_from_to(aspecting_sign,sign):
|
|
623
|
+
ret.append(aspecting_sign)
|
|
624
|
+
return ret
|
|
625
|
+
|
|
626
|
+
def lagna(self) -> Sign:
|
|
627
|
+
"""
|
|
628
|
+
return the Sign class of the lagna sign, i.e., whichever one has Cusp 1
|
|
629
|
+
"""
|
|
630
|
+
return self.where_is(1) # 1 means Cusp 1
|
|
631
|
+
|
|
632
|
+
def where_is(self, object: int | str) -> Sign:
|
|
633
|
+
"""
|
|
634
|
+
if object is int, a Cusp
|
|
635
|
+
if object is str, a Planet id
|
|
636
|
+
return the Sign class that has in it object
|
|
637
|
+
"""
|
|
638
|
+
if isinstance(object, Planet):
|
|
639
|
+
object = object.identity()
|
|
640
|
+
if isinstance(object, Cusp):
|
|
641
|
+
object = object.number()
|
|
642
|
+
for sign in self:
|
|
643
|
+
if isinstance(object, str):
|
|
644
|
+
for planet in sign.planets():
|
|
645
|
+
if object == planet.identity():
|
|
646
|
+
return sign
|
|
647
|
+
if isinstance(object, int):
|
|
648
|
+
for cusp in sign.cusps():
|
|
649
|
+
if object == cusp.number():
|
|
650
|
+
return sign
|
|
651
|
+
|
|
652
|
+
def get_signs_of(self, planet: Planet | str) -> [Sign]:
|
|
653
|
+
"""
|
|
654
|
+
get the signs of Planet, either a Planet class or a Planet.identity
|
|
655
|
+
"""
|
|
656
|
+
ret = []
|
|
657
|
+
# find the lord string of the Planet
|
|
658
|
+
if isinstance(planet, Planet):
|
|
659
|
+
planet = planet.identity()
|
|
660
|
+
for sign in self:
|
|
661
|
+
if sign.lord() == planet:
|
|
662
|
+
ret.append(sign)
|
|
663
|
+
return ret
|
|
664
|
+
|
|
665
|
+
def most_objects(self):
|
|
666
|
+
"""
|
|
667
|
+
return the number of objects that is greatest of any sign
|
|
668
|
+
"""
|
|
669
|
+
most=0
|
|
670
|
+
for sign in self:
|
|
671
|
+
if sign.how_many_objects() > most:
|
|
672
|
+
most = sign.how_many_objects()
|
|
673
|
+
return most
|
|
674
|
+
|
|
675
|
+
def mkheader(self):
|
|
676
|
+
return utils.mkheader(self)
|
|
677
|
+
|
|
678
|
+
# this is to placate a field in utils.mkheader()
|
|
679
|
+
# this information is in Varga and is not really necessary
|
|
680
|
+
# since we do know the amsha
|
|
681
|
+
def varga_name(self):
|
|
682
|
+
return ""
|
|
683
|
+
|
|
684
|
+
def __repr__(self):
|
|
685
|
+
"""
|
|
686
|
+
represents as a header with the chart information
|
|
687
|
+
"""
|
|
688
|
+
return self.mkheader()
|
|
689
|
+
|
|
690
|
+
|