kerykeion 4.5.1__py3-none-any.whl → 4.6.1__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.

Potentially problematic release.


This version of kerykeion might be problematic. Click here for more details.

kerykeion/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- This is part of Kerykeion (C) 2023 Giacomo Battaglia
3
+ This is part of Kerykeion (C) 2024 Giacomo Battaglia
4
4
 
5
5
  Kerykeion is a python library for Astrology.
6
6
  It can calculate all the planet and house position,
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- This is part of Kerykeion (C) 2023 Giacomo Battaglia
3
+ This is part of Kerykeion (C) 2024 Giacomo Battaglia
4
4
 
5
5
  The aspects module contains the classes and functions for calculating
6
6
  aspects between planets and points in a chart.
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- This is part of Kerykeion (C) 2023 Giacomo Battaglia
3
+ This is part of Kerykeion (C) 2024 Giacomo Battaglia
4
4
  """
5
5
  # TODO: Better documentation and unit tests
6
6
 
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- This is part of Kerykeion (C) 2023 Giacomo Battaglia
3
+ This is part of Kerykeion (C) 2024 Giacomo Battaglia
4
4
  """
5
5
 
6
6
  from pathlib import Path
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- This is part of Kerykeion (C) 2023 Giacomo Battaglia
3
+ This is part of Kerykeion (C) 2024 Giacomo Battaglia
4
4
  """
5
5
 
6
6
  from kerykeion import AstrologicalSubject
@@ -1,9 +1,8 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- This is part of Kerykeion (C) 2023 Giacomo Battaglia
3
+ This is part of Kerykeion (C) 2024 Giacomo Battaglia
4
4
  """
5
5
 
6
- import math
7
6
  import pytz
8
7
  import swisseph as swe
9
8
  import logging
@@ -17,7 +16,13 @@ from kerykeion.kr_types import (
17
16
  LunarPhaseModel,
18
17
  KerykeionPointModel,
19
18
  )
20
- from kerykeion.utilities import get_number_from_name, calculate_position
19
+ from kerykeion.utilities import (
20
+ get_number_from_name,
21
+ calculate_position,
22
+ get_planet_house,
23
+ get_moon_emoji_from_phase_int,
24
+ get_moon_phase_name_from_phase_int,
25
+ )
21
26
  from pathlib import Path
22
27
  from typing import Union, Literal
23
28
 
@@ -431,64 +436,21 @@ class AstrologicalSubject:
431
436
  """Calculates the house of the planet and updates
432
437
  the planets dictionary."""
433
438
 
434
- def for_every_planet(planet, planet_deg):
435
- """Function to do the calculation.
436
- Args: planet dictionary, planet degree"""
437
-
438
- def point_between(p1, p2, p3):
439
- """Finds if a point is between two other in a circle
440
- args: first point, second point, point in the middle"""
441
- p1_p2 = math.fmod(p2 - p1 + 360, 360)
442
- p1_p3 = math.fmod(p3 - p1 + 360, 360)
443
- if (p1_p2 <= 180) != (p1_p3 > p1_p2):
444
- return True
445
- else:
446
- return False
447
-
448
- if point_between(self.houses_degree_ut[0], self.houses_degree_ut[1], planet_deg) == True:
449
- planet["house"] = "First_House"
450
- elif point_between(self.houses_degree_ut[1], self.houses_degree_ut[2], planet_deg) == True:
451
- planet["house"] = "Second_House"
452
- elif point_between(self.houses_degree_ut[2], self.houses_degree_ut[3], planet_deg) == True:
453
- planet["house"] = "Third_House"
454
- elif point_between(self.houses_degree_ut[3], self.houses_degree_ut[4], planet_deg) == True:
455
- planet["house"] = "Fourth_House"
456
- elif point_between(self.houses_degree_ut[4], self.houses_degree_ut[5], planet_deg) == True:
457
- planet["house"] = "Fifth_House"
458
- elif point_between(self.houses_degree_ut[5], self.houses_degree_ut[6], planet_deg) == True:
459
- planet["house"] = "Sixth_House"
460
- elif point_between(self.houses_degree_ut[6], self.houses_degree_ut[7], planet_deg) == True:
461
- planet["house"] = "Seventh_House"
462
- elif point_between(self.houses_degree_ut[7], self.houses_degree_ut[8], planet_deg) == True:
463
- planet["house"] = "Eighth_House"
464
- elif point_between(self.houses_degree_ut[8], self.houses_degree_ut[9], planet_deg) == True:
465
- planet["house"] = "Ninth_House"
466
- elif point_between(self.houses_degree_ut[9], self.houses_degree_ut[10], planet_deg) == True:
467
- planet["house"] = "Tenth_House"
468
- elif point_between(self.houses_degree_ut[10], self.houses_degree_ut[11], planet_deg) == True:
469
- planet["house"] = "Eleventh_House"
470
- elif point_between(self.houses_degree_ut[11], self.houses_degree_ut[0], planet_deg) == True:
471
- planet["house"] = "Twelfth_House"
472
- else:
473
- planet["house"] = "error!"
474
-
475
- return planet
476
-
477
- self.sun = for_every_planet(self.sun, self.planets_degrees_ut[0])
478
- self.moon = for_every_planet(self.moon, self.planets_degrees_ut[1])
479
- self.mercury = for_every_planet(self.mercury, self.planets_degrees_ut[2])
480
- self.venus = for_every_planet(self.venus, self.planets_degrees_ut[3])
481
- self.mars = for_every_planet(self.mars, self.planets_degrees_ut[4])
482
- self.jupiter = for_every_planet(self.jupiter, self.planets_degrees_ut[5])
483
- self.saturn = for_every_planet(self.saturn, self.planets_degrees_ut[6])
484
- self.uranus = for_every_planet(self.uranus, self.planets_degrees_ut[7])
485
- self.neptune = for_every_planet(self.neptune, self.planets_degrees_ut[8])
486
- self.pluto = for_every_planet(self.pluto, self.planets_degrees_ut[9])
487
- self.mean_node = for_every_planet(self.mean_node, self.planets_degrees_ut[10])
488
- self.true_node = for_every_planet(self.true_node, self.planets_degrees_ut[11])
439
+ self.sun.house = get_planet_house(self.planets_degrees_ut[0], self.houses_degree_ut)
440
+ self.moon.house = get_planet_house(self.planets_degrees_ut[1], self.houses_degree_ut)
441
+ self.mercury.house = get_planet_house(self.planets_degrees_ut[2], self.houses_degree_ut)
442
+ self.venus.house = get_planet_house(self.planets_degrees_ut[3], self.houses_degree_ut)
443
+ self.mars.house = get_planet_house(self.planets_degrees_ut[4], self.houses_degree_ut)
444
+ self.jupiter.house = get_planet_house(self.planets_degrees_ut[5], self.houses_degree_ut)
445
+ self.saturn.house = get_planet_house(self.planets_degrees_ut[6], self.houses_degree_ut)
446
+ self.uranus.house = get_planet_house(self.planets_degrees_ut[7], self.houses_degree_ut)
447
+ self.neptune.house = get_planet_house(self.planets_degrees_ut[8], self.houses_degree_ut)
448
+ self.pluto.house = get_planet_house(self.planets_degrees_ut[9], self.houses_degree_ut)
449
+ self.mean_node.house = get_planet_house(self.planets_degrees_ut[10], self.houses_degree_ut)
450
+ self.true_node.house = get_planet_house(self.planets_degrees_ut[11], self.houses_degree_ut)
489
451
 
