<jupyter_start><jupyter_text>Imports<jupyter_code>from __future__ import annotations

import collections
import datetime
import dataclasses
import importlib
import pathlib
import os
import sys
import types
from typing import Any

from etils import epy

import pandas as pd
import plotly
import plotly.express as px
import plotly.graph_objects as go
import plotly.io as pio

Json = Any
# Add notion_api to the path
module_path = os.fspath(pathlib.Path().absolute().parent)
if module_path not in sys.path:
    sys.path.append(module_path)
# Load the API token
p = pathlib.Path('~/__A__/life_calendar_api_token.txt')
p = p.expanduser()
os.environ['NOTION_TOKEN'] = p.read_text().strip()
def clear_modules(module_names: list[str] | str) -> None:
    """Clear modules from `sys.module`."""
    if isinstance(module_names, str):
        module_names = [module_names]

    for module in list(sys.modules):
        if any(module.startswith(prefix) for prefix in module_names):
            del sys.modules[module]
pio.templates.default = 'seaborn'<jupyter_output><empty_output><jupyter_text>Code<jupyter_code>clear_modules('life_calendar')

import life_calendar

life_db = life_calendar.LifeCalendarDb()
life_db.events
life_weeks = []
for event in life_db.events:
    life_weeks.extend(event.to_weeks())
life_weeks
TODO:
* Collisions
* Types
* Countries
* Fill-up empty square
df = pd.DataFrame(life_weeks)

fig = px.scatter(
    df, 
    x='week', 
    y='year',
    hover_data=['desc', 'date_range'],
    color='desc',
    height=1000,
    # template="seaborn",
    # template="plotly_dark",
)
fig.update_traces(
    marker=go.scattergl.Marker(
        symbol='square',
    ),
)
fig.update_layout(
    margin=dict(l=0, r=0, t=0, b=0),
    # showlegend=False,
    # paper_bgcolor="LightSteelBlue",
)
fig.update_yaxes(
    autorange="reversed",
    scaleanchor="x",
    scaleratio=1,
    showgrid=False,
    zeroline=False,  # Line at 0
    visible=False,  # Legend
)
fig.update_xaxes(
    showgrid=False,
    zeroline=False,  # Line at 0
    visible=False,  # Legend
)
fig
class Database:

    def __init__(self, database_id: str) -> None:
        # TODO
        self._client = client = notion_api.Client()

        results = self._client.api.databases.query(
            database_id=CALENDAR_ID,
        )

    def __iter__(self):
        return results

help(go.scatter.Marker)
import os

list(os.environ.keys())<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11617405582922824, 'fraction_numerical': 0.00451559934318555, 'mean_word_length': 3.903420523138833, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '355646', 'license': 'Apache-2.0', 'n_tokens_mistral': 859, 'n_tokens_neox': 838, 'n_words': 183, 'path': 'life_calendar/play.ipynb', 'repo_name': 'Conchylicultor/automations', 'size': '2436'}