diff --git a/README.md b/README.md index a2f3688..bf36197 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ - timezone, latitude and longitude database from [GeoNames] - auto aware of daylight saving for a given time and location - natal chart data statistics - - element, quality, and polarity counts + - element, modality, and polarity counts - planets in each houses - quadrant and hemisphere distribution - aspect pair counts @@ -120,7 +120,7 @@ sun.sign.color # earth sun.sign.ruler # venus sun.sign.classic_ruler # venus sun.sign.element # earth -sun.sign.quality # fixed +sun.sign.modality # fixed sun.sign.polarity # negative # Aspect object @@ -170,9 +170,9 @@ print(stats.full_report(kind="markdown")) | air | 3 | venus ♊, pluto ♎, mc ♊ | -# Quality Distribution (MiMi) +# Modality Distribution (MiMi) -| quality | count | bodies | +| modality | count | bodies | |-----------|---------|------------------------------------------------------------| | fixed | 4 | sun ♉, mars ♌, uranus ♏, asc_node ♌ | | cardinal | 3 | moon ♋, mercury ♈, pluto ♎ | diff --git a/demo.ipynb b/demo.ipynb index aeb150e..86ca7ed 100644 --- a/demo.ipynb +++ b/demo.ipynb @@ -19,19 +19,19 @@ { "data": { "text/html": [ - "123456789101112\n", - "\n", + "123456789101112\n", + "\n", "\n", - "\n", + "\n", "\n", "\n", "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "None" + "None" ], "text/plain": [ "" @@ -64,30 +64,30 @@ { "data": { "text/html": [ - "123456789101112\n", - "\n", - "\n", - "\n", - "\n", + "123456789101112\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", + "\n", + "\n", "\n", "\n", "\n", - "\n", + "\n", + "\n", + "\n", "\n", - "\n", + "\n", "\n", "\n", "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "" + "" ], "text/plain": [ "" @@ -122,30 +122,30 @@ "\n", "

Element Distribution (MiMi)

\n", "\n", - "\n", + "\n", "\n", "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "
element count bodies
element sum bodies
earth 4 sun ♉, jupiter ♍, saturn ♍, asc ♍
water 2 moon ♋, uranus ♏
fire 4 mercury ♈, mars ♌, neptune ♐, asc_node ♌
air 3 venus ♊, pluto ♎, mc ♊
earth 4 sun ♉, jupiter ♍, saturn ♍, asc ♍
water 2 moon ♋, uranus ♏
fire 4 mercury ♈, mars ♌, neptune ♐, asc_node ♌
air 3 venus ♊, pluto ♎, mc ♊

Quality Distribution (MiMi)

\n", + "

Modality Distribution (MiMi)

\n", "\n", - "\n", + "\n", "\n", "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", "\n", "
quality count bodies
modality sum bodies
fixed 4 sun ♉, mars ♌, uranus ♏, asc_node ♌
cardinal 3 moon ♋, mercury ♈, pluto ♎
mutable 6 venus ♊, jupiter ♍, saturn ♍, neptune ♐, asc ♍, mc ♊
fixed 4 sun ♉, mars ♌, uranus ♏, asc_node ♌
cardinal 3 moon ♋, mercury ♈, pluto ♎
mutable 6 venus ♊, jupiter ♍, saturn ♍, neptune ♐, asc ♍, mc ♊

Polarity Distribution (MiMi)

\n", "\n", - "\n", + "\n", "\n", "\n", - "\n", - "\n", + "\n", + "\n", "\n", "
polarity count bodies
polarity sum bodies
negative 6 sun ♉, moon ♋, jupiter ♍, saturn ♍, uranus ♏, asc ♍
positive 7 mercury ♈, venus ♊, mars ♌, neptune ♐, pluto ♎, asc_node ♌, mc ♊
negative 6 sun ♉, moon ♋, jupiter ♍, saturn ♍, uranus ♏, asc ♍
positive 7 mercury ♈, venus ♊, mars ♌, neptune ♐, pluto ♎, asc_node ♌, mc ♊

Celestial Bodies (MiMi)

\n", "\n", @@ -186,79 +186,77 @@ "\n", "

Quadrants (MiMi)