490
452
  if not self.disable_chiron:
491
- self.chiron = for_every_planet(self.chiron, self.planets_degrees_ut[12])
453
+ self.chiron.house = get_planet_house(self.planets_degrees_ut[12], self.houses_degree_ut)
492
454
  else:
493
455
  self.chiron = None
494
456
 
@@ -583,33 +545,12 @@ class AstrologicalSubject:
583
545
  if degrees_between >= low and degrees_between < high:
584
546
  sun_phase = x + 1
585
547
 
586
- def moon_emoji(phase):
587
- if phase == 1:
588
- result = "🌑"
589
- elif phase < 7:
590
- result = "🌒"
591
- elif 7 <= phase <= 9:
592
- result = "🌓"
593
- elif phase < 14:
594
- result = "🌔"
595
- elif phase == 14:
596
- result = "🌕"
597
- elif phase < 20:
598
- result = "🌖"
599
- elif 20 <= phase <= 22:
600
- result = "🌗"
601
- elif phase <= 28:
602
- result = "🌘"
603
- else:
604
- result = phase
605
-
606
- return result
607
-
608
548
  lunar_phase_dictionary = {
609
549
  "degrees_between_s_m": degrees_between,
610
550
  "moon_phase": moon_phase,
611
551
  "sun_phase": sun_phase,
612
- "moon_emoji": moon_emoji(moon_phase),
552
+ "moon_emoji": get_moon_emoji_from_phase_int(moon_phase),
553
+ "moon_phase_name": get_moon_phase_name_from_phase_int(moon_phase)
613
554
  }
614
555
 
615
556
  self.lunar_phase = LunarPhaseModel(**lunar_phase_dictionary)
@@ -1,5 +1,5 @@
1
1
  """
2
- This is part of Kerykeion (C) 2023 Giacomo Battaglia
2
+ This is part of Kerykeion (C) 2024 Giacomo Battaglia
3
3
 
4
4
  This modules contains the charts logic for the Kerykeion project.
5
5
  """
@@ -1,6 +1,6 @@
1
1
  import math
2
2
  import datetime
3
- from kerykeion.kr_types import KerykeionException
3
+ from kerykeion.kr_types import KerykeionException, ChartType
4
4
  from typing import Union
5
5
 
6
6
  def decHourJoin(inH: int, inM: int, inS: int) -> float:
