reykit 1.1.33__py3-none-any.whl → 1.1.35__py3-none-any.whl
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.
- reykit/rbase.py +4 -42
- reykit/rdata.py +45 -0
- reykit/rlog.py +6 -3
- reykit/rmonkey.py +48 -63
- reykit/ros.py +1 -1
- reykit/rstdout.py +4 -2
- reykit/rtable.py +412 -406
- reykit/rtask.py +4 -2
- reykit/rtext.py +1 -49
- reykit/rtime.py +13 -12
- {reykit-1.1.33.dist-info → reykit-1.1.35.dist-info}/METADATA +1 -2
- {reykit-1.1.33.dist-info → reykit-1.1.35.dist-info}/RECORD +14 -14
- {reykit-1.1.33.dist-info → reykit-1.1.35.dist-info}/WHEEL +0 -0
- {reykit-1.1.33.dist-info → reykit-1.1.35.dist-info}/licenses/LICENSE +0 -0
reykit/rtable.py
CHANGED
@@ -9,503 +9,509 @@
|
|
9
9
|
"""
|
10
10
|
|
11
11
|
|
12
|
-
from typing import Any, TypedDict, overload
|
13
|
-
from collections.abc import
|
12
|
+
from typing import Any, TypedDict, Literal, overload
|
13
|
+
from collections.abc import Collection, MutableMapping
|
14
14
|
from os.path import abspath as os_abspath
|
15
|
-
from
|
16
|
-
from
|
15
|
+
from sqlalchemy.engine.cursor import CursorResult, Row as CursorRow
|
16
|
+
from pandas import DataFrame, Series, ExcelWriter
|
17
17
|
|
18
|
+
from .rbase import Base, throw
|
19
|
+
from .rdata import to_json
|
18
20
|
from .ros import File
|
19
|
-
from .rtext import
|
21
|
+
from .rtext import to_text
|
20
22
|
from .rtime import time_to
|
21
23
|
|
22
24
|
|
23
25
|
__all__ = (
|
24
|
-
'
|
25
|
-
'
|
26
|
-
'
|
27
|
-
'to_df',
|
28
|
-
'to_json',
|
29
|
-
'to_text',
|
30
|
-
'to_sql',
|
31
|
-
'to_html',
|
32
|
-
'to_csv',
|
33
|
-
'to_excel'
|
26
|
+
'is_row',
|
27
|
+
'is_table',
|
28
|
+
'Table'
|
34
29
|
)
|
35
30
|
|
36
31
|
|
37
|
-
type
|
32
|
+
type RowData = MutableMapping | CursorRow | Series
|
33
|
+
type TableData = Collection[MutableMapping] | RowData | CursorResult | DataFrame
|
38
34
|
SheetSet = TypedDict('SheetsSet', {'name': str, 'index': int, 'fields': str | list[str]})
|
39
35
|
|
40
36
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
37
|
+
@overload
|
38
|
+
def is_row(obj: RowData) -> Literal[True]: ...
|
39
|
+
|
40
|
+
@overload
|
41
|
+
def is_row(obj: Any) -> Literal[False]: ...
|
42
|
+
|
43
|
+
def is_row(obj: Any) -> bool:
|
45
44
|
"""
|
46
|
-
|
45
|
+
Judge whether it is row format.
|
47
46
|
|
48
47
|
Parameters
|
49
48
|
----------
|
50
|
-
|
51
|
-
fields : Table fields.
|
52
|
-
- `None`: Infer.
|
53
|
-
- `Iterable`: Use values in Iterable.
|
49
|
+
obj : Ojbect.
|
54
50
|
|
55
51
|
Returns
|
56
52
|
-------
|
57
|
-
|
53
|
+
Judgment result.
|
58
54
|
"""
|
59
55
|
|
60
|
-
#
|
61
|
-
|
56
|
+
# Judge.
|
57
|
+
result = isinstance(obj, (MutableMapping, CursorRow, Series))
|
62
58
|
|
63
|
-
|
64
|
-
case CursorResult():
|
65
|
-
fields = fields or data.keys()
|
66
|
-
data_table = [
|
67
|
-
dict(zip(fields, row))
|
68
|
-
for row in data
|
69
|
-
]
|
70
|
-
|
71
|
-
## From DataFrame object.
|
72
|
-
case DataFrame():
|
73
|
-
data_df = to_df(data, fields)
|
74
|
-
fields = data_df.columns
|
75
|
-
data_table = [
|
76
|
-
dict(zip(
|
77
|
-
fields,
|
78
|
-
[
|
79
|
-
None
|
80
|
-
if (type(value) != list and isnull(value))
|
81
|
-
else value
|
82
|
-
for value in row
|
83
|
-
]
|
84
|
-
))
|
85
|
-
for row in data_df.values
|
86
|
-
]
|
87
|
-
|
88
|
-
## From other object.
|
89
|
-
case _:
|
90
|
-
data_df = to_df(data, fields)
|
91
|
-
data_table = to_table(data_df)
|
92
|
-
|
93
|
-
return data_table
|
59
|
+
return result
|
94
60
|
|
95
61
|
|
96
62
|
@overload
|
97
|
-
def
|
98
|
-
data: Table | Iterable[Iterable],
|
99
|
-
key_field: int | str = 0
|
100
|
-
) -> dict[Any, dict]: ...
|
63
|
+
def is_table(obj: TableData) -> bool: ...
|
101
64
|
|
102
65
|
@overload
|
103
|
-
def
|
104
|
-
|
105
|
-
|
106
|
-
*,
|
107
|
-
val_field: int | str
|
108
|
-
) -> dict: ...
|
109
|
-
|
110
|
-
def to_dict(
|
111
|
-
data: Table | Iterable[Iterable],
|
112
|
-
key_field: int | str = 0,
|
113
|
-
val_field: int | str | None = None
|
114
|
-
) -> dict[Any, dict] | dict:
|
66
|
+
def is_table(obj: Any) -> Literal[False]: ...
|
67
|
+
|
68
|
+
def is_table(obj: Any) -> bool:
|
115
69
|
"""
|
116
|
-
|
70
|
+
Judge whether it is table format, and keys sort of the row are the same.
|
117
71
|
|
118
72
|
Parameters
|
119
73
|
----------
|
120
|
-
|
121
|
-
key_field : Key field of dictionary.
|
122
|
-
- `int`: Subscript index.
|
123
|
-
- `str`: Name index.
|
124
|
-
val_field : Value field of dictionary.
|
125
|
-
- `None`: All fields except key.
|
126
|
-
- `int`: Subscript index.
|
127
|
-
- `str`: Name index.
|
74
|
+
obj : Ojbect.
|
128
75
|
|
129
76
|
Returns
|
130
77
|
-------
|
131
|
-
|
78
|
+
Judgment result.
|
132
79
|
"""
|
133
80
|
|
134
|
-
#
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
key: value
|
155
|
-
for key, value in row.items()
|
156
|
-
if key != key_field
|
157
|
-
}
|
158
|
-
for row in data
|
159
|
-
}
|
160
|
-
|
161
|
-
## Value is one field.
|
162
|
-
else:
|
163
|
-
data_dict = {
|
164
|
-
row[key_field]: row[val_field]
|
165
|
-
for row in data
|
166
|
-
}
|
167
|
-
|
168
|
-
return data_dict
|
169
|
-
|
170
|
-
|
171
|
-
def to_list(
|
172
|
-
data: Table | Iterable[Iterable],
|
173
|
-
field: int | str = 0,
|
174
|
-
) -> list:
|
81
|
+
# Judge.
|
82
|
+
if is_row(obj):
|
83
|
+
return True
|
84
|
+
if isinstance(obj, (CursorResult, DataFrame)):
|
85
|
+
return True
|
86
|
+
if isinstance(obj, Collection):
|
87
|
+
keys_strs = []
|
88
|
+
for row in obj:
|
89
|
+
if not isinstance(row, MutableMapping):
|
90
|
+
break
|
91
|
+
keys_str = ':'.join(row.keys())
|
92
|
+
keys_strs.append(keys_str)
|
93
|
+
keys_strs = set(keys_strs)
|
94
|
+
if len(keys_strs) == 1:
|
95
|
+
return True
|
96
|
+
|
97
|
+
return False
|
98
|
+
|
99
|
+
|
100
|
+
class Table(Base):
|
175
101
|
"""
|
176
|
-
|
177
|
-
|
178
|
-
Parameters
|
179
|
-
----------
|
180
|
-
data : Table format data.
|
181
|
-
field : Field of value.
|
182
|
-
- `int`: Subscript index.
|
183
|
-
- `str`: Name index.
|
184
|
-
|
185
|
-
Returns
|
186
|
-
-------
|
187
|
-
List.
|
102
|
+
Table type.
|
188
103
|
"""
|
189
104
|
|
190
|
-
# Handle parameter.
|
191
|
-
data = to_table(data)
|
192
105
|
|
193
|
-
|
194
|
-
|
195
|
-
|
106
|
+
def __init__(self, data: TableData) -> None:
|
107
|
+
"""
|
108
|
+
Build instance attributes.
|
109
|
+
|
110
|
+
Parameters
|
111
|
+
----------
|
112
|
+
data : Data.
|
113
|
+
"""
|
114
|
+
|
115
|
+
# Set parameter.
|
116
|
+
self.data = data
|
117
|
+
|
118
|
+
|
119
|
+
def to_row(self) -> dict:
|
120
|
+
"""
|
121
|
+
Convert data to `dict` format.
|
122
|
+
|
123
|
+
Returns
|
124
|
+
-------
|
125
|
+
Converted data.
|
126
|
+
"""
|
127
|
+
|
128
|
+
# Convert.
|
129
|
+
match self.data:
|
130
|
+
case MutableMapping():
|
131
|
+
result = [dict(self.data)]
|
132
|
+
case CursorRow():
|
133
|
+
result = [dict(self.data._mapping)]
|
134
|
+
case Series():
|
135
|
+
result = [dict(self.data.items())]
|
136
|
+
|
137
|
+
return result
|
138
|
+
|
139
|
+
|
140
|
+
def to_table(self) -> list[dict]:
|
141
|
+
"""
|
142
|
+
Convert data to `list[dict]` format.
|
143
|
+
|
144
|
+
Returns
|
145
|
+
-------
|
146
|
+
Converted data.
|
147
|
+
"""
|
148
|
+
|
149
|
+
# Convert.
|
150
|
+
match self.data:
|
151
|
+
case MutableMapping() | CursorRow() | Series():
|
152
|
+
result = [self.to_row()]
|
153
|
+
case CursorResult():
|
154
|
+
result = [
|
155
|
+
dict(row)
|
156
|
+
for row in self.data.mappings()
|
157
|
+
]
|
158
|
+
case DataFrame():
|
159
|
+
result = self.data.to_dict('records')
|
160
|
+
case Collection():
|
161
|
+
if not is_table(self.data):
|
162
|
+
text = 'is not table format, or keys sort of the row are the not same'
|
163
|
+
throw(TypeError, text=text)
|
164
|
+
result = [
|
165
|
+
dict(row)
|
166
|
+
for row in self.data
|
167
|
+
]
|
168
|
+
|
169
|
+
return result
|
170
|
+
|
171
|
+
|
172
|
+
@overload
|
173
|
+
def to_dict(
|
174
|
+
self,
|
175
|
+
key_field: int | str = 0
|
176
|
+
) -> dict[Any, dict]: ...
|
177
|
+
|
178
|
+
@overload
|
179
|
+
def to_dict(
|
180
|
+
self,
|
181
|
+
key_field: int | str = 0,
|
182
|
+
*,
|
183
|
+
val_field: int | str
|
184
|
+
) -> dict: ...
|
185
|
+
|
186
|
+
def to_dict(
|
187
|
+
self,
|
188
|
+
key_field: int | str = 0,
|
189
|
+
val_field: int | str | None = None
|
190
|
+
) -> dict[Any, dict] | dict:
|
191
|
+
"""
|
192
|
+
Convert data as dictionary.
|
193
|
+
|
194
|
+
Parameters
|
195
|
+
----------
|
196
|
+
key_field : Key field of dictionary.
|
197
|
+
- `int`: Subscript index.
|
198
|
+
- `str`: Name index.
|
199
|
+
val_field : Value field of dictionary.
|
200
|
+
- `None`: All fields except key.
|
201
|
+
- `int`: Subscript index.
|
202
|
+
- `str`: Name index.
|
203
|
+
|
204
|
+
Returns
|
205
|
+
-------
|
206
|
+
Dictionary.
|
207
|
+
"""
|
208
|
+
|
209
|
+
# Get parameter.
|
210
|
+
data = self.to_table()
|
211
|
+
|
212
|
+
# Check.
|
213
|
+
if len(data) == 0:
|
214
|
+
return {}
|
215
|
+
|
216
|
+
# Get fields.
|
217
|
+
fields = list(data[0].keys())
|
218
|
+
if type(key_field) == int:
|
219
|
+
key_field = fields[key_field]
|
220
|
+
if type(val_field) == int:
|
221
|
+
val_field = fields[val_field]
|
222
|
+
|
223
|
+
# Convert.
|
224
|
+
|
225
|
+
## Value is all fields except key.
|
226
|
+
if val_field is None:
|
227
|
+
data_dict = {
|
228
|
+
row[key_field]: {
|
229
|
+
key: value
|
230
|
+
for key, value in row.items()
|
231
|
+
if key != key_field
|
232
|
+
}
|
233
|
+
for row in data
|
234
|
+
}
|
196
235
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
236
|
+
## Value is one field.
|
237
|
+
else:
|
238
|
+
data_dict = {
|
239
|
+
row[key_field]: row[val_field]
|
240
|
+
for row in data
|
241
|
+
}
|
201
242
|
|
202
|
-
|
203
|
-
data_list = [
|
204
|
-
row[field]
|
205
|
-
for row in data
|
206
|
-
]
|
243
|
+
return data_dict
|
207
244
|
|
208
|
-
return data_list
|
209
245
|
|
246
|
+
def to_list(self, field: int | str = 0) -> list:
|
247
|
+
"""
|
248
|
+
Convert data as list.
|
210
249
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
Convert data to table of `DataFrame` object.
|
250
|
+
Parameters
|
251
|
+
----------
|
252
|
+
field : Field of value.
|
253
|
+
- `int`: Subscript index.
|
254
|
+
- `str`: Name index.
|
217
255
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
- `None`: Infer.
|
223
|
-
- `Iterable`: Use values in Iterable.
|
256
|
+
Returns
|
257
|
+
-------
|
258
|
+
List.
|
259
|
+
"""
|
224
260
|
|
225
|
-
|
226
|
-
|
227
|
-
DataFrame object.
|
228
|
-
"""
|
261
|
+
# Get parameter.
|
262
|
+
data = self.to_table()
|
229
263
|
|
230
|
-
|
231
|
-
|
264
|
+
# Check.
|
265
|
+
if len(data) == 0:
|
266
|
+
return []
|
232
267
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
data_df = data_df.convert_dtypes()
|
268
|
+
# Get fields.
|
269
|
+
fields = list(data[0].keys())
|
270
|
+
if type(field) == int:
|
271
|
+
field = fields[field]
|
238
272
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
273
|
+
# Convert.
|
274
|
+
data_list = [
|
275
|
+
row[field]
|
276
|
+
for row in data
|
277
|
+
]
|
244
278
|
|
245
|
-
|
246
|
-
case _:
|
247
|
-
if type(data) == dict:
|
248
|
-
data = [data]
|
249
|
-
data_df = DataFrame(data, columns=fields)
|
250
|
-
data_df = data_df.convert_dtypes()
|
279
|
+
return data_list
|
251
280
|
|
252
|
-
return data_df
|
253
281
|
|
282
|
+
def to_text(self, width: int | None = None) -> str:
|
283
|
+
"""
|
284
|
+
Convert data to text.
|
254
285
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
) -> str:
|
260
|
-
"""
|
261
|
-
Convert data to JSON string.
|
286
|
+
Parameters
|
287
|
+
----------
|
288
|
+
width : Format width.
|
289
|
+
- `None` : Use terminal display character size.
|
262
290
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
- `None`: Infer.
|
268
|
-
- `Iterable`: Use values in Iterable.
|
269
|
-
compact : Whether compact content.
|
291
|
+
Returns
|
292
|
+
-------
|
293
|
+
Formatted text.
|
294
|
+
"""
|
270
295
|
|
271
|
-
|
272
|
-
|
273
|
-
JSON string.
|
274
|
-
"""
|
296
|
+
# Get parameter.
|
297
|
+
data = self.to_table()
|
275
298
|
|
276
|
-
|
277
|
-
|
299
|
+
# Convert.
|
300
|
+
text = to_text(data, width)
|
278
301
|
|
279
|
-
|
280
|
-
string = to_json(data, compact)
|
302
|
+
return text
|
281
303
|
|
282
|
-
return string
|
283
304
|
|
305
|
+
def to_json(self, compact: bool = True) -> str:
|
306
|
+
"""
|
307
|
+
Convert data to JSON string.
|
284
308
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
width: int = 100
|
289
|
-
) -> str:
|
290
|
-
"""
|
291
|
-
Convert data to text.
|
309
|
+
Parameters
|
310
|
+
----------
|
311
|
+
compact : Whether compact content.
|
292
312
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
- `None`: Infer.
|
298
|
-
- `Iterable`: Use values in Iterable.
|
299
|
-
width : Format width.
|
313
|
+
Returns
|
314
|
+
-------
|
315
|
+
JSON string.
|
316
|
+
"""
|
300
317
|
|
301
|
-
|
302
|
-
|
303
|
-
Formatted text.
|
304
|
-
"""
|
318
|
+
# Get parameter.
|
319
|
+
data = self.to_table()
|
305
320
|
|
306
|
-
|
307
|
-
|
321
|
+
# Convert.
|
322
|
+
string = to_json(data, compact)
|
308
323
|
|
309
|
-
|
310
|
-
text = to_text(data, width)
|
324
|
+
return string
|
311
325
|
|
312
|
-
return text
|
313
326
|
|
327
|
+
def to_sql(self) -> str:
|
328
|
+
"""
|
329
|
+
Convert data to SQL string.
|
314
330
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
"""
|
320
|
-
Convert data to SQL string.
|
331
|
+
Returns
|
332
|
+
-------
|
333
|
+
SQL string.
|
334
|
+
"""
|
321
335
|
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
336
|
+
# Get parameter.
|
337
|
+
data = self.to_table()
|
338
|
+
data = [
|
339
|
+
{
|
340
|
+
key : (
|
341
|
+
repr(time_to(value, raising=False))
|
342
|
+
if bool(value)
|
343
|
+
else 'NULL'
|
344
|
+
)
|
345
|
+
for key, value in row.items()
|
346
|
+
}
|
347
|
+
for row in data
|
348
|
+
]
|
328
349
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
"""
|
350
|
+
# Check.
|
351
|
+
if len(data) == 0:
|
352
|
+
throw(ValueError, data)
|
333
353
|
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
data = to_table(data, fields)
|
339
|
-
fields = data[0].keys()
|
340
|
-
|
341
|
-
# Generate SQL.
|
342
|
-
sql_rows_values = [
|
343
|
-
[
|
344
|
-
repr(time_to(value, raising=False))
|
345
|
-
if value is not None
|
346
|
-
else 'NULL'
|
347
|
-
for value in row
|
354
|
+
# Generate SQL.
|
355
|
+
sql_rows = [
|
356
|
+
'SELECT ' + ','.join(row.values())
|
357
|
+
for row in data[1:]
|
348
358
|
]
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
f'{value} AS `{key}`'
|
358
|
-
for key, value in list(zip(fields, sql_rows_values[0]))
|
359
|
-
]
|
360
|
-
)
|
361
|
-
sql_rows[0] = sql_row_first
|
362
|
-
data_sql = ' UNION ALL '.join(sql_rows)
|
359
|
+
sql_row_first = 'SELECT ' + ','.join(
|
360
|
+
[
|
361
|
+
f'{value} AS `{key}`'
|
362
|
+
for key, value in data[0].items()
|
363
|
+
]
|
364
|
+
)
|
365
|
+
sql_rows.insert(0, sql_row_first)
|
366
|
+
data_sql = ' UNION ALL '.join(sql_rows)
|
363
367
|
|
364
|
-
|
368
|
+
return data_sql
|
365
369
|
|
366
370
|
|
367
|
-
def
|
368
|
-
|
369
|
-
|
370
|
-
) -> str:
|
371
|
-
"""
|
372
|
-
Convert data to HTML string.
|
371
|
+
def to_df(self) -> DataFrame:
|
372
|
+
"""
|
373
|
+
Convert data to table of `DataFrame` object.
|
373
374
|
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
- `None`: Infer.
|
379
|
-
- `Iterable`: Use values in Iterable.
|
375
|
+
Returns
|
376
|
+
-------
|
377
|
+
DataFrame object.
|
378
|
+
"""
|
380
379
|
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
"""
|
380
|
+
# Check.
|
381
|
+
if type(self.data) == DataFrame:
|
382
|
+
return self.data
|
385
383
|
|
386
|
-
|
387
|
-
|
384
|
+
# Get parameter.
|
385
|
+
data = self.to_table()
|
388
386
|
|
389
|
-
|
390
|
-
|
387
|
+
# Convert.
|
388
|
+
result = DataFrame(data)
|
391
389
|
|
392
|
-
|
390
|
+
return result
|
393
391
|
|
394
392
|
|
395
|
-
def
|
396
|
-
|
397
|
-
|
398
|
-
fields: Iterable | None = None
|
399
|
-
) -> str:
|
400
|
-
"""
|
401
|
-
Convert data to save CSV format file.
|
402
|
-
When file exist, then append data.
|
393
|
+
def to_html(self) -> str:
|
394
|
+
"""
|
395
|
+
Convert data to HTML string.
|
403
396
|
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
fields : Table fields.
|
409
|
-
- `None`: Infer.
|
410
|
-
- `Iterable`: Use values in Iterable.
|
397
|
+
Returns
|
398
|
+
-------
|
399
|
+
HTML string.
|
400
|
+
"""
|
411
401
|
|
412
|
-
|
413
|
-
|
414
|
-
File absolute path.
|
415
|
-
"""
|
402
|
+
# Get parameter.
|
403
|
+
data = self.to_df()
|
416
404
|
|
417
|
-
|
418
|
-
|
419
|
-
rfile = File(path)
|
420
|
-
if rfile:
|
421
|
-
header = False
|
422
|
-
else:
|
423
|
-
header = True
|
405
|
+
# Convert.
|
406
|
+
result = data.to_html(col_space=50, index=False, justify='center')
|
424
407
|
|
425
|
-
|
426
|
-
data_df.to_csv(rfile.path, header=header, index=False, mode='a')
|
408
|
+
return result
|
427
409
|
|
428
|
-
return rfile.path
|
429
410
|
|
411
|
+
def to_csv(self, path: str = 'data.csv') -> str:
|
412
|
+
"""
|
413
|
+
Convert data to save CSV format file.
|
414
|
+
When file exist, then append data.
|
430
415
|
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
group_field: str | None = None,
|
435
|
-
sheets_set: dict[str | int, SheetSet] = {}
|
436
|
-
) -> str:
|
437
|
-
"""
|
438
|
-
Convert data to save Excel format file and return sheet name and sheet data.
|
439
|
-
When file exist, then rebuild file.
|
440
|
-
|
441
|
-
Parameters
|
442
|
-
----------
|
443
|
-
data : Table format data.
|
444
|
-
path : File save path.
|
445
|
-
group_field : Group filed.
|
446
|
-
sheets_set : Set sheet new name and sort sheet and filter sheet fields,
|
447
|
-
key is old name or index, value is set parameters.
|
448
|
-
- Parameter `name` : Set sheet new name.
|
449
|
-
- Parameter `index` : Sort sheet.
|
450
|
-
- Parameter `fields` : Filter sheet fields.
|
416
|
+
Parameters
|
417
|
+
----------
|
418
|
+
path : File save path.
|
451
419
|
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
Examples
|
457
|
-
--------
|
458
|
-
>>> data = [
|
459
|
-
... {'id': 1, 'age': 21, 'group': 'one'},
|
460
|
-
... {'id': 2, 'age': 22, 'group': 'one'},
|
461
|
-
... {'id': 3, 'age': 23, 'group': 'two'}
|
462
|
-
... ]
|
463
|
-
>>> sheets_set = {
|
464
|
-
... 'one': {'name': 'age', 'index': 2, 'fields': ['id', 'age']},
|
465
|
-
... 'two': {'name': 'id', 'index': 1, 'fields': 'id'}
|
466
|
-
... }
|
467
|
-
>>> to_excel(data, 'file.xlsx', 'group', sheets_set)
|
468
|
-
"""
|
420
|
+
Returns
|
421
|
+
-------
|
422
|
+
File absolute path.
|
423
|
+
"""
|
469
424
|
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
# Generate sheets.
|
476
|
-
if group_field is None:
|
477
|
-
data_group = (('Sheet1', data),)
|
478
|
-
else:
|
479
|
-
data_group = data.groupby(group_field)
|
480
|
-
sheets_table_before = []
|
481
|
-
sheets_table_after = []
|
482
|
-
for index, sheet_table in enumerate(data_group):
|
483
|
-
sheet_name, sheet_df = sheet_table
|
484
|
-
if group_field is not None:
|
485
|
-
del sheet_df[group_field]
|
486
|
-
if sheet_name in sheets_set:
|
487
|
-
sheet_set = sheets_set[sheet_name]
|
488
|
-
elif index in sheets_set:
|
489
|
-
sheet_set = sheets_set[index]
|
425
|
+
# Get parameter.
|
426
|
+
data = self.to_df()
|
427
|
+
rfile = File(path)
|
428
|
+
if rfile:
|
429
|
+
header = False
|
490
430
|
else:
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
431
|
+
header = True
|
432
|
+
|
433
|
+
# Save file.
|
434
|
+
data.to_csv(rfile.path, header=header, index=False, mode='a')
|
435
|
+
|
436
|
+
return rfile.path
|
437
|
+
|
438
|
+
|
439
|
+
def to_excel(
|
440
|
+
self,
|
441
|
+
path: str = 'data.xlsx',
|
442
|
+
group_field: str | None = None,
|
443
|
+
sheets_set: dict[str | int, SheetSet] = {}
|
444
|
+
) -> str:
|
445
|
+
"""
|
446
|
+
Convert data to save Excel format file and return sheet name and sheet data.
|
447
|
+
When file exist, then rebuild file.
|
448
|
+
|
449
|
+
Parameters
|
450
|
+
----------
|
451
|
+
path : File save path.
|
452
|
+
group_field : Group filed.
|
453
|
+
sheets_set : Set sheet new name and sort sheet and filter sheet fields,
|
454
|
+
key is old name or index, value is set parameters.
|
455
|
+
- Parameter `name` : Set sheet new name.
|
456
|
+
- Parameter `index` : Sort sheet.
|
457
|
+
- Parameter `fields` : Filter sheet fields.
|
458
|
+
|
459
|
+
Returns
|
460
|
+
-------
|
461
|
+
File absolute path.
|
462
|
+
|
463
|
+
Examples
|
464
|
+
--------
|
465
|
+
>>> data = [
|
466
|
+
... {'id': 1, 'age': 21, 'group': 'one'},
|
467
|
+
... {'id': 2, 'age': 22, 'group': 'one'},
|
468
|
+
... {'id': 3, 'age': 23, 'group': 'two'}
|
469
|
+
... ]
|
470
|
+
>>> sheets_set = {
|
471
|
+
... 'one': {'name': 'age', 'index': 2, 'fields': ['id', 'age']},
|
472
|
+
... 'two': {'name': 'id', 'index': 1, 'fields': 'id'}
|
473
|
+
... }
|
474
|
+
>>> to_excel(data, 'file.xlsx', 'group', sheets_set)
|
475
|
+
"""
|
476
|
+
|
477
|
+
# Get parameter.
|
478
|
+
data = self.to_df()
|
479
|
+
path = os_abspath(path)
|
480
|
+
|
481
|
+
# Generate sheets.
|
482
|
+
if group_field is None:
|
483
|
+
data_group = (('Sheet1', data),)
|
499
484
|
else:
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
485
|
+
data_group = data.groupby(group_field)
|
486
|
+
sheets_table_before = []
|
487
|
+
sheets_table_after = []
|
488
|
+
for index, sheet_table in enumerate(data_group):
|
489
|
+
sheet_name, sheet_df = sheet_table
|
490
|
+
if group_field is not None:
|
491
|
+
del sheet_df[group_field]
|
492
|
+
if sheet_name in sheets_set:
|
493
|
+
sheet_set = sheets_set[sheet_name]
|
494
|
+
elif index in sheets_set:
|
495
|
+
sheet_set = sheets_set[index]
|
496
|
+
else:
|
497
|
+
sheets_table_after.append((sheet_name, sheet_df))
|
498
|
+
continue
|
499
|
+
if 'name' in sheet_set:
|
500
|
+
sheet_name = sheet_set['name']
|
501
|
+
if 'fields' in sheet_set:
|
502
|
+
sheet_df = sheet_df[sheet_set['fields']]
|
503
|
+
if 'index' in sheet_set:
|
504
|
+
sheets_table_before.append((sheet_set['index'], (sheet_name, sheet_df)))
|
505
|
+
else:
|
506
|
+
sheets_table_after.append((sheet_name, sheet_df))
|
507
|
+
sort_func = lambda item: item[0]
|
508
|
+
sheets_table_before.sort(key=sort_func)
|
509
|
+
sheets_table = [sheet_table for sheet_index, sheet_table in sheets_table_before] + sheets_table_after
|
510
|
+
|
511
|
+
# Save file.
|
512
|
+
excel = ExcelWriter(path)
|
513
|
+
for sheet_name, sheet_df in sheets_table:
|
514
|
+
sheet_df.to_excel(excel, sheet_name, index=False)
|
515
|
+
excel.close()
|
516
|
+
|
517
|
+
return path
|