Skip to content

Commit

Permalink
feat: add basic info section in Stat module. Update README and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hoishing committed Dec 25, 2024
1 parent 7e3f0e2 commit c7d2e90
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 43 deletions.
14 changes: 5 additions & 9 deletions .cursorrules
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
# Project Dependencies

- Natal: https://pypi.org/project/natal/

# Python Style

- use python 3.12 or above
Expand All @@ -13,16 +9,16 @@
- `A | B` instead of `Union[A, B]`
- use `typing.Self` instead of forward reference string "ClassName"

# Docstrings
# Docstrings Style

- use Google style docstrings
- don't write type hints in docstrings
- write short description in the first line
- refer to the following example:

```python
def function_with_pep484_type_annotations(param1: int, param2: str) -> bool:
"""Example function with PEP 484 type annotations.
def sample_function(param1: int, param2: str) -> bool:
"""
Example function with PEP 484 type annotations.

Args:
param1: The first parameter.
Expand All @@ -33,7 +29,7 @@ Returns:
"""
```

# CSS
# CSS Style

- use nested selectors to style components
- try to use variables for colors, sizes, etc.
25 changes: 17 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ from natal import Data, Chart
# create chart data object
mimi = Data(
name="MiMi",
utc_dt="1980-04-20 06:30:00",
utc_dt="1980-04-20 06:30",
lat=25.0531,
lon=121.526,
)
Expand All @@ -64,7 +64,7 @@ Chart(mimi, width=600).svg
# create transit data object
transit = Data(
name="Transit",
utc_dt="2024-01-01 05:30:00",
utc_dt="2024-01-01 05:30",
lat=25.0531,
lon=121.526,
)
Expand Down Expand Up @@ -145,6 +145,14 @@ print(stats.full_report(kind="markdown"))
- following markdown report will be produced:

```markdown
# Basic Information

| name | location | UTC time |
|---------|----------------------|------------------|
| MiMi | 25.0531°N, 121.526°E | 1980-04-20 06:30 |
| Transit | 25.0531°N, 121.526°E | 2024-01-01 05:30 |


# Element Distribution (MiMi)

| element | sum | bodies |
Expand Down Expand Up @@ -296,8 +304,8 @@ print(stats.full_report(kind="markdown"))
- optional dependencies for PDF report generation
- install with `pip install "natal[report]"`
- see [natal-report] package for details
- [demo_report_light.pdf]: light theme report with Birth Chart
- [demo_report_mono.pdf]: mono theme report with Transit Chart
- [light theme PDF sample]
- [mono theme PDF sample]

## Configuration

Expand Down Expand Up @@ -334,8 +342,9 @@ config = Config(
# create data object with the config
data = Data(
name = "MiMi",
city = "Taipei",
dt = "1980-04-20 14:30",
utc_dt = "1980-04-20 06:30",
lat = 25.0531,
lon = 121.526,
config = config,
)
```
Expand All @@ -352,8 +361,8 @@ read the [docs] for complete references
[black-url]: https://github.com/psf/black
[ci-badge]: https://github.com/hoishing/natal/actions/workflows/ci.yml/badge.svg
[ci-url]: https://github.com/hoishing/natal/actions/workflows/ci.yml
[demo_report_light.pdf]: https://github.com/hoishing/natal_report/blob/main/demo_report_light.pdf
[demo_report_mono.pdf]: https://github.com/hoishing/natal_report/blob/main/demo_report_mono.pdf
[light theme PDF sample]: https://github.com/hoishing/natal-report/blob/main/demo_report_light.pdf
[mono theme PDF sample]: https://github.com/hoishing/natal-report/blob/main/demo_report_mono.pdf
[demo.ipynb]: https://github.com/hoishing/natal/blob/main/demo.ipynb
[docs]: https://hoishing.github.io/natal
[MIT-badge]: https://img.shields.io/github/license/hoishing/natal
Expand Down
42 changes: 25 additions & 17 deletions natal/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
from math import floor
from natal.classes import Aspect, Aspectable
from natal.data import Data
from tagit import div, h4
from tabulate import tabulate
from tagit import div, h4
from typing import Iterable, Literal, NamedTuple

DistKind = Literal["element", "modality", "polarity"]
Expand Down Expand Up @@ -62,17 +62,36 @@ def __init__(self, data1: Data, data2: Data | None = None) -> None:

# data grids =================================================================

@property
def basic_info(self) -> StatData:
"""
Generate basic information about the provided data.
Returns:
The title and grid of basic information data, where the grid includes name, location coordinates, and UTC time.
"""
title = "Basic Information"
time_fmt = "%Y-%m-%d %H:%M"
dt1 = self.data1.utc_dt.strftime(time_fmt)
coordinates1 = f"{self.data1.lat}°N, {self.data1.lon}°E"
grid = [("name", "location", "UTC time")]
grid.append((self.data1.name, coordinates1, dt1))
if self.data2:
dt2 = self.data2.utc_dt.strftime(time_fmt)
coordinates2 = f"{self.data2.lat}°N, {self.data2.lon}°E"
grid.append((self.data2.name, coordinates2, dt2))
return StatData(title, grid)