@@ -108,3 +108,52 @@ def sliceToY(slice: Union[int, float], r: Union[int, float], offset: Union[int,
108
108
  plus = (math.pi * offset) / 180
109
109
  radial = ((math.pi / 6) * slice) + plus
110
110
  return r * ((math.sin(radial) / -1) + 1)
111
+
112
+
113
+ def draw_zodiac_slice(
114
+ c1: Union[int, float],
115
+ chart_type: ChartType,
116
+ sixth_house_degree_ut: Union[int, float],
117
+ num: int,
118
+ r: Union[int, float],
119
+ style: str,
120
+ type: str,
121
+ ):
122
+ """
123
+ Draws a zodiac slice based on the given parameters.
124
+
125
+ Args:
126
+ - c1 (Union[int, float]): The value of c1.
127
+ - chart_type (Literal["Natal", "ExternalNatal", "Synastry", "Transit"]): The type of chart.
128
+ - sixth_house_degree_ut (Union[int, float]): The degree of the sixth house.
129
+ - num (int): The number of the sign. Note: In OpenAstro it did refer to self.zodiac,
130
+ which is a list of the signs in order, starting with Aries. Eg:
131
+ {"name": "aries", "element": "fire"}
132
+ - r (Union[int, float]): The value of r.
133
+ - style (str): The CSS inline style.
134
+ - type (str): The type ?. In OpenAstro, it was the symbol of the sign. Eg: "aries".
135
+ self.zodiac[i]["name"]
136
+
137
+ Returns:
138
+ - str: The zodiac slice and symbol as an SVG path.
139
+ """
140
+
141
+ # pie slices
142
+ offset = 360 - sixth_house_degree_ut
143
+ # check transit
144
+ if chart_type == "Transit" or chart_type == "Synastry":
145
+ dropin = 0
146
+ else:
147
+ dropin = c1
148
+ slice = f'<path d="M{str(r)},{str(r)} L{str(dropin + sliceToX(num, r - dropin, offset))},{str(dropin + sliceToY(num, r - dropin, offset))} A{str(r - dropin)},{str(r - dropin)} 0 0,0 {str(dropin + sliceToX(num + 1, r - dropin, offset))},{str(dropin + sliceToY(num + 1, r - dropin, offset))} z" style="{style}"/>'
149
+
150
+ # symbols
151
+ offset = offset + 15
152
+ # check transit
153
+ if chart_type == "Transit" or chart_type == "Synastry":
154
+ dropin = 54
155
+ else:
156
+ dropin = 18 + c1
157
+ sign = f'<g transform="translate(-16,-16)"><use x="{str(dropin + sliceToX(num, r - dropin, offset))}" y="{str(dropin + sliceToY(num, r - dropin, offset))}" xlink:href="#{type}" /></g>'
158
+
159
+ return slice + "" + sign
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- This is part of Kerykeion (C) 2023 Giacomo Battaglia
3
+ This is part of Kerykeion (C) 2024 Giacomo Battaglia
4
4
  """
5
5
 
6
6
 
@@ -14,7 +14,7 @@ from kerykeion.aspects.natal_aspects import NatalAspects
14
14
  from kerykeion.astrological_subject import AstrologicalSubject
15
15
  from kerykeion.kr_types import KerykeionException, ChartType
16
16
  from kerykeion.kr_types import ChartTemplateDictionary
17
- from kerykeion.charts.charts_utils import decHourJoin, degreeDiff, offsetToTz, sliceToX, sliceToY
17
+ from kerykeion.charts.charts_utils import decHourJoin, degreeDiff, offsetToTz, sliceToX, sliceToY, draw_zodiac_slice
18
18
  from pathlib import Path
19
19
  from string import Template
20
20
  from typing import Union
@@ -371,39 +371,30 @@ class KerykeionChartSVG:
371
371
 
372
372
  return out
373
373
 
374
- def _zodiacSlice(self, num, r, style, type):
375
- # pie slices
376
- offset = 360 - self.user.houses_degree_ut[6]
377
- # check transit
378
- if self.chart_type == "Transit" or self.chart_type == "Synastry":
379
- dropin = 0
380
- else:
381
- dropin = self.c1
382
- slice = f'<path d="M{str(r)},{str(r)} L{str(dropin + sliceToX(num, r - dropin, offset))},{str(dropin + sliceToY(num, r - dropin, offset))} A{str(r - dropin)},{str(r - dropin)} 0 0,0 {str(dropin + sliceToX(num + 1, r - dropin, offset))},{str(dropin + sliceToY(num + 1, r - dropin, offset))} z" style="{style}"/>'
374
+ def _draw_zodiac_circle_slices(self, r):
375
+ """
376
+ Generate the SVG string representing the zodiac circle
377
+ with the 12 slices for each zodiac sign.
383
378
 
384
- # symbols
385
- offset = offset + 15
386
- # check transit
387
- if self.chart_type == "Transit" or self.chart_type == "Synastry":
388
- dropin = 54
389
- else:
390
- dropin = 18 + self.c1
391
- sign = f'<g transform="translate(-16,-16)"><use x="{str(dropin + sliceToX(num, r - dropin, offset))}" y="{str(dropin + sliceToY(num, r - dropin, offset))}" xlink:href="#{type}" /></g>'
379
+ Args:
380
+ r (float): The radius of the zodiac slices.
392
381
 
393
- return slice + "" + sign
382
+ Returns:
383
+ str: The SVG string representing the zodiac circle.
384
+ """
394
385
 
395
- def _makeZodiac(self, r):
396
386
  output = ""
397
- for i in range(len(self.zodiac)):
398
- output = (
399
- output
400
- + self._zodiacSlice(
401
- i,
402
- r,
403
- f'fill:{self.chart_colors_settings[f"zodiac_bg_{i}"]}; fill-opacity: 0.5;',
404
- self.zodiac[i]["name"],
405
- )
387
+ for i, zodiac_element in enumerate(self.zodiac):
388
+ output += draw_zodiac_slice(
389
+ c1=self.c1,
390
+ chart_type=self.chart_type,
391
+ sixth_house_degree_ut=self.user.houses_degree_ut[6],
392
+ num=i,
393
+ r=r,
394
+ style=f'fill:{self.chart_colors_settings[f"zodiac_bg_{i}"]}; fill-opacity: 0.5;',
395
+ type=zodiac_element["name"],
406
396
  )
397
+
407
398
  return output
408
399
 
409
400
  def _makeHouses(self, r):
@@ -1210,40 +1201,47 @@ class KerykeionChartSVG:
1210
1201
  return out
1211
1202
 
1212
1203
  def _makeHousesGrid(self):
1213
- out = '<g transform="translate(600,-20)">'
1204
+ """
1205
+ Generate SVG code for a grid of astrological houses.
1214
1206
 
1215
- li = 10
1207
+ Returns:
1208
+ str: The SVG code for the grid of houses.
1209
+ """
1210
+ # Initialize the SVG group for the grid
1211
+ grid_svg = '<g transform="translate(600,-20)">'
1212
+
1213
+ # Vertical position of the current house in the grid
1214
+ vertical_position = 10
1215
+
1216
+ # Generate SVG code for each house
1216
1217
  for i in range(12):
1217
- if i < 9:
1218
- cusp = "&#160;&#160;" + str(i + 1)
1219
- else:
1220
- cusp = str(i + 1)
1221
- out += f'<g transform="translate(0,{li})">'
1222
- out += f'<text text-anchor="end" x="40" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["cusp"]} {cusp}:</text>'
1223
- out += f'<g transform="translate(40,-8)"><use transform="scale(0.3)" xlink:href="#{self.zodiac[self.houses_sign_graph[i]]["name"]}" /></g>'
1224
- out += f'<text x="53" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;"> {self._dec2deg(self.user.houses_list[i]["position"])}</text>'
1225
- out += "</g>"
1226
- li = li + 14
1218
+ # Add leading spaces to single-digit house numbers for alignment
1219
+ house_number = str(i + 1).rjust(2, ' ')
1227
1220
 
1228
- out += "</g>"
1221
+ # Start a new SVG group for the current house
1222
+ grid_svg += f'<g transform="translate(0,{vertical_position})">'
1229
1223
 
1230
- if self.chart_type == "Synastry":
1231
- out += '<g transform="translate(840, -20)">'
1232
- li = 10
1233
- for i in range(12):
1234
- if i < 9:
1235
- cusp = "&#160;&#160;" + str(i + 1)
1236
- else:
1237
- cusp = str(i + 1)
1238
- out += '<g transform="translate(0,' + str(li) + ')">'
1239
- out += f'<text text-anchor="end" x="40" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["cusp"]} {cusp}:</text>'
1240
- out += f'<g transform="translate(40,-8)"><use transform="scale(0.3)" xlink:href="#{self.zodiac[self.t_houses_sign_graph[i]]["name"]}" /></g>'
1241
- out += f'<text x="53" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;"> {self._dec2deg(self.t_user.houses_list[i]["position"])}</text>'
1242
- out += "</g>"
1243
- li = li + 14
1244
- out += "</g>"
1224
+ # Add the house label
1225
+ grid_svg += f'<text text-anchor="end" x="40" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["cusp"]} {house_number}:</text>'
1245
1226
 
1246
- return out
1227
+ # Add the zodiac sign symbol for the house
1228
+ zodiac_sign = self.zodiac[self.houses_sign_graph[i]]["name"]
1229
+ grid_svg += f'<g transform="translate(40,-8)"><use transform="scale(0.3)" xlink:href="#{zodiac_sign}" /></g>'
1230
+
1231
+ # Add the position of the house
1232
+ house_position = self._dec2deg(self.user.houses_list[i]["position"])
1233
+ grid_svg += f'<text x="53" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;"> {house_position}</text>'
1234
+
1235
+ # End the SVG group for the current house
1236
+ grid_svg += "</g>"
1237
+
1238
+ # Move down for the next house
1239
+ vertical_position += 14
1240
+
1241
+ # End the SVG group for the grid
1242
+ grid_svg += "</g>"
1243
+
1244
+ return grid_svg
1247
1245
 
1248
1246
  def _createTemplateDictionary(self) -> ChartTemplateDictionary:
1249
1247
  # self.chart_type = "Transit"
@@ -1446,8 +1444,13 @@ class KerykeionChartSVG:
1446
1444
  td["cfgRotate"] = rotate
1447
1445
  td["cfgTranslate"] = translate
1448
1446
 
1449
- # functions
1450
- td["makeZodiac"] = self._makeZodiac(r)
1447
+ # ---
1448
+ # Drawing Functions
1449
+ #---
1450
+
1451
+ # Drawing the Zodiac slices
1452
+ td["makeZodiac"] = self._draw_zodiac_circle_slices(r)
1453
+ # TODO: Add the rest of the functions
1451
1454
  td["makeHouses"] = self._makeHouses(r)
1452
1455
  td["makePlanets"] = self._make_planets(r)
1453
1456
  td["makeElements"] = self._makeElements(r)
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- This is part of Kerykeion (C) 2023 Giacomo Battaglia
3
+ This is part of Kerykeion (C) 2024 Giacomo Battaglia
4
4
  """
5
5
 
6
6
 
@@ -1,3 +1,8 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ This is part of Kerykeion (C) 2024 Giacomo Battaglia
4
+ """
5
+
1
6
  from .kerykeion_exception import KerykeionException
2
7
  from .kr_literals import *
3
8
  from .kr_models import *
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- This is part of Kerykeion (C) 2023 Giacomo Battaglia
3
+ This is part of Kerykeion (C) 2024 Giacomo Battaglia
4
4
  """
5
5
 
6
6
 
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- This is part of Kerykeion (C) 2023 Giacomo Battaglia
3
+ This is part of Kerykeion (C) 2024 Giacomo Battaglia
4
4
  """
5
5
 
6
6
 
@@ -56,3 +56,13 @@ Quality = Literal[
56
56
  ChartType = Literal["Natal", "ExternalNatal", "Synastry", "Transit"]
57
57
 
58
58
  LunarPhaseEmoji = Literal["🌑", "🌒", "🌓", "🌔", "🌕", "🌖", "🌗", "🌘"]
59
+ LunarPhaseName = Literal[
60
+ "New Moon",
61
+ "Waxing Crescent",
62
+ "First Quarter",
63
+ "Waxing Gibbous",
64
+ "Full Moon",
65
+ "Waning Gibbous",
66
+ "Last Quarter",
67
+ "Waning Crescent"
68
+ ]
@@ -1,13 +1,13 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- This is part of Kerykeion (C) 2023 Giacomo Battaglia
3
+ This is part of Kerykeion (C) 2024 Giacomo Battaglia
4
4
  """
5
5
 
6
6
 
7
7
  from typing import Literal, Union, Optional
8
8
  from pydantic import BaseModel
9
9
 
10
- from .kr_literals import *
10
+ from kerykeion.kr_types import LunarPhaseEmoji, LunarPhaseName, Planet, Houses, Quality, Element, Sign, ZodiacType
11
11
 
12
12
 
13
13
  class LunarPhaseModel(BaseModel):
@@ -15,11 +15,12 @@ class LunarPhaseModel(BaseModel):
15
15
  moon_phase: int
16
16
  sun_phase: int
17
17
  moon_emoji: LunarPhaseEmoji
18
+ moon_phase_name: LunarPhaseName
18
19
 
19
20
  def __str__(self):
20
21
  return (
21
22
  super()
22
- .dict(
23
+ .model_dump(
23
24
  exclude_none=True,
24
25
  exclude_unset=True,
25
26
  exclude_defaults=True,
@@ -73,7 +74,7 @@ class KerykeionPointModel(BaseModel):
73
74
  def __str__(self):
74
75
  return (
75
76
  super()
76
- .dict(
77
+ .model_dump(
77
78
  exclude_none=True,
78
79
  exclude_unset=True,
79
80
  exclude_defaults=True,
@@ -85,7 +86,7 @@ class KerykeionPointModel(BaseModel):
85
86
  def __repr__(self):
86
87
  return (
87
88
  super()
88
- .dict(
89
+ .model_dump(
89
90
  exclude_none=True,
90
91
  exclude_unset=True,
91
92
  exclude_defaults=True,
@@ -162,6 +163,7 @@ class AstrologicalSubjectModel(BaseModel):
162
163
 
163
164
  if __name__ == "__main__":
164
165
  from kerykeion.utilities import setup_logging
166
+
165
167
  setup_logging(level="debug")
166
168
 
167
169
  sun = KerykeionPointModel(
@@ -176,5 +178,5 @@ if __name__ == "__main__":
176
178
  point_type="Planet",
177
179
  )
178
180
 
179
- print(sun.json())
181
+ print(sun.model_dump_json())
180
182
  print(sun)
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- This is part of Kerykeion (C) 2023 Giacomo Battaglia
3
+ This is part of Kerykeion (C) 2024 Giacomo Battaglia
4
4
  """
5
5
 
6
6
 
@@ -22,7 +22,7 @@ class CustomBaseModel(BaseModel):
22
22
  return getattr(self, item)
23
23
 
24
24
  def __str__(self) -> str:
25
- return str(self.dict())
25
+ return str(self.model_dump())
26
26
 
27
27
  def get(self, item, default=None):
28
28
  return getattr(self, item, default)
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- This is part of Kerykeion (C) 2023 Giacomo Battaglia
3
+ This is part of Kerykeion (C) 2024 Giacomo Battaglia
4
4
  """
5
5
 
6
6
  from kerykeion import AstrologicalSubject
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- This is part of Kerykeion (C) 2023 Giacomo Battaglia
3
+ This is part of Kerykeion (C) 2024 Giacomo Battaglia
4
4
  """
5
5
 
6
6
 
@@ -60,7 +60,7 @@ def merge_settings(settings: KerykeionSettingsModel, new_settings: Dict) -> Kery
60
60
  Returns:
61
61
  KerykeionSettingsModel: The new settings
62
62
  """
63
- new_settings_dict = settings.dict() | new_settings
63
+ new_settings_dict = settings.model_dump() | new_settings
64
64
  return KerykeionSettingsModel(**new_settings_dict)
65
65
 
66
66
 
kerykeion/utilities.py CHANGED
@@ -1,6 +1,9 @@
1
1
  from kerykeion.kr_types import KerykeionPointModel, KerykeionException, KerykeionSettingsModel, AstrologicalSubjectModel
2
+ from kerykeion.kr_types.kr_literals import LunarPhaseEmoji, LunarPhaseName
2
3
  from typing import Union, Literal
3
4
  import logging
5
+ import math
6
+
4
7
 
5
8
 
6
9
  def get_number_from_name(name: str) -> int:
@@ -220,3 +223,135 @@ def setup_logging(level: str) -> None:
220
223
  format: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
221
224
  loglevel: int = logopt.get(level, logging.INFO)
222
225
  logging.basicConfig(format=format, level=loglevel)
226
+
227
+ def check_if_point_between(
228
+ start_point: Union[int, float], end_point: Union[int, float], evaluated_point: Union[int, float]
229
+ ) -> bool:
230
+ """
231
+ Finds if a point is between two other in a circle.
232
+
233
+ Args:
234
+ - start_point: The first point
235
+ - end_point: The second point
236
+ - point: The point to check if it is between start_point and end_point
237
+
238
+ Returns:
239
+ - True if point is between start_point and end_point, False otherwise
240
+ """
241
+
242
+ p1_p2 = math.fmod(end_point - start_point + 360, 360)
243
+ p1_p3 = math.fmod(evaluated_point - start_point + 360, 360)
244
+
245
+ if (p1_p2 <= 180) != (p1_p3 > p1_p2):
246
+ return True
247
+ else:
248
+ return False
249
+
250
+
251
+ def get_planet_house(planet_position_degree: Union[int, float], houses_degree_ut_list: list) -> str:
252
+ """
253
+ Returns the house in which a planet is located.
254
+
255
+ Args:
256
+ - planet_position_degree: The position of the planet in degrees
257
+ - houses_degree_ut_list: A list of the houses in degrees (0-360)
258
+
259
+ Returns:
260
+ - The house in which the planet is located
261
+ """
262
+
263
+ house = None
264
+ if check_if_point_between(houses_degree_ut_list[0], houses_degree_ut_list[1], planet_position_degree) == True:
265
+ house = "First_House"
266
+ elif check_if_point_between(houses_degree_ut_list[1], houses_degree_ut_list[2], planet_position_degree) == True:
267
+ house = "Second_House"
268
+ elif check_if_point_between(houses_degree_ut_list[2], houses_degree_ut_list[3], planet_position_degree) == True:
269
+ house = "Third_House"
270
+ elif check_if_point_between(houses_degree_ut_list[3], houses_degree_ut_list[4], planet_position_degree) == True:
271
+ house = "Fourth_House"
272
+ elif check_if_point_between(houses_degree_ut_list[4], houses_degree_ut_list[5], planet_position_degree) == True:
273
+ house = "Fifth_House"
274
+ elif check_if_point_between(houses_degree_ut_list[5], houses_degree_ut_list[6], planet_position_degree) == True:
275
+ house = "Sixth_House"
276
+ elif check_if_point_between(houses_degree_ut_list[6], houses_degree_ut_list[7], planet_position_degree) == True:
277
+ house = "Seventh_House"
278
+ elif check_if_point_between(houses_degree_ut_list[7], houses_degree_ut_list[8], planet_position_degree) == True:
279
+ house = "Eighth_House"
280
+ elif check_if_point_between(houses_degree_ut_list[8], houses_degree_ut_list[9], planet_position_degree) == True:
281
+ house = "Ninth_House"
282
+ elif check_if_point_between(houses_degree_ut_list[9], houses_degree_ut_list[10], planet_position_degree) == True:
283
+ house = "Tenth_House"
284
+ elif check_if_point_between(houses_degree_ut_list[10], houses_degree_ut_list[11], planet_position_degree) == True:
285
+ house = "Eleventh_House"
286
+ elif check_if_point_between(houses_degree_ut_list[11], houses_degree_ut_list[0], planet_position_degree) == True:
287
+ house = "Twelfth_House"
288
+ else:
289
+ raise ValueError("Error in house calculation, planet: ", planet_position_degree)
290
+
291
+ return house
292
+
293
+ def get_moon_emoji_from_phase_int(phase: int) -> LunarPhaseEmoji:
294
+ """
295
+ Returns the emoji of the moon phase.
296
+
297
+ Args:
298
+ - phase: The phase of the moon (0-28)
299
+
300
+ Returns:
301
+ - The emoji of the moon phase
302
+ """
303
+
304
+ if phase == 1:
305
+ result = "🌑"
306
+ elif phase < 7:
307
+ result = "🌒"
308
+ elif 7 <= phase <= 9:
309
+ result = "🌓"
310
+ elif phase < 14:
311
+ result = "🌔"
312
+ elif phase == 14:
313
+ result = "🌕"
314
+ elif phase < 20:
315
+ result = "🌖"
316
+ elif 20 <= phase <= 22:
317
+ result = "🌗"
318
+ elif phase <= 28:
319
+ result = "🌘"
320
+
321
+ else:
322
+ raise KerykeionException(f"Error in moon emoji calculation! Phase: {phase}")
323
+
324
+ return result
325
+
326
+ def get_moon_phase_name_from_phase_int(phase: int) -> LunarPhaseName:
327
+ """
328
+ Returns the name of the moon phase.
329
+
330
+ Args:
331
+ - phase: The phase of the moon (0-28)
332
+
333
+ Returns:
334
+ - The name of the moon phase
335
+ """
336
+
337
+ if phase == 1:
338
+ result = "New Moon"
339
+ elif phase < 7:
340
+ result = "Waxing Crescent"
341
+ elif 7 <= phase <= 9:
342
+ result = "First Quarter"
343
+ elif phase < 14:
344
+ result = "Waxing Gibbous"
345
+ elif phase == 14:
346
+ result = "Full Moon"
347
+ elif phase < 20:
348
+ result = "Waning Gibbous"
349
+ elif 20 <= phase <= 22:
350
+ result = "Last Quarter"
351
+ elif phase <= 28:
352
+ result = "Waning Crescent"
353
+
354
+ else:
355
+ raise KerykeionException(f"Error in moon name calculation! Phase: {phase}")
356
+
357
+ return result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kerykeion
3
- Version: 4.5.1
3
+ Version: 4.6.1
4
4
  Summary: A python library for astrology.
5
5
  Home-page: https://github.com/g-battaglia/kerykeion
6
6
  License: AGPL-3.0
@@ -0,0 +1,32 @@
1
+ LICENSE,sha256=UTLH8EdbAsgQei4PA2PnBCPGLSZkq5J-dhkyJuXgWQU,34273
2
+ kerykeion/__init__.py,sha256=Z2-gAp09RAl2_WwzPO-OTc4ZRDLh54kTduAoy891gQc,3917
3
+ kerykeion/aspects/__init__.py,sha256=9FlDVI1ndCJga0-chNIhcLitjU_x3kbtAFfFqVp2ejc,293
4
+ kerykeion/aspects/aspects_utils.py,sha256=Rdo3ITDSU80n6U7aazpzzK4ruv7Iui2PaI3zMGqu1NQ,5832
5
+ kerykeion/aspects/natal_aspects.py,sha256=m3_v1dM6YXvENZ6iN_EJkikKxySZBeR5QKhGsaChERk,4507
6
+ kerykeion/aspects/synastry_aspects.py,sha256=uwg7Lc7wKnpxW9ydOdBHqx9cvO_t0ydGfIGluBIDD7c,3993
7
+ kerykeion/astrological_subject.py,sha256=9vLsYZYfAfkR5EJO_EkbkhXa4i788Yv1lCESaQrt5kU,22965
8
+ kerykeion/charts/__init__.py,sha256=Juxkduy2TaagWblh_7CE8Acrg3dHL27-WEddJhau_eQ,127
9
+ kerykeion/charts/charts_utils.py,sha256=jJLgoBcs9e6-ArNFsj_N7Wel0zCzMKEsGrlz_A7MECE,5167
10
+ kerykeion/charts/kerykeion_chart_svg.py,sha256=mx6VOcSCbPJlxNI0rFk-PQAwMvNEM5wbHMpClWV9EcA,64662
11
+ kerykeion/charts/templates/chart.xml,sha256=ZrkqJV3Du8vG1w8kVkM1wI-IiZNVDLDuS6dRtPz7wVo,69874
12
+ kerykeion/enums.py,sha256=Ben9GLYkPucpYY2ZDpURzUbNCc9jzK2MuaffkgiXFdQ,965
13
+ kerykeion/fetch_geonames.py,sha256=fWuhgP_hZTPzDuodu7hvSznzGCWj3IC3vHAX32zPRw8,4444
14
+ kerykeion/kr_types/__init__.py,sha256=-qhGQikurdoHnGtuT1bsaEeZ-IwmZtIHMjGOPC9_oqQ,295
15
+ kerykeion/kr_types/chart_types.py,sha256=PvdOEqzZZBrJxFKQqAC0KcnfIY4T4I2i6CeLQhvVbe8,1945
16
+ kerykeion/kr_types/kerykeion_exception.py,sha256=G-7VFta78qBt10l54JZWvwH-3lUNKmDwuILXaVGVu9A,314
17
+ kerykeion/kr_types/kr_literals.py,sha256=Kc7LfdeTqHi5uDGoQHWsB81GTBc5E-fGxTJqWKK1FFU,1267
18
+ kerykeion/kr_types/kr_models.py,sha256=3gyT4z-J9EM6p5175HKJX9q9WVWQTDt5Y_m3m8lZu9s,4260
19
+ kerykeion/kr_types/settings_models.py,sha256=fueHaDLW2GPQl4HWImUNsWxeM7xcF0JU-fFc3rQqPgE,12743
20
+ kerykeion/relationship_score.py,sha256=R9JugfK5_gJgr5ND-EghkqpqZcutzzKlJ-2JnYUMVv4,6794
21
+ kerykeion/report.py,sha256=kS5avIN119pJVapYjZOvabg77nEcA8sSrOuXbRifABk,2565
22
+ kerykeion/settings/__init__.py,sha256=QQNFCl7sgN27MKaVscqtpPk10HGz4wZS3I_7KEGMaVA,69
23
+ kerykeion/settings/kerykeion_settings.py,sha256=uRAbhJ0ZXAbGBPGJjhh5u8YX2phcXobEwJA646wMHcM,2347
24
+ kerykeion/settings/kr.config.json,sha256=1Yhv9RGHom5U9e-JZZRWVfT2Ubllz2WrckdwadDWfyg,12282
25
+ kerykeion/sweph/README.md,sha256=L7FtNAJTWtrZNGKa8MX87SjduFYPYxwWhaI5fmtzNZo,73
26
+ kerykeion/sweph/seas_18.se1,sha256=X9nCqhZU43wJpq61WAdueVQJt9xL2UjrwPqn1Kdoa1s,223002
27
+ kerykeion/utilities.py,sha256=ncoXHvzXhNjhdm-uU6hMirVo287laq2GAJElNE6cBZM,10822
28
+ kerykeion-4.6.1.dist-info/LICENSE,sha256=UTLH8EdbAsgQei4PA2PnBCPGLSZkq5J-dhkyJuXgWQU,34273
29
+ kerykeion-4.6.1.dist-info/METADATA,sha256=ex70YSaS2hxS_HFpcfQx0rkIfd0Xpp_PoskW6BNXC90,10311
30
+ kerykeion-4.6.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
31
+ kerykeion-4.6.1.dist-info/entry_points.txt,sha256=5SmANYscFDDTdeovHvGQ-cnj0hdFvGoxPaWLCpyDFnQ,49
32
+ kerykeion-4.6.1.dist-info/RECORD,,
@@ -1,32 +0,0 @@
1
- LICENSE,sha256=UTLH8EdbAsgQei4PA2PnBCPGLSZkq5J-dhkyJuXgWQU,34273
2
- kerykeion/__init__.py,sha256=PCtgM8o1R8Poo4RoISq23jLP-74LYWoShnK4bm81Yks,3917
3
- kerykeion/aspects/__init__.py,sha256=8uOTYtcMwyDBbDjIoz8wvWtdcgdU-86yQeM3EVLwnIA,293
4
- kerykeion/aspects/aspects_utils.py,sha256=10ozUZ4ZhMJ8e_wOZ02hoW9mHJm_d7bq4QXKG90CeNc,5832
5
- kerykeion/aspects/natal_aspects.py,sha256=k3L6wLec7l7BF1jKULN8rNlQNOhINnfPN6x8MixoMMo,4507
6
- kerykeion/aspects/synastry_aspects.py,sha256=rM_of6GU-ZQL1A6JaLsG59MTaAeWx29MWRf9te9hHeg,3993
7
- kerykeion/astrological_subject.py,sha256=PjupScv1RFmQyqRwJWBG6lJX1KyZJzek2L3V37Kb19I,25678
8
- kerykeion/charts/__init__.py,sha256=3WzR2n9dr6MDzjTbEQOYpXSFlhfMfga5YWNsPawdbRw,127
9
- kerykeion/charts/charts_utils.py,sha256=qQMXu5XZCCjvyqL62fzh4JnKLzd_G6u9pcMk6f1DpIc,3197
10
- kerykeion/charts/kerykeion_chart_svg.py,sha256=-5kclHKKL8kya2lFFnw5pZiygck82lAFBSI-eyse8lk,65295
11
- kerykeion/charts/templates/chart.xml,sha256=ZrkqJV3Du8vG1w8kVkM1wI-IiZNVDLDuS6dRtPz7wVo,69874
12
- kerykeion/enums.py,sha256=Ben9GLYkPucpYY2ZDpURzUbNCc9jzK2MuaffkgiXFdQ,965
13
- kerykeion/fetch_geonames.py,sha256=NwiRzl-OlA2yoEtgHEvdgWeed42cpcONmOhb9s-DAOY,4444
14
- kerykeion/kr_types/__init__.py,sha256=-vRe-jixD6n8d7vsLSwbbvU4c2RXOoVvv0pjbX-9eiY,205
15
- kerykeion/kr_types/chart_types.py,sha256=PvdOEqzZZBrJxFKQqAC0KcnfIY4T4I2i6CeLQhvVbe8,1945
16
- kerykeion/kr_types/kerykeion_exception.py,sha256=CtdpOaGTox_LBGB0Ji_qtcwbgYAqBJ8AfDXbeaiAkM0,314
17
- kerykeion/kr_types/kr_literals.py,sha256=hbgeq5yPuyLv9zXp7shBeEsMHOd8UQBBUa_HQnBQu7w,1034
18
- kerykeion/kr_types/kr_models.py,sha256=q34Dp0nRu9BZ7Wk_1oBCXpOxmK665gHmVlPBLXNoOe0,4106
19
- kerykeion/kr_types/settings_models.py,sha256=4dOTAy6UgevF9dGPnBLIp4Aw5FBEygifnjDO8kALmdw,12737
20
- kerykeion/relationship_score.py,sha256=IPO8IH9J6GOYuuAfn01d0KamY1xSIjl391Zvk5F434Y,6794
21
- kerykeion/report.py,sha256=kS5avIN119pJVapYjZOvabg77nEcA8sSrOuXbRifABk,2565
22
- kerykeion/settings/__init__.py,sha256=QQNFCl7sgN27MKaVscqtpPk10HGz4wZS3I_7KEGMaVA,69
23
- kerykeion/settings/kerykeion_settings.py,sha256=vZCpWpTHVD3ItERWzsVW3syhgchJbWaPqGN6bsSl6vQ,2341
24
- kerykeion/settings/kr.config.json,sha256=1Yhv9RGHom5U9e-JZZRWVfT2Ubllz2WrckdwadDWfyg,12282
25
- kerykeion/sweph/README.md,sha256=L7FtNAJTWtrZNGKa8MX87SjduFYPYxwWhaI5fmtzNZo,73
26
- kerykeion/sweph/seas_18.se1,sha256=X9nCqhZU43wJpq61WAdueVQJt9xL2UjrwPqn1Kdoa1s,223002
27
- kerykeion/utilities.py,sha256=LOug1qgHoR12hNvL2hqdRWTnTHst4BdzY6u1dl3PfL0,6207
28
- kerykeion-4.5.1.dist-info/LICENSE,sha256=UTLH8EdbAsgQei4PA2PnBCPGLSZkq5J-dhkyJuXgWQU,34273
29
- kerykeion-4.5.1.dist-info/METADATA,sha256=WHRoRCegIbOD5j7kII32Wo68NBK0YRGjmKIyHp5k8uA,10311
30
- kerykeion-4.5.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
31
- kerykeion-4.5.1.dist-info/entry_points.txt,sha256=5SmANYscFDDTdeovHvGQ-cnj0hdFvGoxPaWLCpyDFnQ,49
32
- kerykeion-4.5.1.dist-info/RECORD,,