\n", "\n", - "\n", + "\n", "\n", "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", "\n", "
quadrant count bodies
quadrant sum bodies
1st ◵ 3 saturn, uranus, pluto
2nd ◶ 1 neptune
3rd ◷ 2 sun, mercury
4th ◴ 5 moon, venus, mars, jupiter, asc_node
1st ◵ 3 saturn, uranus, pluto
2nd ◶ 1 neptune
3rd ◷ 2 sun, mercury
4th ◴ 5 moon, venus, mars, jupiter, asc_node

Hemispheres (MiMi)

\n", "\n", - "\n", + "\n", "\n", "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", "\n", "
hemisphere count bodies
hemisphere sum bodies
8 saturn, uranus, pluto, moon, venus, mars, jupiter, asc_node
3 neptune, sun, mercury
7 sun, mercury, moon, venus, mars, jupiter, asc_node
4 saturn, uranus, pluto, neptune
8 saturn, uranus, pluto, moon, venus, mars, jupiter, asc_node
3 neptune, sun, mercury
7 sun, mercury, moon, venus, mars, jupiter, asc_node
4 saturn, uranus, pluto, neptune

Celestial Bodies of Current in MiMi's chart

\n", "\n", - "\n", + "\n", "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", "
Current sign house
Current sign house dignity
sun 19°♏26' 3
moon 16°♓43' 7
mercury 11°♐15' 4
venus 29°♐30' 4
mars 02°♌14' 11
jupiter 19°♊33'℞ 10
saturn 12°♓42'℞ 7
uranus 25°♉28'℞ 9
neptune 27°♓19'℞ 7
pluto 29°♑51' 5
asc_node 04°♈10'℞ 7
asc 07°♉34' 8
mc 26°♑29' 5
sun 24°♏41' 3
moon 03°♊54' 9
mercury 17°♐05' 4 detriment
venus 05°♑42' 4
mars 03°♌36' 11
jupiter 19°♊00'℞ 10 detriment
saturn 12°♓41' 7
uranus 25°♉15'℞ 9
neptune 27°♓15'℞ 7
pluto 29°♑56' 5
asc_node 03°♈54'℞ 7
asc 27°♋54' 11
mc 21°♈31' 8

Aspects of Current vs MiMi

\n", "\n", "\n", "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", "
Current aspect MiMi phase orb
moon venus ← → 1° 31'
mercury asc ← → 1° 33'
venus sun → ← 0° 50'
venus jupiter → ← 0° 48'
mars sun → ← 1° 55'
jupiter saturn ← → 1° 30'
jupiter pluto ← → 0° 33'
uranus mars ← → 1° 30'
uranus uranus → ← 0° 57'
uranus asc_node→ ← 0° 35'
pluto sun ← → 0° 28'
asc moon ← → 0° 55'
sun uranus ← → 0° 10'
sun asc_node→ ← 1° 22'
mercury venus ← → 1° 53'
jupiter pluto ← → 1° 07'
uranus mars ← → 1° 43'
uranus uranus → ← 0° 44'
uranus asc_node→ ← 0° 48'
pluto sun ← → 0° 23'
mc neptune → ← 0° 58'
mc pluto ← → 1° 25'

Aspect Cross Reference of Current(cols) vs MiMi(rows)