def distribution(self, kind: DistKind) -> StatData:
"""
Generate distribution statistics for elements, modalities, or polarities.
Args:
kind (DistKind): The type of distribution to calculate.
Must be one of "element", "modality", or "polarity".
kind: The type of distribution to calculate. Must be one of "element", "modality", or "polarity".
Returns:
StatData: A named tuple containing the title and grid of distribution data,
where the grid includes the distribution type, count, and bodies.
The title and grid of distribution data, where the grid includes the distribution type,
count, and bodies.
"""
title = f"{kind.capitalize()} Distribution ({self.data1.name})"
bodies = defaultdict(lambda: [0, []])
Expand Down Expand Up @@ -294,6 +313,7 @@ def full_report(self, kind: ReportKind) -> str:
str: A formatted string containing the full statistical report with various tables.
"""
output = "\n"
output += self.table_of("basic_info", kind)
for dist in DistKind.__args__:
output += self.table_of("distribution", kind, dist)
output += self.table_of("celestial_body", kind)
Expand Down Expand Up @@ -400,15 +420,3 @@ def dignity_of(body: Aspectable) -> str:
if body.name == body.sign.fall:
return "fall"
return ""


# for quick testing
if __name__ == "__main__":
from natal.config import Orb

mimi = Data(name="MiMi", city="Taipei", dt="1980-04-20 14:30")
mimi.config.orb = Orb(conjunction=2, opposition=2, square=2, trine=2, sextile=1)
transit = Data(name="Transit", city="Taipei", dt="2024-01-01 13:30")

stats = Stats(data1=mimi, data2=transit)
print(stats.full_report(kind="markdown"))
8 changes: 4 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "natal"
version = "0.9.2"
version = "0.9.3"
description = "create Natal Chart with ease"
license = "MIT"
repository = "https://github.com/hoishing/natal"
Expand All @@ -10,7 +10,7 @@ readme = "README.md"
packages = [{ include = "natal", from = "." }]

[tool.poetry.dependencies]
natal-report = { version = "^0.1.3", optional = true }
natal-report = { version = "^0.1.5", optional = true }
pydantic = "^2.8.2"
pyswisseph = "^2.10.3.2"
python = "^3.12"
Expand Down
32 changes: 29 additions & 3 deletions tests/test_stats.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from natal.stats import Stats, Data
from natal.config import Display, Config
from pytest import fixture
from . import data1, data2, person1, person2
from natal.config import Config, Display
from natal.stats import Data, Stats
from pytest import fixture


@fixture(scope="module")
Expand All @@ -15,6 +15,22 @@ def composite_stats(data1, data2):


# fmt: off
@fixture
def info_grid():
return [
("name", "location", "UTC time"),
("shing", "22.2783°N, 114.175°E", "1976-04-20 09:58"),
]


@fixture
def composite_info_grid():
return [
("name", "location", "UTC time"),
("shing", "22.2783°N, 114.175°E", "1976-04-20 09:58"),
("belle", "22.2783°N, 114.175°E", "2011-01-23 00:44"),
]


@fixture
def element_grid():
Expand Down Expand Up @@ -254,6 +270,14 @@ def inner_planets_cross_ref_grid():
# fmt: on


def test_info_grid(stats, info_grid):
assert stats.basic_info.grid == info_grid


def test_composite_info_grid(composite_stats, composite_info_grid):
assert composite_stats.basic_info.grid == composite_info_grid


def test_distribution_grid(stats, element_grid, modality_grid, polarity_grid):
assert stats.distribution("element").grid == element_grid
assert stats.distribution("modality").grid == modality_grid
Expand Down Expand Up @@ -295,6 +319,7 @@ def test_data1_cross_ref_grid(stats, data1_cross_ref_grid):
def test_composite_cross_ref_grid(composite_stats, composite_cross_ref_grid):
assert composite_stats.cross_ref.grid == composite_cross_ref_grid


def test_inner_planets_cross_ref_grid(inner_planets_cross_ref_grid):
inner = dict(sun=True, moon=True, mercury=True, venus=True, mars=True)
inner_only = dict.fromkeys(Display(), False) | inner
Expand All @@ -304,6 +329,7 @@ def test_inner_planets_cross_ref_grid(inner_planets_cross_ref_grid):
stats = Stats(data1=d1, data2=d2)
assert stats.cross_ref.grid == inner_planets_cross_ref_grid


def test_display_no_entities():
display = Display(**dict.fromkeys(Display(), False))
stats = Stats(data1=Data(**person1, config=Config(display=display)))
Expand Down

0 comments on commit c7d2e90

Please sign in to comment.