toolsos 0.2.3__tar.gz → 0.2.5__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.
- {toolsos-0.2.3 → toolsos-0.2.5}/PKG-INFO +9 -2
- {toolsos-0.2.3 → toolsos-0.2.5}/README.md +8 -1
- {toolsos-0.2.3 → toolsos-0.2.5}/pyproject.toml +1 -1
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/cbs_tools.py +36 -17
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/database/database_connection.py +52 -13
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/geo.py +1 -1
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/graphs/bargraph.py +11 -1
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/graphs/graph_styles.py +3 -1
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/graphs/linegraph.py +2 -1
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/graphs/piegraph.py +2 -1
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/graphs/styler.py +21 -14
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/tables/tables.py +19 -5
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos.egg-info/PKG-INFO +9 -2
- {toolsos-0.2.3 → toolsos-0.2.5}/setup.cfg +0 -0
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/__init__.py +0 -0
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/create_tables.py +0 -0
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/database/database_transfer.py +0 -0
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/download.py +0 -0
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/helpers.py +0 -0
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/__init__.py +0 -0
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/colors.py +0 -0
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/graphs/__init__.py +0 -0
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/tables/__init__.py +0 -0
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/tables/table_helpers.py +0 -0
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/tables/table_styles.py +0 -0
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/polars_helpers.py +0 -0
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos.egg-info/SOURCES.txt +0 -0
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos.egg-info/dependency_links.txt +0 -0
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos.egg-info/requires.txt +0 -0
- {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: toolsos
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: OS tools
|
|
5
5
|
Author-email: OS <d.schmitz@amsterdam.nl>
|
|
6
6
|
Keywords: tools,Onderzoek & Statistiek
|
|
@@ -63,5 +63,12 @@ Instructions on building a package can be found [here](https://packaging.python.
|
|
|
63
63
|
|
|
64
64
|
- make a pypi account
|
|
65
65
|
- ask to be added as collaborator to toolsos
|
|
66
|
-
- first update twine: py -m pip install --upgrade
|
|
66
|
+
- first update twine: py -m pip install --upgrade twine
|
|
67
67
|
- upload to pypi: twine upload dist/* --skip-existing
|
|
68
|
+
|
|
69
|
+
## Install to local enviroment for testing
|
|
70
|
+
|
|
71
|
+
- python -m venv local (maak een lokale venv aan)
|
|
72
|
+
- local\Scripts\activate (activeer de venv)
|
|
73
|
+
- pip install -e . (installer toolsos)
|
|
74
|
+
- pip install -r local_requirements.txt (installeer de benodigde dependencies)
|
|
@@ -34,5 +34,12 @@ Instructions on building a package can be found [here](https://packaging.python.
|
|
|
34
34
|
|
|
35
35
|
- make a pypi account
|
|
36
36
|
- ask to be added as collaborator to toolsos
|
|
37
|
-
- first update twine: py -m pip install --upgrade
|
|
37
|
+
- first update twine: py -m pip install --upgrade twine
|
|
38
38
|
- upload to pypi: twine upload dist/* --skip-existing
|
|
39
|
+
|
|
40
|
+
## Install to local enviroment for testing
|
|
41
|
+
|
|
42
|
+
- python -m venv local (maak een lokale venv aan)
|
|
43
|
+
- local\Scripts\activate (activeer de venv)
|
|
44
|
+
- pip install -e . (installer toolsos)
|
|
45
|
+
- pip install -r local_requirements.txt (installeer de benodigde dependencies)
|
|
@@ -2,8 +2,9 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import pickle
|
|
5
|
+
from datetime import datetime
|
|
5
6
|
from pathlib import Path
|
|
6
|
-
from typing import TYPE_CHECKING, Iterator, Optional
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Iterator, Optional
|
|
7
8
|
|
|
8
9
|
import pandas as pd
|
|
9
10
|
import pyarrow as pa
|
|
@@ -14,18 +15,27 @@ if TYPE_CHECKING:
|
|
|
14
15
|
import pyreadstat
|
|
15
16
|
|
|
16
17
|
|
|
18
|
+
def get_batch_size(path, memory_limit):
|
|
19
|
+
df, _ = prs.read_sav(path, row_limit=1000)
|
|
20
|
+
|
|
21
|
+
# memory in megabytes
|
|
22
|
+
mem_size = df.memory_usage().sum() / 1_000_000
|
|
23
|
+
|
|
24
|
+
# The amount of blocks (of a thousand rows fit in the memory_limit)
|
|
25
|
+
n_blocks = memory_limit / mem_size
|
|
26
|
+
|
|
27
|
+
# Calculate the number of rows that fit within the memory limit
|
|
28
|
+
return round(n_blocks * 1000)
|
|
29
|
+
|
|
30
|
+
|
|
17
31
|
class SavToParquet:
|
|
18
32
|
def __init__(
|
|
19
|
-
self,
|
|
20
|
-
file: str,
|
|
21
|
-
folder_out: str,
|
|
22
|
-
chunksize: Optional[int] = None,
|
|
23
|
-
verbose: bool = False,
|
|
33
|
+
self, file: str, folder_out: str, verbose: bool = False, memory_limit=10_000
|
|
24
34
|
) -> None:
|
|
25
35
|
self.file = file
|
|
26
36
|
self.folder_out = folder_out
|
|
27
37
|
self.verbose = verbose
|
|
28
|
-
self.
|
|
38
|
+
self.memory_limit = memory_limit
|
|
29
39
|
|
|
30
40
|
@property
|
|
31
41
|
def path_out(self) -> str:
|
|
@@ -33,20 +43,27 @@ class SavToParquet:
|
|
|
33
43
|
|
|
34
44
|
@property
|
|
35
45
|
def chunks(self) -> Iterator[tuple["pyreadstat.metadata_container", pd.DataFrame]]:
|
|
36
|
-
return prs.read_file_in_chunks(
|
|
37
|
-
prs.read_sav, self.file, chunksize=self.chunksize
|
|
38
|
-
)
|
|
39
46
|
|
|
40
|
-
|
|
41
|
-
|
|
47
|
+
chunksize = get_batch_size(self.file, self.memory_limit)
|
|
48
|
+
|
|
49
|
+
if self.verbose:
|
|
50
|
+
print(f"Reading file in blocks of {chunksize} rows")
|
|
51
|
+
print("One such block should fit within the memory limit")
|
|
52
|
+
|
|
53
|
+
return prs.read_file_in_chunks(prs.read_sav, self.file, chunksize=chunksize)
|
|
42
54
|
|
|
43
55
|
def write_meta_to_json(self) -> None:
|
|
44
56
|
json_path = self.path_out.replace(".parquet", "_meta.json")
|
|
45
57
|
|
|
46
58
|
meta_dict = {}
|
|
47
|
-
for
|
|
48
|
-
if not
|
|
49
|
-
|
|
59
|
+
for attr_name in dir(self.meta):
|
|
60
|
+
if not attr_name.startswith("__"):
|
|
61
|
+
attr = getattr(self.meta, attr_name)
|
|
62
|
+
|
|
63
|
+
if isinstance(attr, datetime):
|
|
64
|
+
attr = attr.strftime("%Y-%m-%d %H:%M:%S")
|
|
65
|
+
|
|
66
|
+
meta_dict[attr_name] = attr
|
|
50
67
|
|
|
51
68
|
with open(json_path, "w") as file:
|
|
52
69
|
json.dump(meta_dict, file)
|
|
@@ -58,10 +75,12 @@ class SavToParquet:
|
|
|
58
75
|
pickle.dump(self.meta, file)
|
|
59
76
|
|
|
60
77
|
def write_to_parquet(self) -> None:
|
|
61
|
-
meta_df, self.meta = self.get_meta()
|
|
62
|
-
schema = table = pa.Table.from_pandas(meta_df).schema
|
|
63
78
|
|
|
64
79
|
print("Writing table")
|
|
80
|
+
|
|
81
|
+
line1, self.meta = prs.read_sav(self.file, row_limit=1)
|
|
82
|
+
schema = pa.Table.from_pandas(line1).schema
|
|
83
|
+
|
|
65
84
|
with pq.ParquetWriter(self.path_out, schema) as writer:
|
|
66
85
|
for idx, (df, _) in enumerate(self.chunks):
|
|
67
86
|
if self.verbose:
|
|
@@ -2,8 +2,10 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import getpass
|
|
4
4
|
import json
|
|
5
|
+
import os
|
|
5
6
|
import subprocess
|
|
6
7
|
from json import JSONDecodeError
|
|
8
|
+
from pathlib import Path
|
|
7
9
|
from typing import Optional
|
|
8
10
|
|
|
9
11
|
import keyring
|
|
@@ -99,18 +101,55 @@ def get_azure_access_token():
|
|
|
99
101
|
subprocess.run("az login", shell=True)
|
|
100
102
|
|
|
101
103
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
def get_token_from_pgpass() -> None:
|
|
105
|
+
p = Path(os.getenv("APPDATA")) / "postgresql" / "pgpass.conf"
|
|
106
|
+
with open(p) as f:
|
|
107
|
+
token = f.readline().split(":")[4]
|
|
105
108
|
|
|
106
|
-
|
|
107
|
-
engine_strings = get_db_connection_strings(
|
|
108
|
-
"src/toolsos/database/database_config.yml"
|
|
109
|
-
)
|
|
110
|
-
print(engine_strings.ruimte_analyse222)
|
|
109
|
+
return token
|
|
111
110
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
111
|
+
|
|
112
|
+
def write_pgpass(
|
|
113
|
+
host: str, port: str, database: str, user: str, path: str | None = None
|
|
114
|
+
) -> None:
|
|
115
|
+
password = get_azure_access_token()
|
|
116
|
+
conn_string = f"{host}:{port}:{database}:{user}:{password}"
|
|
117
|
+
|
|
118
|
+
if not path:
|
|
119
|
+
if os.name == "nt":
|
|
120
|
+
path = Path(os.getenv("APPDATA")) / "postgresql" / "pgpass.conf"
|
|
121
|
+
else:
|
|
122
|
+
path = Path("$home/.pgpass")
|
|
123
|
+
|
|
124
|
+
if not path.parent.exists():
|
|
125
|
+
path.parent.mkdir()
|
|
126
|
+
|
|
127
|
+
with open(path, "w") as f:
|
|
128
|
+
f.write(conn_string)
|
|
129
|
+
|
|
130
|
+
if os.name != "nt":
|
|
131
|
+
path.chmod("0600")
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def write_multiple_pgpass(conn_details, path: str | None = None):
|
|
135
|
+
password = get_azure_access_token()
|
|
136
|
+
|
|
137
|
+
conn_strings = []
|
|
138
|
+
for c in conn_details:
|
|
139
|
+
c_string = f'{c["host"]}:{c["port"]}:{c["database"]}:{c["user"]}:{password}'
|
|
140
|
+
conn_strings.append(c_string)
|
|
141
|
+
|
|
142
|
+
if not path:
|
|
143
|
+
if os.name == "nt":
|
|
144
|
+
path = Path(os.getenv("APPDATA")) / "postgresql" / "pgpass.conf"
|
|
145
|
+
else:
|
|
146
|
+
path = Path("$home/.pgpass")
|
|
147
|
+
|
|
148
|
+
if not path.parent.exists():
|
|
149
|
+
path.parent.mkdir()
|
|
150
|
+
|
|
151
|
+
with open(path, "w") as f:
|
|
152
|
+
f.writelines(line + "\n" for line in conn_strings)
|
|
153
|
+
|
|
154
|
+
if os.name != "nt":
|
|
155
|
+
path.chmod("0600")
|
|
@@ -17,7 +17,7 @@ def get_geo_json(
|
|
|
17
17
|
Returns:
|
|
18
18
|
dict[str, str]: geo json containg of the desired level and year
|
|
19
19
|
"""
|
|
20
|
-
base_url = "https://gitlab.com/os-amsterdam/datavisualisatie-onderzoek-en-statistiek/-/raw/main/geo/"
|
|
20
|
+
base_url = "https://gitlab.com/os-amsterdam/datavisualisatie-onderzoek-en-statistiek/-/raw/main/public/geo/"
|
|
21
21
|
|
|
22
22
|
if mra:
|
|
23
23
|
level = f"{level}-mra"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import plotly.express as px
|
|
2
|
+
|
|
2
3
|
from .styler import BaseStyle
|
|
3
4
|
|
|
4
5
|
basestyle = BaseStyle()
|
|
@@ -14,6 +15,7 @@ def bar(
|
|
|
14
15
|
barmode=None,
|
|
15
16
|
width=750,
|
|
16
17
|
height=490,
|
|
18
|
+
font="Amsterdam Sans",
|
|
17
19
|
**kwargs,
|
|
18
20
|
):
|
|
19
21
|
fig = px.bar(
|
|
@@ -21,7 +23,7 @@ def bar(
|
|
|
21
23
|
x=x,
|
|
22
24
|
y=y,
|
|
23
25
|
color=color,
|
|
24
|
-
template=basestyle.get_base_template("bar", orientation=orientation),
|
|
26
|
+
template=basestyle.get_base_template("bar", orientation=orientation, font=font),
|
|
25
27
|
width=width,
|
|
26
28
|
color_discrete_sequence=color_discrete_sequence,
|
|
27
29
|
height=height,
|
|
@@ -43,6 +45,7 @@ def stacked_single(
|
|
|
43
45
|
color: str = None,
|
|
44
46
|
color_discrete_sequence: list = None,
|
|
45
47
|
orientation="v",
|
|
48
|
+
font="Amsterdam Sans",
|
|
46
49
|
**kwargs,
|
|
47
50
|
):
|
|
48
51
|
fig = bar(
|
|
@@ -53,6 +56,7 @@ def stacked_single(
|
|
|
53
56
|
color_discrete_sequence=color_discrete_sequence,
|
|
54
57
|
barmode="relative",
|
|
55
58
|
orientation=orientation,
|
|
59
|
+
font=font,
|
|
56
60
|
**kwargs,
|
|
57
61
|
)
|
|
58
62
|
|
|
@@ -71,6 +75,7 @@ def stacked_multiple(
|
|
|
71
75
|
color: str = None,
|
|
72
76
|
color_discrete_sequence: list = None,
|
|
73
77
|
orientation="v",
|
|
78
|
+
font="Amsterdam Sans",
|
|
74
79
|
**kwargs,
|
|
75
80
|
):
|
|
76
81
|
fig = bar(
|
|
@@ -81,6 +86,7 @@ def stacked_multiple(
|
|
|
81
86
|
color_discrete_sequence=color_discrete_sequence,
|
|
82
87
|
barmode="stack",
|
|
83
88
|
orientation=orientation,
|
|
89
|
+
font=font,
|
|
84
90
|
**kwargs,
|
|
85
91
|
)
|
|
86
92
|
|
|
@@ -94,6 +100,7 @@ def grouped(
|
|
|
94
100
|
color: str = None,
|
|
95
101
|
color_discrete_sequence: list = None,
|
|
96
102
|
orientation="v",
|
|
103
|
+
font="Amsterdam Sans",
|
|
97
104
|
**kwargs,
|
|
98
105
|
):
|
|
99
106
|
fig = bar(
|
|
@@ -104,6 +111,7 @@ def grouped(
|
|
|
104
111
|
color_discrete_sequence=color_discrete_sequence,
|
|
105
112
|
barmode="group",
|
|
106
113
|
orientation=orientation,
|
|
114
|
+
font=font,
|
|
107
115
|
**kwargs,
|
|
108
116
|
)
|
|
109
117
|
|
|
@@ -116,6 +124,7 @@ def single(
|
|
|
116
124
|
y: str,
|
|
117
125
|
color_discrete_sequence: list = None,
|
|
118
126
|
orientation="v",
|
|
127
|
+
font="Amsterdam Sans",
|
|
119
128
|
**kwargs,
|
|
120
129
|
):
|
|
121
130
|
fig = bar(
|
|
@@ -124,6 +133,7 @@ def single(
|
|
|
124
133
|
y=y,
|
|
125
134
|
color_discrete_sequence=color_discrete_sequence,
|
|
126
135
|
orientation=orientation,
|
|
136
|
+
font=font,
|
|
127
137
|
**kwargs,
|
|
128
138
|
)
|
|
129
139
|
|
|
@@ -16,8 +16,10 @@ STYLE_OLD = {
|
|
|
16
16
|
|
|
17
17
|
STYLE_NEW = {
|
|
18
18
|
"font_bold": {"family": "Amsterdam Sans ExtraBold, Corbel", "size": 15},
|
|
19
|
+
"font_bold_corbel": {"family": "Corbel Bold", "size": 15},
|
|
19
20
|
"font": {"family": "Amsterdam Sans, Corbel", "size": 15},
|
|
20
|
-
"
|
|
21
|
+
"font_corbel": {"family": "Corbel", "size": 15},
|
|
22
|
+
"axis_font": {"family": "Amsterdam Sans ExtraBold, Corbel", "size": 15},
|
|
21
23
|
"plot_bgcolor": "#FFFFFF",
|
|
22
24
|
"gridline_color": "#dbdbdb",
|
|
23
25
|
"gridline_width": 0.75,
|
|
@@ -13,6 +13,7 @@ def line(
|
|
|
13
13
|
width=750,
|
|
14
14
|
height=490,
|
|
15
15
|
color_discrete_sequence=None,
|
|
16
|
+
font="Amsterdam Sans",
|
|
16
17
|
**kwargs,
|
|
17
18
|
):
|
|
18
19
|
fig = px.line(
|
|
@@ -23,7 +24,7 @@ def line(
|
|
|
23
24
|
width=width,
|
|
24
25
|
height=height,
|
|
25
26
|
color_discrete_sequence=color_discrete_sequence,
|
|
26
|
-
template=BaseStyle().get_base_template(graph_type="line"),
|
|
27
|
+
template=BaseStyle().get_base_template(graph_type="line", font=font),
|
|
27
28
|
**kwargs,
|
|
28
29
|
)
|
|
29
30
|
|
|
@@ -14,6 +14,7 @@ def pie(
|
|
|
14
14
|
height=490,
|
|
15
15
|
text_format: str = None,
|
|
16
16
|
color_discrete_sequence=None,
|
|
17
|
+
font="Amsterdam Sans",
|
|
17
18
|
**kwargs,
|
|
18
19
|
):
|
|
19
20
|
fig = px.pie(
|
|
@@ -23,7 +24,7 @@ def pie(
|
|
|
23
24
|
width=width,
|
|
24
25
|
height=height,
|
|
25
26
|
hole=hole,
|
|
26
|
-
template=BaseStyle().get_base_template(),
|
|
27
|
+
template=BaseStyle().get_base_template(font=font),
|
|
27
28
|
color_discrete_sequence=color_discrete_sequence,
|
|
28
29
|
**kwargs,
|
|
29
30
|
)
|
|
@@ -109,7 +109,6 @@ class BaseStyle:
|
|
|
109
109
|
self.style = json.load(file)
|
|
110
110
|
|
|
111
111
|
def _get_axis_format(self):
|
|
112
|
-
self.gridline_color = "#dbdbdb" # Jorren vragen om deze aan te passen
|
|
113
112
|
|
|
114
113
|
return {
|
|
115
114
|
"zerolinecolor": self.style["gridline_color"],
|
|
@@ -121,29 +120,37 @@ class BaseStyle:
|
|
|
121
120
|
"showgrid": self.style["showgrid"],
|
|
122
121
|
}
|
|
123
122
|
|
|
124
|
-
def _get_base_template_layout(self):
|
|
123
|
+
def _get_base_template_layout(self, font):
|
|
124
|
+
if font == "Amsterdam Sans":
|
|
125
|
+
font_ = self.style["font"]
|
|
126
|
+
font_bold_ = self.style["font_bold"]
|
|
127
|
+
elif font == "Corbel":
|
|
128
|
+
font_ = self.style["font_corbel"]
|
|
129
|
+
font_bold_ = self.style["font_bold_corbel"]
|
|
130
|
+
else:
|
|
131
|
+
raise ValueError("Font should be 'Amsterdam Sans' or 'Corbel'")
|
|
132
|
+
|
|
125
133
|
return go.layout.Template(
|
|
126
134
|
layout={
|
|
127
|
-
# "font": self.styles["font_bold"],
|
|
128
135
|
"xaxis": {
|
|
129
|
-
"tickfont":
|
|
136
|
+
"tickfont": font_bold_,
|
|
130
137
|
},
|
|
131
138
|
"yaxis": {
|
|
132
|
-
"tickfont":
|
|
133
|
-
"family": self.style["axis_font"]["family"],
|
|
134
|
-
"size": self.style["axis_font"]["size"],
|
|
135
|
-
},
|
|
139
|
+
"tickfont": font_bold_,
|
|
136
140
|
},
|
|
137
|
-
"legend": {"font":
|
|
141
|
+
"legend": {"font": font_},
|
|
138
142
|
"plot_bgcolor": self.style["plot_bgcolor"],
|
|
139
|
-
|
|
140
|
-
"
|
|
141
|
-
"font": self.style["font_bold"],
|
|
143
|
+
"separators": ",",
|
|
144
|
+
"font": font_bold_,
|
|
142
145
|
}
|
|
143
146
|
)
|
|
144
147
|
|
|
145
148
|
def get_base_template(
|
|
146
|
-
self,
|
|
149
|
+
self,
|
|
150
|
+
graph_type: str = None,
|
|
151
|
+
orientation: str = None,
|
|
152
|
+
colors: str = None,
|
|
153
|
+
font: str = "Amsterdam Sans",
|
|
147
154
|
):
|
|
148
155
|
"""[summary]
|
|
149
156
|
|
|
@@ -158,7 +165,7 @@ class BaseStyle:
|
|
|
158
165
|
Returns:
|
|
159
166
|
[type]: [description]
|
|
160
167
|
"""
|
|
161
|
-
base_template = self._get_base_template_layout()
|
|
168
|
+
base_template = self._get_base_template_layout(font)
|
|
162
169
|
axis_format = self._get_axis_format()
|
|
163
170
|
|
|
164
171
|
if graph_type == "bar":
|
|
@@ -56,6 +56,8 @@ def cols_to_str(df: pd.DataFrame) -> pd.DataFrame:
|
|
|
56
56
|
Returns:
|
|
57
57
|
pd.DataFrame: Dataframe with column names as strings
|
|
58
58
|
"""
|
|
59
|
+
|
|
60
|
+
# Multiindex columns are always strings and therefore can't be casted as string
|
|
59
61
|
if df.columns.nlevels == 1:
|
|
60
62
|
df.columns = df.columns.astype(str)
|
|
61
63
|
|
|
@@ -379,6 +381,7 @@ def write_to_worksheet(
|
|
|
379
381
|
source: str | None = None,
|
|
380
382
|
col_filter: bool | None = None,
|
|
381
383
|
col_widths: list | None = None,
|
|
384
|
+
min_column_width: int | None = None,
|
|
382
385
|
cells_to_merge: list[list[int]] | None = None,
|
|
383
386
|
) -> None:
|
|
384
387
|
"""Writing data to worksheet. Used for writing values to cells and formatting the cells
|
|
@@ -423,7 +426,7 @@ def write_to_worksheet(
|
|
|
423
426
|
_insert_source(ws, source, arr)
|
|
424
427
|
|
|
425
428
|
if col_widths:
|
|
426
|
-
_set_column_widths(ws, col_widths)
|
|
429
|
+
_set_column_widths(ws, col_widths, min_column_width)
|
|
427
430
|
|
|
428
431
|
if title:
|
|
429
432
|
_insert_title(ws, title)
|
|
@@ -432,9 +435,16 @@ def write_to_worksheet(
|
|
|
432
435
|
_merge_cells(ws, cells_to_merge, title)
|
|
433
436
|
|
|
434
437
|
|
|
435
|
-
def _set_column_widths(
|
|
438
|
+
def _set_column_widths(
|
|
439
|
+
ws: Any, col_widths: list[int], min_column_width: int | None
|
|
440
|
+
) -> None:
|
|
436
441
|
for idx, col_width in enumerate(col_widths):
|
|
437
442
|
col_letter = get_column_letter(idx + 1)
|
|
443
|
+
|
|
444
|
+
if min_column_width:
|
|
445
|
+
if col_width < min_column_width:
|
|
446
|
+
col_width = min_column_width
|
|
447
|
+
|
|
438
448
|
ws.column_dimensions[col_letter].width = col_width
|
|
439
449
|
|
|
440
450
|
|
|
@@ -493,6 +503,7 @@ def write_table(
|
|
|
493
503
|
blue_border_row_ids: int | list[int] | None = None,
|
|
494
504
|
number_format: str = "0.0",
|
|
495
505
|
autofit_columns: str | None = "column_names",
|
|
506
|
+
min_column_width: int | None = None,
|
|
496
507
|
col_filter: bool | None = False,
|
|
497
508
|
style: str = "old",
|
|
498
509
|
combine_multiindex: bool | int = False,
|
|
@@ -508,9 +519,6 @@ def write_table(
|
|
|
508
519
|
data = {"Sheet1": data}
|
|
509
520
|
|
|
510
521
|
for sheet_name, df in data.items():
|
|
511
|
-
if column_names_to_string == True:
|
|
512
|
-
df = cols_to_str(df)
|
|
513
|
-
|
|
514
522
|
format_worksheet(
|
|
515
523
|
wb=wb,
|
|
516
524
|
df=df,
|
|
@@ -534,6 +542,7 @@ def write_table(
|
|
|
534
542
|
blue_border_row_ids=blue_border_row_ids,
|
|
535
543
|
number_format=number_format,
|
|
536
544
|
autofit_columns=autofit_columns,
|
|
545
|
+
min_column_width=min_column_width,
|
|
537
546
|
col_filter=col_filter,
|
|
538
547
|
combine_multiindex=combine_multiindex,
|
|
539
548
|
column_names_to_string=column_names_to_string,
|
|
@@ -582,6 +591,7 @@ def format_worksheet(
|
|
|
582
591
|
blue_border_row_ids: int | list[int] | None = None,
|
|
583
592
|
number_format: str = "0.0",
|
|
584
593
|
autofit_columns: str | None = "column_names",
|
|
594
|
+
min_column_width: int | None = None,
|
|
585
595
|
col_filter: bool | None = False,
|
|
586
596
|
combine_multiindex: bool | int = False,
|
|
587
597
|
column_names_to_string: bool = True,
|
|
@@ -607,6 +617,9 @@ def format_worksheet(
|
|
|
607
617
|
perc_col_format (str, optional): The formatting string of percentage columns. Defaults to None.
|
|
608
618
|
col_filter (bool, optional): Set filter on columns. Defaults to False.
|
|
609
619
|
"""
|
|
620
|
+
if column_names_to_string == True:
|
|
621
|
+
df = cols_to_str(df)
|
|
622
|
+
|
|
610
623
|
arr = df_to_array(df)
|
|
611
624
|
|
|
612
625
|
blue_rows = []
|
|
@@ -711,4 +724,5 @@ def format_worksheet(
|
|
|
711
724
|
col_filter=col_filter,
|
|
712
725
|
col_widths=col_widths,
|
|
713
726
|
cells_to_merge=cells_to_merge,
|
|
727
|
+
min_column_width=min_column_width,
|
|
714
728
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: toolsos
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: OS tools
|
|
5
5
|
Author-email: OS <d.schmitz@amsterdam.nl>
|
|
6
6
|
Keywords: tools,Onderzoek & Statistiek
|
|
@@ -63,5 +63,12 @@ Instructions on building a package can be found [here](https://packaging.python.
|
|
|
63
63
|
|
|
64
64
|
- make a pypi account
|
|
65
65
|
- ask to be added as collaborator to toolsos
|
|
66
|
-
- first update twine: py -m pip install --upgrade
|
|
66
|
+
- first update twine: py -m pip install --upgrade twine
|
|
67
67
|
- upload to pypi: twine upload dist/* --skip-existing
|
|
68
|
+
|
|
69
|
+
## Install to local enviroment for testing
|
|
70
|
+
|
|
71
|
+
- python -m venv local (maak een lokale venv aan)
|
|
72
|
+
- local\Scripts\activate (activeer de venv)
|
|
73
|
+
- pip install -e . (installer toolsos)
|
|
74
|
+
- pip install -r local_requirements.txt (installeer de benodigde dependencies)
|
|
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
|