\n", "\n", - "\n", + "\n", "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", "
Asc MC Total
Asc MC sum
3
1
0
1
1
1
1
1
0
1
1
Asc 1
MC 0
1
0
0
1
1
0
0
2
1
2
2
Asc 0
MC 0
" ], @@ -286,19 +284,19 @@ { "data": { "text/html": [ - "123456789101112\n", - "\n", + "123456789101112\n", + "\n", "\n", - "\n", + "\n", "\n", "\n", "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "None" + "None" ], "text/plain": [ "" @@ -333,7 +331,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.7" + "version": "3.13.0" } }, "nbformat": 4, diff --git a/docs/classes.md b/docs/classes.md index 1d9dda3..3609afb 100644 --- a/docs/classes.md +++ b/docs/classes.md @@ -1 +1 @@ -::: natal.classes \ No newline at end of file +::: natal.classes diff --git a/docs/data.md b/docs/data.md index 097b2cf..7e36070 100644 --- a/docs/data.md +++ b/docs/data.md @@ -1 +1 @@ -::: natal.data \ No newline at end of file +::: natal.data diff --git a/docs/report.md b/docs/report.md index 756fbbd..6b8d9f7 100644 --- a/docs/report.md +++ b/docs/report.md @@ -1 +1 @@ -::: natal.report \ No newline at end of file +::: natal.report diff --git a/docs/stats.md b/docs/stats.md index 26cbf88..a0823ab 100644 --- a/docs/stats.md +++ b/docs/stats.md @@ -1 +1 @@ -::: natal.stats \ No newline at end of file +::: natal.stats diff --git a/docs/utils.md b/docs/utils.md index e21656f..a257cd7 100644 --- a/docs/utils.md +++ b/docs/utils.md @@ -1 +1 @@ -::: natal.utils \ No newline at end of file +::: natal.utils diff --git a/natal/classes.py b/natal/classes.py index f827187..d192960 100644 --- a/natal/classes.py +++ b/natal/classes.py @@ -57,7 +57,7 @@ def rx(self) -> str: @property def sign(self) -> SignMember: """ - Return sign name, symbol, element, quality, and polarity. + Return sign name, symbol, element, modality, and polarity. Returns: SignMember: The sign member. diff --git a/natal/const.py b/natal/const.py index e5b0c73..9f06990 100644 --- a/natal/const.py +++ b/natal/const.py @@ -1,4 +1,3 @@ - """ Constants and utility functions for the natal package. """ @@ -44,9 +43,9 @@ class ElementMember(Body): ... -class QualityMember(Body): +class ModalityMember(Body): """ - Represents a quality in raw data. + Represents a modality in raw data. (cardinal, fixed, mutable) """ @@ -98,7 +97,7 @@ class SignMember(Body): fall: str classic_ruler: str classic_detriment: str - quality: str + modality: str element: str polarity: str @@ -141,7 +140,7 @@ def get_members(raw_data: dict) -> list[DotDict]: PLANET_NAMES = ["sun", "moon", "mercury", "venus", "mars", "jupiter", "saturn", "uranus", "neptune", "pluto"] EXTRA_NAMES = ["asc_node", "chiron", "ceres", "pallas", "juno", "vesta"] ELEMENT_NAMES = ["fire", "earth", "air", "water"] -QUALITY_NAMES = ["cardinal", "fixed", "mutable"] +MODALITY_NAMES = ["cardinal", "fixed", "mutable"] POLARITY_NAMES = ["positive", "negative"] SIGN_NAMES = ["aries", "taurus", "gemini", "cancer", "leo", "virgo", "libra", "scorpio", "sagittarius", "capricorn", "aquarius", "pisces"] HOUSE_NAMES = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve"] @@ -170,8 +169,8 @@ def get_members(raw_data: dict) -> list[DotDict]: color=["fire", "earth", "air", "water"], ) -QUALITY = dict( - name=QUALITY_NAMES, +MODALITY = dict( + name=MODALITY_NAMES, symbol="⟑⊟𛰣", value=[0, 1, 2], color=["fire", "earth", "air"], @@ -191,11 +190,37 @@ def get_members(raw_data: dict) -> list[DotDict]: color=["fire", "earth", "air", "water"] * 3, ruler="mars venus mercury moon sun mercury venus pluto jupiter saturn uranus neptune".split(), detriment="venus pluto jupiter saturn uranus neptune mars venus mercury moon sun mercury".split(), - exaltation=['sun', 'moon', '', 'jupiter', '', 'mercury', 'saturn', '', '', 'mars', '', 'venus'], - fall=['saturn', '', '', 'mars', '', 'venus', 'sun', 'moon', '', 'jupiter', '', 'mercury'], + exaltation=[ + "sun", + "moon", + "", + "jupiter", + "", + "mercury", + "saturn", + "", + "", + "mars", + "", + "venus", + ], + fall=[ + "saturn", + "", + "", + "mars", + "", + "venus", + "sun", + "moon", + "", + "jupiter", + "", + "mercury", + ], classic_ruler="mars venus mercury moon sun mercury venus mars jupiter saturn saturn jupiter".split(), classic_detriment="venus mars jupiter saturn saturn jupiter mars venus mercury moon sun mercury".split(), - quality=list(QUALITY["name"]) * 4, + modality=list(MODALITY["name"]) * 4, element=list(ELEMENTS["name"]) * 3, polarity=list(POLARITY["name"]) * 6, ) @@ -226,7 +251,7 @@ def get_members(raw_data: dict) -> list[DotDict]: PLANET_MEMBERS = get_members(PLANETS) ASPECT_MEMBERS = get_members(ASPECTS) ELEMENT_MEMBERS = get_members(ELEMENTS) -QUALITY_MEMBERS = get_members(QUALITY) +MODALITY_MEMBERS = get_members(MODALITY) POLARITY_MEMBERS = get_members(POLARITY) SIGN_MEMBERS = get_members(SIGNS) HOUSE_MEMBERS = get_members(HOUSES) diff --git a/natal/data.py b/natal/data.py index 26ae122..57da66c 100644 --- a/natal/data.py +++ b/natal/data.py @@ -206,7 +206,7 @@ def __str__(self) -> str: op += f"{e.name}: {e.signed_dms}\n" op += "Signs:\n" for e in self.signs: - op += f"{e.name}: degree={e.degree:.2f}, ruler={e.ruler}, color={e.color}, quality={e.quality}, element={e.element}, polarity={e.polarity}\n" + op += f"{e.name}: degree={e.degree:.2f}, ruler={e.ruler}, color={e.color}, modality={e.modality}, element={e.element}, polarity={e.polarity}\n" op += "Aspects:\n" for e in self.aspects: op += f"{e.body1.name} {e.aspect_member.symbol} {e.body2.name}: {e.aspect_member.color}\n" diff --git a/natal/report.py b/natal/report.py index cfdc21c..25a8f15 100644 --- a/natal/report.py +++ b/natal/report.py @@ -14,7 +14,7 @@ ELEMENT_MEMBERS, EXTRA_MEMBERS, PLANET_MEMBERS, - QUALITY_MEMBERS, + MODALITY_MEMBERS, SIGN_MEMBERS, VERTEX_MEMBERS, ) @@ -71,34 +71,34 @@ def basic_info(self) -> Grid: return list(zip(*output)) @property - def element_vs_quality(self) -> Grid: + def element_vs_modality(self) -> Grid: """ - Generates a grid comparing elements and qualities. + Generates a grid comparing elements and modalities. Returns: - A grid comparing elements and qualities. + A grid comparing elements and modalities. """ aspectable1 = self.data1.aspectables element_symbols = [svg_of(ele.name) for ele in ELEMENTS] grid = [[""] + element_symbols + ["sum"]] element_count = defaultdict(int) - for quality in QUALITY_MEMBERS: - row = [svg_of(quality.name)] - quality_count = 0 + for modality in MODALITY_MEMBERS: + row = [svg_of(modality.name)] + modality_count = 0 for element in ELEMENTS: count = 0 symbols = "" for body in aspectable1: if ( body.sign.element == element.name - and body.sign.quality == quality.name + and body.sign.modality == modality.name ): symbols += svg_of(body.name) count += 1 element_count[element.name] += 1 row.append(symbols) - quality_count += count - row.append(quality_count) + modality_count += count + row.append(modality_count) grid.append(row) grid.append( ["sum"] + list(element_count.values()) + [sum(element_count.values())] @@ -250,7 +250,7 @@ def full_report(self) -> str: chart = Chart(self.data1, width=400, data2=self.data2) row1 = div( section("Birth Info", self.basic_info) - + section("Elements, Modality & Polarity", self.element_vs_quality) + + section("Elements, Modality & Polarity", self.element_vs_modality) + section("Hemisphere & Quadrants", self.quadrants_vs_hemisphere), class_="info_col", ) + div(chart.svg, class_="chart") @@ -292,10 +292,10 @@ def create_pdf(self, html: str) -> BytesIO: def html_table_of(grid: Grid) -> str: """ Converts a grid of data into an HTML table. - + # Arguments * grid - The grid of data to convert - + # Returns String containing the HTML table """ diff --git a/natal/stats.py b/natal/stats.py index 22880b0..2bcf36c 100644 --- a/natal/stats.py +++ b/natal/stats.py @@ -13,7 +13,7 @@ from tabulate import tabulate from typing import Iterable, Literal, NamedTuple, Callable -DistKind = Literal["element", "quality", "polarity"] +DistKind = Literal["element", "modality", "polarity"] ReportKind = Literal["markdown", "html"] Grid = list[Iterable[str | int]] @@ -63,11 +63,11 @@ def __init__(self, data1: Data, data2: Data | None = None) -> None: def distribution(self, kind: DistKind) -> StatData: """ - Generate distribution statistics for elements, qualities, or polarities. + Generate distribution statistics for elements, modalities, or polarities. Args: kind (DistKind): The type of distribution to calculate. - Must be one of "element", "quality", or "polarity". + Must be one of "element", "modality", or "polarity". Returns: StatData: A named tuple containing the title and grid of distribution data, diff --git a/pyproject.toml b/pyproject.toml index 66a83d6..746752a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "natal" -version = "0.7.7" +version = "0.8.0" description = "create Natal Chart with ease" license = "MIT" repository = "https://github.com/hoishing/natal" diff --git a/tests/test_const.py b/tests/test_const.py index 1ace938..d20df94 100644 --- a/tests/test_const.py +++ b/tests/test_const.py @@ -5,7 +5,7 @@ def test_const(): assert len(PLANET_MEMBERS) == 10 assert len(ASPECT_MEMBERS) == 5 assert len(ELEMENT_MEMBERS) == 4 - assert len(QUALITY_MEMBERS) == 3 + assert len(MODALITY_MEMBERS) == 3 assert len(POLARITY_MEMBERS) == 2 assert len(SIGN_MEMBERS) == 12 assert len(HOUSE_MEMBERS) == 12 @@ -31,6 +31,7 @@ def test_house_member(): assert house.name == "four" assert house.color == "water" + def test_extra_member(): node = EXTRA_MEMBERS[0] assert node.name == "asc_node" diff --git a/tests/test_data.py b/tests/test_data.py index d72b065..c756c2b 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -125,7 +125,7 @@ def test_signs(data1: Data, signs: dict) -> None: assert round(sign.degree, 2) == signs[sign.name][0] assert sign.ruler == signs[sign.name][1] assert sign.color == signs[sign.name][2] - assert sign.quality == signs[sign.name][3] + assert sign.modality == signs[sign.name][3] assert sign.element == signs[sign.name][4] assert sign.polarity == signs[sign.name][5] @@ -158,6 +158,7 @@ def test_fix_orb_eq_0(data1: Data) -> None: assert len(data1.aspects) == 24 assert len(data.aspects) == 14 + def test_house_sys(data1: Data) -> None: data = Data(data1.name, data1.city, data1.dt, config=Config(house_sys="W")) assert data.house_sys == "W" diff --git a/tests/test_report.py b/tests/test_report.py index 863d46c..f0b0223 100644 --- a/tests/test_report.py +++ b/tests/test_report.py @@ -40,8 +40,8 @@ def test_basic_info(report): assert basic_info[2][0] == "birth" -def test_element_vs_quality(report): - grid = report.element_vs_quality +def test_element_vs_modality(report): + grid = report.element_vs_modality assert len(grid) > 0 assert grid[4] == ["sum", 2, 2, 5, 4, 13] assert [g[5] for g in grid[:5]] == ["sum", 7, 5, 1, 13] diff --git a/tests/test_stats.py b/tests/test_stats.py index 33254ec..1785942 100644 --- a/tests/test_stats.py +++ b/tests/test_stats.py @@ -28,9 +28,9 @@ def element_grid(): @fixture -def quality_grid(): +def modality_grid(): return [ - ("quality", "sum", "bodies"), + ("modality", "sum", "bodies"), ("fixed", 5, "sun ♉, mercury ♉, jupiter ♉, uranus ♏, asc_node ♏"), ("cardinal", 7, "moon ♑, venus ♈, mars ♋, saturn ♋, pluto ♎, asc ♎, mc ♋"), ("mutable", 1, "neptune ♐"), @@ -254,9 +254,9 @@ def inner_planets_cross_ref_grid(): # fmt: on -def test_distribution_grid(stats, element_grid, quality_grid, polarity_grid): +def test_distribution_grid(stats, element_grid, modality_grid, polarity_grid): assert stats.distribution("element").grid == element_grid - assert stats.distribution("quality").grid == quality_grid + assert stats.distribution("modality").grid == modality_grid assert stats.distribution("polarity").grid == polarity_grid