tesorotools-python 0.0.13__tar.gz → 0.0.15__tar.gz
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.
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/PKG-INFO +1 -1
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/pyproject.toml +1 -1
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/convert.py +9 -3
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/render/__init__.py +4 -0
- tesorotools_python-0.0.13/tesorotools/render/introduction.py → tesorotools_python-0.0.15/tesorotools/render/content/subtitle.py +8 -4
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/render/content/table.py +23 -14
- tesorotools_python-0.0.13/tesorotools/render/headline.py → tesorotools_python-0.0.15/tesorotools/render/content/title.py +8 -8
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/render/report.py +3 -1
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/.gitignore +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/__init__.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/artists/__init__.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/artists/barh_plot.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/artists/line_plot.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/artists/table.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/artists/type_curve.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/assets/README.md +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/assets/fonts/CabinetGrotesk-Black.otf +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/assets/fonts/CabinetGrotesk-Bold.otf +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/assets/fonts/CabinetGrotesk-Extrabold.otf +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/assets/fonts/CabinetGrotesk-Extralight.otf +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/assets/fonts/CabinetGrotesk-Light.otf +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/assets/fonts/CabinetGrotesk-Medium.otf +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/assets/fonts/CabinetGrotesk-Regular.otf +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/assets/fonts/CabinetGrotesk-Thin.otf +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/assets/fonts/README.md +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/assets/plots.yaml +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/assets/tesoro.mplstyle +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/data_sources/README.md +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/data_sources/__init__.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/data_sources/debug.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/data_sources/lseg.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/database/__init__.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/database/push.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/dependencies/__init__.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/dependencies/functions.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/dependencies/node.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/dependencies/resolution.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/main.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/offsets/__init__.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/offsets/offsets.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/offsets/outliers.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/render/content/__init__.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/render/content/content.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/render/content/images.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/render/content/section.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/render/content/text.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/utils/__init__.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/utils/config.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/utils/globals.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/utils/matplotlib.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/utils/series.py +0 -0
- {tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/utils/template.py +0 -0
|
@@ -37,13 +37,19 @@ def cheap_convert(old_file: Path) -> pd.DataFrame:
|
|
|
37
37
|
trimmed = old.loc[(slice(None), "no", "absolute", "value"), :].copy()
|
|
38
38
|
|
|
39
39
|
old = old.loc[
|
|
40
|
-
(
|
|
40
|
+
(
|
|
41
|
+
slice(None),
|
|
42
|
+
["day", "mtd", "week", "year", "tariff_crisis"],
|
|
43
|
+
slice(None),
|
|
44
|
+
slice(None),
|
|
45
|
+
),
|
|
41
46
|
:,
|
|
42
47
|
]
|
|
43
48
|
old.index = index_replace("day", "bday", old.index)
|
|
44
49
|
old.index = index_replace("week", "ftd", old.index)
|
|
45
50
|
old.index = index_replace("year", "ytd", old.index)
|
|
46
51
|
old.index = index_replace("roll_var", "roll_std", old.index)
|
|
52
|
+
old.index = index_replace("tariff_crisis", "2025-04-02", old.index)
|
|
47
53
|
|
|
48
54
|
trimmed.index = index_replace("absolute", "no", trimmed.index)
|
|
49
55
|
|
|
@@ -52,7 +58,7 @@ def cheap_convert(old_file: Path) -> pd.DataFrame:
|
|
|
52
58
|
|
|
53
59
|
|
|
54
60
|
if __name__ == "__main__":
|
|
55
|
-
preprocess =
|
|
61
|
+
preprocess = True
|
|
56
62
|
barh_config_dicts = read_config(Path("examples") / "barh_plots.yaml")
|
|
57
63
|
line_config_dicts = read_config(Path("examples") / "line_plots.yaml")
|
|
58
64
|
type_config_dicts = read_config(Path("examples") / "type_curves.yaml")
|
|
@@ -81,7 +87,7 @@ if __name__ == "__main__":
|
|
|
81
87
|
independent_full_df,
|
|
82
88
|
dependent_trimmed_df,
|
|
83
89
|
offsets_config,
|
|
84
|
-
force_trim=True,
|
|
90
|
+
# force_trim=True,
|
|
85
91
|
)
|
|
86
92
|
full_df.to_feather("derivates.feather")
|
|
87
93
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
from tesorotools.render.content.images import Image, Images
|
|
2
2
|
from tesorotools.render.content.section import Section
|
|
3
|
+
from tesorotools.render.content.subtitle import Subtitle
|
|
3
4
|
from tesorotools.render.content.table import Table
|
|
4
5
|
from tesorotools.render.content.text import Text
|
|
6
|
+
from tesorotools.render.content.title import Title
|
|
5
7
|
from tesorotools.render.report import Report
|
|
6
8
|
from tesorotools.utils.template import TemplateLoader
|
|
7
9
|
|
|
@@ -11,3 +13,5 @@ TemplateLoader.add_constructor("!image", Image.from_yaml)
|
|
|
11
13
|
TemplateLoader.add_constructor("!images", Images.from_yaml)
|
|
12
14
|
TemplateLoader.add_constructor("!table", Table.from_yaml)
|
|
13
15
|
TemplateLoader.add_constructor("!text", Text.from_yaml)
|
|
16
|
+
TemplateLoader.add_constructor("!title", Title.from_yaml)
|
|
17
|
+
TemplateLoader.add_constructor("!subtitle", Subtitle.from_yaml)
|
|
@@ -3,18 +3,22 @@ from typing import Any, Self
|
|
|
3
3
|
|
|
4
4
|
from babel.dates import format_datetime
|
|
5
5
|
from docx.document import Document
|
|
6
|
+
from yaml import MappingNode
|
|
6
7
|
|
|
8
|
+
from tesorotools.utils.config import TemplateLoader
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
|
|
11
|
+
class Subtitle:
|
|
9
12
|
def __init__(self, date_time: datetime | None = None) -> None:
|
|
10
13
|
if date_time is None:
|
|
11
14
|
date_time: datetime = datetime.now()
|
|
12
15
|
self._date_time: datetime = date_time
|
|
13
16
|
|
|
14
17
|
@classmethod
|
|
15
|
-
def
|
|
18
|
+
def from_yaml(cls, loader: TemplateLoader, node: MappingNode) -> Self:
|
|
19
|
+
subtitle_cfg: dict[str, Any] = loader.construct_mapping(node, deep=True)
|
|
16
20
|
# parse date
|
|
17
|
-
date_cfg: str | date | None =
|
|
21
|
+
date_cfg: str | date | None = subtitle_cfg.get("date", None)
|
|
18
22
|
if date_cfg is None:
|
|
19
23
|
date_time: datetime = datetime.now()
|
|
20
24
|
elif isinstance(date_cfg, date):
|
|
@@ -23,7 +27,7 @@ class Introduction:
|
|
|
23
27
|
date_time: datetime = datetime.strptime(date_cfg, "%Y-%m-%d")
|
|
24
28
|
|
|
25
29
|
# parse hour
|
|
26
|
-
hour_cfg: str | None =
|
|
30
|
+
hour_cfg: str | None = subtitle_cfg.get("hour", None)
|
|
27
31
|
if hour_cfg is not None:
|
|
28
32
|
hour_str, minute_str = hour_cfg.split(sep=":")
|
|
29
33
|
date_time = date_time.replace(
|
|
@@ -4,12 +4,12 @@ from typing import Any, Self
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
import pandas as pd
|
|
6
6
|
from docx.document import Document
|
|
7
|
-
from docx.enum.table import WD_ALIGN_VERTICAL
|
|
7
|
+
from docx.enum.table import WD_ALIGN_VERTICAL, WD_TABLE_ALIGNMENT
|
|
8
8
|
from docx.enum.text import WD_ALIGN_PARAGRAPH
|
|
9
9
|
from docx.oxml import OxmlElement, parse_xml
|
|
10
10
|
from docx.oxml.ns import nsdecls, qn
|
|
11
11
|
from docx.shared import Inches, Pt, RGBColor
|
|
12
|
-
from docx.table import Table
|
|
12
|
+
from docx.table import Table as TableDocx
|
|
13
13
|
from docx.table import _Cell as TableCell
|
|
14
14
|
from yaml import MappingNode
|
|
15
15
|
|
|
@@ -69,7 +69,7 @@ def _style_horizontal_blocks_header(cell: TableCell):
|
|
|
69
69
|
cell.paragraphs[0].runs[0].font.size = Pt(12)
|
|
70
70
|
|
|
71
71
|
|
|
72
|
-
def _horizontal_blocks_header(columns: pd.MultiIndex, table_docx:
|
|
72
|
+
def _horizontal_blocks_header(columns: pd.MultiIndex, table_docx: TableDocx):
|
|
73
73
|
column_counter: int = 1
|
|
74
74
|
blocks: list[str] = list(columns.get_level_values(level=0).unique())
|
|
75
75
|
for block in blocks:
|
|
@@ -92,7 +92,7 @@ def _style_column_names(cell: TableCell):
|
|
|
92
92
|
|
|
93
93
|
|
|
94
94
|
def _fill_column_names(
|
|
95
|
-
table: pd.DataFrame, table_docx:
|
|
95
|
+
table: pd.DataFrame, table_docx: TableDocx, horizontal: bool
|
|
96
96
|
):
|
|
97
97
|
if horizontal:
|
|
98
98
|
start_row: int = 1
|
|
@@ -115,13 +115,13 @@ def _style_index_names(cell: TableCell):
|
|
|
115
115
|
|
|
116
116
|
|
|
117
117
|
def _fill_index_names(
|
|
118
|
-
index: pd.Index | pd.MultiIndex, table_docx:
|
|
118
|
+
index: pd.Index | pd.MultiIndex, table_docx: TableDocx, horizontal: bool
|
|
119
119
|
):
|
|
120
120
|
start_row: int = 2 if horizontal else 1
|
|
121
121
|
|
|
122
122
|
index_names: pd.Index = (
|
|
123
123
|
index
|
|
124
|
-
if (horizontal or isinstance(index, pd.
|
|
124
|
+
if (horizontal or (not isinstance(index, pd.MultiIndex)))
|
|
125
125
|
else index.get_level_values(level=1)
|
|
126
126
|
)
|
|
127
127
|
|
|
@@ -132,7 +132,7 @@ def _fill_index_names(
|
|
|
132
132
|
|
|
133
133
|
|
|
134
134
|
# we only separate blocks in vertically stacked tables
|
|
135
|
-
def _separate_blocks(index: pd.MultiIndex, table_docx:
|
|
135
|
+
def _separate_blocks(index: pd.MultiIndex, table_docx: TableDocx):
|
|
136
136
|
blocks: list[str] = list(index.get_level_values(level=0).unique())
|
|
137
137
|
previous_rows = 0
|
|
138
138
|
for block in blocks[:-1]:
|
|
@@ -186,7 +186,7 @@ def _fill_content(
|
|
|
186
186
|
table: pd.DataFrame,
|
|
187
187
|
color_table: pd.DataFrame,
|
|
188
188
|
shade_table: pd.DataFrame,
|
|
189
|
-
table_docx:
|
|
189
|
+
table_docx: TableDocx,
|
|
190
190
|
horizontal: bool,
|
|
191
191
|
):
|
|
192
192
|
start_row: int = 2 if horizontal else 1
|
|
@@ -209,7 +209,7 @@ def _fill_content(
|
|
|
209
209
|
_style_content(cell)
|
|
210
210
|
|
|
211
211
|
|
|
212
|
-
def _style_table(table_docx:
|
|
212
|
+
def _style_table(table_docx: TableDocx):
|
|
213
213
|
table_docx.style = RENDER_CONFIG.get("style", None)
|
|
214
214
|
table_docx.autofit = RENDER_CONFIG["autofit"]
|
|
215
215
|
|
|
@@ -221,10 +221,10 @@ def render_table(
|
|
|
221
221
|
document: Document,
|
|
222
222
|
block_sep: bool,
|
|
223
223
|
**kwargs,
|
|
224
|
-
) ->
|
|
224
|
+
) -> TableDocx:
|
|
225
225
|
|
|
226
226
|
horizontal: bool = isinstance(table.columns, pd.MultiIndex)
|
|
227
|
-
table_docx:
|
|
227
|
+
table_docx: TableDocx = document.add_table(
|
|
228
228
|
rows=len(table.index) + table.columns.nlevels,
|
|
229
229
|
cols=len(table.columns) + 1,
|
|
230
230
|
)
|
|
@@ -237,6 +237,7 @@ def render_table(
|
|
|
237
237
|
if block_sep:
|
|
238
238
|
_separate_blocks(table.index, table_docx)
|
|
239
239
|
_fill_content(table, color_table, shade_table, table_docx, horizontal)
|
|
240
|
+
table_docx.alignment = WD_TABLE_ALIGNMENT.CENTER
|
|
240
241
|
return document
|
|
241
242
|
|
|
242
243
|
|
|
@@ -274,7 +275,15 @@ class Table:
|
|
|
274
275
|
table_cfg: dict[str, Any] = loader.construct_mapping(node, deep=True)
|
|
275
276
|
root_path: Path = loader.imports["table"]
|
|
276
277
|
file_prefix: str = table_cfg.pop("id")
|
|
277
|
-
|
|
278
|
+
|
|
279
|
+
# the data file has an optional "_data" suffix
|
|
280
|
+
# if a file with the suffix exists, it will be preferred
|
|
281
|
+
data_file_suffix: Path = root_path / f"{file_prefix}_data.feather"
|
|
282
|
+
if data_file_suffix.exists():
|
|
283
|
+
data_file: Path = data_file_suffix
|
|
284
|
+
else:
|
|
285
|
+
data_file: Path = root_path / f"{file_prefix}.feather"
|
|
286
|
+
|
|
278
287
|
color_file: Path = root_path / f"{file_prefix}_color.feather"
|
|
279
288
|
shade_file: Path = root_path / f"{file_prefix}_shade.feather"
|
|
280
289
|
return cls(
|
|
@@ -287,9 +296,9 @@ class Table:
|
|
|
287
296
|
def render(self, document: Document) -> Document:
|
|
288
297
|
heading = document.add_heading(self._title, level=2)
|
|
289
298
|
heading.alignment = CENTER
|
|
290
|
-
heading.runs[0].font.size = 10
|
|
299
|
+
heading.runs[0].font.size = Pt(10)
|
|
291
300
|
|
|
292
|
-
|
|
301
|
+
render_table(
|
|
293
302
|
self._data,
|
|
294
303
|
self._color,
|
|
295
304
|
self._shade,
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
from typing import Any, Self
|
|
2
2
|
|
|
3
3
|
from docx.document import Document
|
|
4
|
+
from yaml import MappingNode
|
|
4
5
|
|
|
6
|
+
from tesorotools.utils.config import TemplateLoader
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
|
|
9
|
+
class Title:
|
|
7
10
|
def __init__(
|
|
8
11
|
self, title: str | None = None, comment: str | None = None
|
|
9
12
|
) -> None:
|
|
@@ -11,9 +14,10 @@ class HeadLine:
|
|
|
11
14
|
self._comment: str = "" if comment is None else comment
|
|
12
15
|
|
|
13
16
|
@classmethod
|
|
14
|
-
def
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
def from_yaml(cls, loader: TemplateLoader, node: MappingNode) -> Self:
|
|
18
|
+
title_cfg: dict[str, Any] = loader.construct_mapping(node, deep=True)
|
|
19
|
+
title: str | None = title_cfg.get("title", None)
|
|
20
|
+
comment: str | None = title_cfg.get("comment", None)
|
|
17
21
|
return cls(title, comment)
|
|
18
22
|
|
|
19
23
|
def render(self, document: Document) -> Document:
|
|
@@ -31,10 +35,6 @@ class HeadLine:
|
|
|
31
35
|
def title(self) -> str:
|
|
32
36
|
return self._title
|
|
33
37
|
|
|
34
|
-
@title.setter
|
|
35
|
-
def title(self, title) -> None:
|
|
36
|
-
self._title = title
|
|
37
|
-
|
|
38
38
|
@property
|
|
39
39
|
def comment(self) -> str:
|
|
40
40
|
return self._comment
|
|
@@ -4,6 +4,7 @@ from docx.document import Document
|
|
|
4
4
|
from yaml import Loader, MappingNode
|
|
5
5
|
|
|
6
6
|
from tesorotools.render.content.content import Content
|
|
7
|
+
from tesorotools.render.content.title import Title
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class Report:
|
|
@@ -25,5 +26,6 @@ class Report:
|
|
|
25
26
|
document._body.clear_content()
|
|
26
27
|
for _, content in self.contents.items():
|
|
27
28
|
content.render(document)
|
|
28
|
-
|
|
29
|
+
if not isinstance(content, Title):
|
|
30
|
+
document.add_paragraph()
|
|
29
31
|
return document
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/data_sources/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/dependencies/__init__.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/dependencies/functions.py
RENAMED
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/dependencies/resolution.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/render/content/__init__.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/render/content/content.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/render/content/images.py
RENAMED
|
File without changes
|
{tesorotools_python-0.0.13 → tesorotools_python-0.0.15}/tesorotools/render/content/section.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|