table-stream 0.2.0__tar.gz → 0.2.2__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.
- {table_stream-0.2.0 → table_stream-0.2.2}/PKG-INFO +1 -1
- {table_stream-0.2.0 → table_stream-0.2.2}/pyproject.toml +1 -1
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream/__init__.py +4 -3
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream/erros.py +24 -18
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream/sysfiles.py +0 -1
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream/table.py +129 -110
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream.egg-info/PKG-INFO +1 -1
- {table_stream-0.2.0 → table_stream-0.2.2}/README.md +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/setup.cfg +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream/hash_map.py +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream/notifier.py +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream/pattner/__init__.py +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream/pattner/adapter.py +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream/sheet/__init__.py +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream/sheet/check_mod.py +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream/sheet/load.py +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream/sheet/options.py +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream/sheet/parse.py +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream/sheet/save.py +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream/state.py +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream/thread.py +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream/workbook.py +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream.egg-info/SOURCES.txt +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream.egg-info/dependency_links.txt +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream.egg-info/requires.txt +0 -0
- {table_stream-0.2.0 → table_stream-0.2.2}/table_stream.egg-info/top_level.txt +0 -0
|
@@ -66,11 +66,12 @@ from .table import (
|
|
|
66
66
|
TableEmptyError,
|
|
67
67
|
EmptyRowError,
|
|
68
68
|
ColumnNotFoundError,
|
|
69
|
-
|
|
69
|
+
ColumnNotFoudError,
|
|
70
70
|
HeadersSizeNotIqualError,
|
|
71
71
|
concat_tables,
|
|
72
72
|
RowNotExistError,
|
|
73
73
|
TableData,
|
|
74
|
+
Table,
|
|
74
75
|
ListTablesEmptyError,
|
|
75
76
|
)
|
|
76
77
|
|
|
@@ -84,8 +85,8 @@ from .erros import (
|
|
|
84
85
|
ListTablesEmptyError,
|
|
85
86
|
LoadWorkbookError,
|
|
86
87
|
NotImplementedModuleError,
|
|
87
|
-
|
|
88
|
+
ColumnNotFoudError,
|
|
88
89
|
HeadersSizeNotIqualError,
|
|
89
90
|
)
|
|
90
91
|
|
|
91
|
-
__version__ = "0.2.
|
|
92
|
+
__version__ = "0.2.2"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class CoreException(Exception):
|
|
2
2
|
|
|
3
|
-
def __init__(self, message: str = f
|
|
3
|
+
def __init__(self, message: str = f"Erro") -> None:
|
|
4
4
|
super().__init__(message)
|
|
5
5
|
self._message = message
|
|
6
6
|
|
|
@@ -17,13 +17,13 @@ class CoreException(Exception):
|
|
|
17
17
|
|
|
18
18
|
class ValueNotifyNullError(CoreException):
|
|
19
19
|
|
|
20
|
-
def __init__(self, message: str =
|
|
20
|
+
def __init__(self, message: str = "Notificação nula...") -> None:
|
|
21
21
|
super().__init__(message)
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
class UnsuportedSheetError(CoreException):
|
|
25
25
|
|
|
26
|
-
def __init__(self, message: str =
|
|
26
|
+
def __init__(self, message: str = "Planilha inválida...") -> None:
|
|
27
27
|
super().__init__(message)
|
|
28
28
|
|
|
29
29
|
|
|
@@ -31,21 +31,22 @@ class UnsuportedSheetError(CoreException):
|
|
|
31
31
|
# Erros relacionados a HashMap
|
|
32
32
|
# ============================================================#
|
|
33
33
|
|
|
34
|
+
|
|
34
35
|
class InvalidHashMapTableError(CoreException):
|
|
35
36
|
|
|
36
|
-
def __init__(self, message: str =
|
|
37
|
+
def __init__(self, message: str = "HashMap inválido") -> None:
|
|
37
38
|
super().__init__(message)
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
class InvalidBodyTableError(InvalidHashMapTableError):
|
|
41
42
|
|
|
42
|
-
def __init__(self, message: str =
|
|
43
|
+
def __init__(self, message: str = "Erro corpo de tabela inválido") -> None:
|
|
43
44
|
super().__init__(message)
|
|
44
45
|
|
|
45
46
|
|
|
46
47
|
class SizeTableError(InvalidHashMapTableError):
|
|
47
48
|
|
|
48
|
-
def __init__(self, message: str =
|
|
49
|
+
def __init__(self, message: str = "Tamanho de tabela inválido") -> None:
|
|
49
50
|
super().__init__(message)
|
|
50
51
|
|
|
51
52
|
|
|
@@ -54,21 +55,22 @@ class SizeTableError(InvalidHashMapTableError):
|
|
|
54
55
|
# ============================================================#
|
|
55
56
|
class UndefinedSheetIndex(CoreException):
|
|
56
57
|
|
|
57
|
-
def __init__(self, message: str =
|
|
58
|
+
def __init__(self, message: str = "SheetIndexNames não foi definido") -> None:
|
|
58
59
|
super().__init__(message)
|
|
59
60
|
|
|
60
61
|
|
|
61
62
|
class LoadWorkbookError(CoreException):
|
|
62
63
|
|
|
63
|
-
def __init__(self, message: str =
|
|
64
|
+
def __init__(self, message: str = "Erro ao tentar ler Workbook") -> None:
|
|
64
65
|
super().__init__(message)
|
|
65
66
|
|
|
67
|
+
|
|
66
68
|
# ============================================================#
|
|
67
69
|
# Erros relacionados a arquivos/bytes de imagem (.png, .jpg, ...)
|
|
68
70
|
# ============================================================#
|
|
69
71
|
class InvalidSourceImageError(CoreException):
|
|
70
72
|
|
|
71
|
-
def __init__(self, message: str =
|
|
73
|
+
def __init__(self, message: str = "Erro, use bytes de imagem") -> None:
|
|
72
74
|
super().__init__(message)
|
|
73
75
|
|
|
74
76
|
|
|
@@ -77,56 +79,60 @@ class InvalidSourceImageError(CoreException):
|
|
|
77
79
|
# ============================================================#
|
|
78
80
|
class NotImplementedModuleError(CoreException):
|
|
79
81
|
|
|
80
|
-
def __init__(self, message: str =
|
|
82
|
+
def __init__(self, message: str = "Erro, módulo não implementado") -> None:
|
|
81
83
|
super().__init__(message)
|
|
82
84
|
|
|
83
85
|
|
|
84
86
|
class NotImplementedModuleImageError(NotImplementedModuleError):
|
|
85
87
|
|
|
86
|
-
def __init__(self, message: str =
|
|
88
|
+
def __init__(self, message: str = "Erro, módulo IMAGEM não implementado") -> None:
|
|
87
89
|
super().__init__(message)
|
|
88
90
|
|
|
89
91
|
|
|
90
92
|
class NotImplementedModulePdfError(NotImplementedModuleError):
|
|
91
93
|
|
|
92
|
-
def __init__(self, message: str =
|
|
94
|
+
def __init__(self, message: str = "Erro, módulo PDF não implementado") -> None:
|
|
93
95
|
super().__init__(message)
|
|
94
96
|
|
|
95
97
|
|
|
96
98
|
class NotImplementedInvertColor(NotImplementedError):
|
|
97
99
|
|
|
98
|
-
def __init__(
|
|
100
|
+
def __init__(
|
|
101
|
+
self, message: str = "Adaptador InvertColor não implementado..."
|
|
102
|
+
) -> None:
|
|
99
103
|
super().__init__(message)
|
|
100
104
|
|
|
105
|
+
|
|
101
106
|
# ============================================================#
|
|
102
107
|
# Erros relacionados a tabelas
|
|
103
108
|
# ============================================================#
|
|
104
109
|
|
|
105
110
|
|
|
106
111
|
class ColumnNotFoudError(ValueError):
|
|
107
|
-
|
|
112
|
+
|
|
108
113
|
def __init__(self, *args: object) -> None:
|
|
109
114
|
super().__init__(*args)
|
|
110
115
|
|
|
111
|
-
|
|
116
|
+
|
|
117
|
+
class ColumnExistsError(ValueError):
|
|
112
118
|
|
|
113
119
|
def __init__(self, *args: object) -> None:
|
|
114
120
|
super().__init__(*args)
|
|
115
121
|
|
|
116
122
|
|
|
117
|
-
class
|
|
123
|
+
class ColumnNotIqualSizeError(ValueError):
|
|
118
124
|
|
|
119
125
|
def __init__(self, *args: object) -> None:
|
|
120
126
|
super().__init__(*args)
|
|
121
127
|
|
|
122
128
|
|
|
123
|
-
class
|
|
129
|
+
class EmptyRowError(Exception):
|
|
124
130
|
|
|
125
131
|
def __init__(self, *args: object) -> None:
|
|
126
132
|
super().__init__(*args)
|
|
127
133
|
|
|
128
134
|
|
|
129
|
-
class
|
|
135
|
+
class TableEmptyError(Exception):
|
|
130
136
|
|
|
131
137
|
def __init__(self, *args: object) -> None:
|
|
132
138
|
super().__init__(*args)
|
|
@@ -7,11 +7,12 @@ from abc import abstractmethod, ABC
|
|
|
7
7
|
from table_stream.hash_map import ArrayList, HashMapDict, HashMap, HashMapDataFrame
|
|
8
8
|
from table_stream.erros import (
|
|
9
9
|
ColumnNotFoudError,
|
|
10
|
+
ColumnExistsError,
|
|
10
11
|
RowNotExistError,
|
|
11
12
|
EmptyRowError,
|
|
12
13
|
ColumnNotFoundError,
|
|
13
14
|
HeadersSizeNotIqualError,
|
|
14
|
-
|
|
15
|
+
ColumnNotFoudError,
|
|
15
16
|
TableEmptyError,
|
|
16
17
|
ListTablesEmptyError,
|
|
17
18
|
)
|
|
@@ -34,15 +35,17 @@ class RowH[HEAD, T]:
|
|
|
34
35
|
self.index: int = index
|
|
35
36
|
|
|
36
37
|
def __repr__(self) -> str:
|
|
37
|
-
|
|
38
|
+
sep = "->"
|
|
39
|
+
default_text = f"<{__class__.__name__}()>"
|
|
40
|
+
|
|
38
41
|
if len(self.map) == 0:
|
|
39
|
-
return f"{
|
|
42
|
+
return f"{default_text} Size 0 {sep} []"
|
|
40
43
|
|
|
41
44
|
_values = ArrayList()
|
|
42
45
|
for k, v in self.map.items():
|
|
43
46
|
_values.add(f"{k} -> {v}")
|
|
44
47
|
|
|
45
|
-
return f"{
|
|
48
|
+
return f"{default_text} Size {len(self.map)} {sep} {_values}"
|
|
46
49
|
|
|
47
50
|
def __eq__(self, other: object) -> bool:
|
|
48
51
|
if not isinstance(other, RowH):
|
|
@@ -89,8 +92,8 @@ class ColumnV[HEAD, T]:
|
|
|
89
92
|
self.head: HEAD = head
|
|
90
93
|
|
|
91
94
|
def __repr__(self) -> str:
|
|
92
|
-
|
|
93
|
-
return f"{__class__.__name__}():
|
|
95
|
+
txt = f"Head {self.head}; Size {self.size()}; Type {self.get_type()} -> {self._elements}"
|
|
96
|
+
return f"{__class__.__name__}(): {txt}"
|
|
94
97
|
|
|
95
98
|
# ---------------------------------------------------#
|
|
96
99
|
# Leitura de Dados.
|
|
@@ -288,7 +291,7 @@ class Table[HEAD](ABC):
|
|
|
288
291
|
Adiciona uma nova coluna com texto padrão NULL_TEXT.
|
|
289
292
|
"""
|
|
290
293
|
|
|
291
|
-
if self.
|
|
294
|
+
if self.is_empty():
|
|
292
295
|
self.add(ColumnV(h))
|
|
293
296
|
return
|
|
294
297
|
|
|
@@ -296,24 +299,9 @@ class Table[HEAD](ABC):
|
|
|
296
299
|
values = [Table.NULL_STRING] * total
|
|
297
300
|
self.add(ColumnV(h, ArrayList(values)))
|
|
298
301
|
|
|
302
|
+
@abstractmethod
|
|
299
303
|
def merge(self, tb: Table) -> None:
|
|
300
|
-
|
|
301
|
-
raise TableEmptyError(f"Não é possível unir uma tabela vazia!")
|
|
302
|
-
|
|
303
|
-
if self.header().size() != tb.header().size():
|
|
304
|
-
raise HeadersSizeNotIqualError(
|
|
305
|
-
"Não é possível juntar tabelas com cabeçalhos diferentes!"
|
|
306
|
-
)
|
|
307
|
-
|
|
308
|
-
header = self.header()
|
|
309
|
-
# print(f"[UNINDO TABELAS] Atual: {self} Incrementando: {tb}")
|
|
310
|
-
|
|
311
|
-
for h in header:
|
|
312
|
-
if not tb.contains_header(h):
|
|
313
|
-
raise ColumnNotFoundError(f"Coluna inexistente ... {h}")
|
|
314
|
-
|
|
315
|
-
current_col: ColumnV = tb.get(h)
|
|
316
|
-
self.get(h).add_all(current_col._elements)
|
|
304
|
+
pass
|
|
317
305
|
|
|
318
306
|
@abstractmethod
|
|
319
307
|
def set(self, col: ColumnV[HEAD, ArrayList[T]]):
|
|
@@ -326,39 +314,17 @@ class Table[HEAD](ABC):
|
|
|
326
314
|
@abstractmethod
|
|
327
315
|
def add(self, col: ColumnV) -> None:
|
|
328
316
|
"""
|
|
329
|
-
Adiciona uma coluna na tabela
|
|
317
|
+
Adiciona uma coluna na tabela, se já existir uma coluna com o mesmo nome lança uma
|
|
318
|
+
exceção ColumnExistsError()
|
|
330
319
|
"""
|
|
331
320
|
pass
|
|
332
321
|
|
|
322
|
+
@abstractmethod
|
|
333
323
|
def add_row(self, row: RowH[HEAD, Any]):
|
|
334
324
|
"""
|
|
335
325
|
Adiciona uma linha a tabela se a linha não estiver vazia.
|
|
336
326
|
"""
|
|
337
|
-
|
|
338
|
-
return None
|
|
339
|
-
|
|
340
|
-
if self.empty():
|
|
341
|
-
for row_header in row.header():
|
|
342
|
-
self.add(ColumnV(row_header))
|
|
343
|
-
|
|
344
|
-
header: ArrayList[HEAD] = self.header()
|
|
345
|
-
|
|
346
|
-
if row.header().size() < header.size():
|
|
347
|
-
raise HeadersSizeNotIqualError(
|
|
348
|
-
"A linha que você está tentando adicionar tem cabeçalho menor que o da tabela!!!"
|
|
349
|
-
)
|
|
350
|
-
|
|
351
|
-
for h in header:
|
|
352
|
-
if not row.header().contains(h):
|
|
353
|
-
msg = f"Você está tentando adicionar uma linha que não possui o cabeçalho >> [{h}] <<"
|
|
354
|
-
|
|
355
|
-
raise HeaderNotFoundError(
|
|
356
|
-
f"{msg} \nCabeçalhos existentes na linha => {row.header()}\n\nCabeçalhos da tabela => {header}"
|
|
357
|
-
)
|
|
358
|
-
|
|
359
|
-
# self.tb_map[h].add(row.get(h))
|
|
360
|
-
self.get(h).add(row.get(h))
|
|
361
|
-
return None
|
|
327
|
+
pass
|
|
362
328
|
|
|
363
329
|
# ---------------------------------------------------#
|
|
364
330
|
# Leitura de dados - READ
|
|
@@ -372,7 +338,7 @@ class Table[HEAD](ABC):
|
|
|
372
338
|
pass
|
|
373
339
|
|
|
374
340
|
def get_row_at(self, idx: int) -> RowH[HEAD, Any]:
|
|
375
|
-
if self.
|
|
341
|
+
if self.is_empty():
|
|
376
342
|
raise TableEmptyError("A tabela está vazia")
|
|
377
343
|
|
|
378
344
|
total = self.get_first().size()
|
|
@@ -397,7 +363,7 @@ class Table[HEAD](ABC):
|
|
|
397
363
|
def rows(self) -> ArrayList[RowH[HEAD, Any]]:
|
|
398
364
|
final = ArrayList[RowH]()
|
|
399
365
|
|
|
400
|
-
if self.
|
|
366
|
+
if self.is_empty():
|
|
401
367
|
return final
|
|
402
368
|
|
|
403
369
|
total = self.get(self.header().get_first()).size()
|
|
@@ -425,7 +391,7 @@ class Table[HEAD](ABC):
|
|
|
425
391
|
header = self.header()
|
|
426
392
|
h: HEAD
|
|
427
393
|
|
|
428
|
-
if self.
|
|
394
|
+
if self.is_empty():
|
|
429
395
|
if header.empty():
|
|
430
396
|
print(f"{self}")
|
|
431
397
|
else:
|
|
@@ -457,14 +423,21 @@ class Table[HEAD](ABC):
|
|
|
457
423
|
def search(self, h: HEAD, value: Any) -> Table[HEAD]:
|
|
458
424
|
pass
|
|
459
425
|
|
|
426
|
+
@abstractmethod
|
|
427
|
+
def search_all(self, h: HEAD, values: list[T]) -> Table[HEAD] | None:
|
|
428
|
+
pass
|
|
429
|
+
|
|
460
430
|
# ---------------------------------------------------#
|
|
461
431
|
# Verificação/validação de dados
|
|
462
432
|
# ---------------------------------------------------#
|
|
463
433
|
def size(self) -> int:
|
|
464
|
-
if self.
|
|
434
|
+
if self.is_empty():
|
|
465
435
|
return 0
|
|
466
436
|
return self.get_first().size()
|
|
467
437
|
|
|
438
|
+
def size_header(self) -> int:
|
|
439
|
+
return self.header().size()
|
|
440
|
+
|
|
468
441
|
def contains_header(self, h: HEAD) -> bool:
|
|
469
442
|
return self.header().contains(h)
|
|
470
443
|
|
|
@@ -475,9 +448,19 @@ class Table[HEAD](ABC):
|
|
|
475
448
|
return self.get(h).contains(value)
|
|
476
449
|
|
|
477
450
|
@abstractmethod
|
|
478
|
-
def
|
|
451
|
+
def is_empty(self) -> bool:
|
|
452
|
+
"""
|
|
453
|
+
Retorna True se a tabela não tiver linhas, mesmo que o cabeçalho exista.
|
|
454
|
+
"""
|
|
479
455
|
pass
|
|
480
456
|
|
|
457
|
+
@abstractmethod
|
|
458
|
+
def is_void(self) -> bool:
|
|
459
|
+
"""
|
|
460
|
+
Retorna True se o cabeçalho estiver vazio. False se a tabela tiver pelo menos uma coluna
|
|
461
|
+
mesmo que esteja vazia.
|
|
462
|
+
"""
|
|
463
|
+
|
|
481
464
|
# ---------------------------------------------------#
|
|
482
465
|
# Exclusão de dados - DELETE
|
|
483
466
|
# ---------------------------------------------------#
|
|
@@ -540,13 +523,27 @@ class TableData[HEAD](Table):
|
|
|
540
523
|
self._table_data: pd.DataFrame = data
|
|
541
524
|
|
|
542
525
|
def __repr__(self) -> str:
|
|
543
|
-
|
|
526
|
+
msg = f"{__class__.__name__}(): Size {self.size()}; Columns {self.header().size()};"
|
|
527
|
+
|
|
528
|
+
if self.size() > 0:
|
|
529
|
+
row = self.get_row_at(0)
|
|
530
|
+
msg = f"{msg}\n{row}"
|
|
531
|
+
|
|
532
|
+
return f"{msg}"
|
|
544
533
|
|
|
545
534
|
# ---------------------------------------------------------- #
|
|
546
535
|
# Verificação/Validação de dados.
|
|
547
536
|
# ---------------------------------------------------------- #
|
|
548
|
-
def
|
|
549
|
-
|
|
537
|
+
def is_empty(self) -> bool:
|
|
538
|
+
if self.size_header() == 0:
|
|
539
|
+
return True
|
|
540
|
+
return len(self._table_data[self.header().get_first()]) == 0
|
|
541
|
+
|
|
542
|
+
def is_void(self) -> bool:
|
|
543
|
+
return self.size_header() == 0
|
|
544
|
+
|
|
545
|
+
def size_header(self) -> int:
|
|
546
|
+
return self.header().size()
|
|
550
547
|
|
|
551
548
|
def size(self) -> int:
|
|
552
549
|
return len(self._table_data)
|
|
@@ -559,14 +556,14 @@ class TableData[HEAD](Table):
|
|
|
559
556
|
return self._table_data
|
|
560
557
|
|
|
561
558
|
def get_row_at(self, idx: int) -> RowH[HEAD, Any]:
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
if idx < 0 or idx >= len(self._table_data):
|
|
566
|
-
raise RowNotExistError(f"A linha ... {idx} não existe na tabela {self}")
|
|
559
|
+
total = self.size()
|
|
560
|
+
if idx >= total:
|
|
561
|
+
raise RowNotExistError(f"A linha {idx} não existe ... Total {total}")
|
|
567
562
|
|
|
568
|
-
|
|
569
|
-
|
|
563
|
+
row = RowH(idx)
|
|
564
|
+
header = self.header()
|
|
565
|
+
header.for_each(lambda h: row.set(h, self.get(h).get(idx)))
|
|
566
|
+
return row
|
|
570
567
|
|
|
571
568
|
def get_data_columns(self) -> pd.Index:
|
|
572
569
|
return TableData._object_index(self._table_data.columns)
|
|
@@ -602,8 +599,10 @@ class TableData[HEAD](Table):
|
|
|
602
599
|
if row.is_empty():
|
|
603
600
|
return None
|
|
604
601
|
|
|
605
|
-
|
|
602
|
+
# Tabela completamente vazia, criar o cabeçalho com base na linha recebida.
|
|
603
|
+
if self.is_void():
|
|
606
604
|
self._table_data = pd.DataFrame(columns=row.header())
|
|
605
|
+
row.index = 0
|
|
607
606
|
|
|
608
607
|
header: ArrayList[HEAD] = self.header()
|
|
609
608
|
|
|
@@ -616,7 +615,7 @@ class TableData[HEAD](Table):
|
|
|
616
615
|
if not row.header().contains(h):
|
|
617
616
|
msg = f"Você está tentando adicionar uma linha que não possui o cabeçalho >> [{h}] <<"
|
|
618
617
|
|
|
619
|
-
raise
|
|
618
|
+
raise ColumnNotFoudError(
|
|
620
619
|
f"{msg} \nCabeçalhos existentes na linha => {row.header()}\nCabeçalhos da tabela => {header}"
|
|
621
620
|
)
|
|
622
621
|
|
|
@@ -632,19 +631,28 @@ class TableData[HEAD](Table):
|
|
|
632
631
|
return None
|
|
633
632
|
|
|
634
633
|
def merge(self, tb: Table) -> None:
|
|
635
|
-
if tb.
|
|
634
|
+
if tb.is_empty():
|
|
636
635
|
raise TableEmptyError("Não é possível unir uma tabela vazia!")
|
|
637
636
|
|
|
638
|
-
|
|
639
|
-
|
|
637
|
+
header = self.header()
|
|
638
|
+
size_header_table = self.size_header()
|
|
639
|
+
size_header_other = header.size()
|
|
640
|
+
|
|
641
|
+
if size_header_table == 0:
|
|
642
|
+
cols = tb.header()
|
|
643
|
+
cols.for_each(lambda c: self.add(ColumnV(c)))
|
|
644
|
+
|
|
645
|
+
if size_header_table != size_header_other:
|
|
646
|
+
msg = f"Cabeçalho da tabela -> {self.header().size()} | Cabeçalho externo -> {tb.header().size()}"
|
|
640
647
|
raise HeadersSizeNotIqualError(
|
|
641
648
|
f"Não é possível juntar tabelas com cabeçalhos diferentes.\n{msg}"
|
|
642
649
|
)
|
|
643
650
|
|
|
644
|
-
header = self.header()
|
|
645
651
|
for h in header:
|
|
646
652
|
if not tb.contains_header(h):
|
|
647
|
-
raise ColumnNotFoundError(
|
|
653
|
+
raise ColumnNotFoundError(
|
|
654
|
+
f"Coluna inexistente ... {h} ... Colunas disponíveis ... {self.header()}"
|
|
655
|
+
)
|
|
648
656
|
|
|
649
657
|
other = tb.to_dataframe()[list(header)]
|
|
650
658
|
|
|
@@ -654,32 +662,44 @@ class TableData[HEAD](Table):
|
|
|
654
662
|
self._table_data = pd.concat([self._table_data, other], ignore_index=True)
|
|
655
663
|
|
|
656
664
|
def add(self, col: ColumnV) -> None:
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
self.
|
|
665
|
+
if self.header().contains(col.head):
|
|
666
|
+
raise ColumnExistsError(f"Já existe uma coluna com o nome: {col.head}")
|
|
667
|
+
|
|
668
|
+
if self.is_void():
|
|
669
|
+
self._table_data = pd.DataFrame({col.head: col.get_elements()})
|
|
670
|
+
return
|
|
671
|
+
|
|
672
|
+
current_size = col.size()
|
|
673
|
+
cols_size = self.get_first().size()
|
|
674
|
+
|
|
675
|
+
if cols_size != current_size:
|
|
676
|
+
raise HeadersSizeNotIqualError(
|
|
677
|
+
f"Não é possível adicionar uma coluna com tamanho {current_size} ... Tamanho da tabela ... {cols_size}!"
|
|
678
|
+
)
|
|
679
|
+
|
|
680
|
+
self._table_data[col.head] = pd.Series(col.get_elements())
|
|
661
681
|
|
|
662
682
|
def set(self, col: ColumnV[HEAD, ArrayList[T]]) -> None:
|
|
683
|
+
|
|
663
684
|
values: ArrayList = col.get_elements()
|
|
664
685
|
|
|
665
|
-
if self.
|
|
686
|
+
if self.header().empty():
|
|
666
687
|
# Tabela sem colunas: cria o DataFrame a partir da primeira coluna.
|
|
667
688
|
self._table_data = pd.DataFrame({col.head: values})
|
|
689
|
+
self._table_data.columns = self.get_data_columns()
|
|
668
690
|
return
|
|
669
691
|
|
|
670
692
|
total = self.size()
|
|
671
693
|
total_values = values.size()
|
|
672
694
|
|
|
673
695
|
if total == 0 and total_values > 0:
|
|
674
|
-
# Tabela só com cabeçalho (0 linhas): estende o índice.
|
|
675
696
|
self._table_data = self._table_data.reindex(range(total_values))
|
|
676
697
|
total = total_values
|
|
677
698
|
|
|
678
699
|
if total_values != total:
|
|
679
|
-
|
|
680
700
|
raise HeadersSizeNotIqualError(
|
|
681
701
|
f"{__class__.__name__}() Não é possível adicionar uma coluna com tamanho "
|
|
682
|
-
f"diferente da tabela. Tabela {total} | Coluna {
|
|
702
|
+
f"diferente da tabela. Tabela {total} | Coluna {total_values} {col.head}"
|
|
683
703
|
)
|
|
684
704
|
self._table_data[col.head] = values
|
|
685
705
|
self._table_data.columns = self.get_data_columns()
|
|
@@ -714,13 +734,27 @@ class TableData[HEAD](Table):
|
|
|
714
734
|
Se nada for encontrado, retorna uma tabela com o mesmo cabeçalho e 0 linhas.
|
|
715
735
|
"""
|
|
716
736
|
if not self.contains_header(h):
|
|
717
|
-
raise ColumnNotFoundError(
|
|
718
|
-
f"Coluna não encontrada: {h}\nColunas disponiveis -> {self.header()}"
|
|
719
|
-
)
|
|
737
|
+
raise ColumnNotFoundError(f"Coluna não encontrada: {h}")
|
|
720
738
|
|
|
721
739
|
df = self._table_data[self._table_data[h] == value].reset_index(drop=True)
|
|
722
740
|
return TableData(df)
|
|
723
741
|
|
|
742
|
+
def search_all(self, h: Any, values: list[T]) -> Table | None:
|
|
743
|
+
if len(values) == 0:
|
|
744
|
+
return None
|
|
745
|
+
|
|
746
|
+
content = ArrayList[Table]()
|
|
747
|
+
|
|
748
|
+
for v in values:
|
|
749
|
+
found = self.search(h, v)
|
|
750
|
+
|
|
751
|
+
if not found.is_empty():
|
|
752
|
+
content.add(found)
|
|
753
|
+
|
|
754
|
+
if content.empty():
|
|
755
|
+
return None
|
|
756
|
+
return concat_tables(content)
|
|
757
|
+
|
|
724
758
|
# ---------------------------------------------------------- #
|
|
725
759
|
# Exclusão de dados - DELETE
|
|
726
760
|
# ---------------------------------------------------------- #
|
|
@@ -728,7 +762,7 @@ class TableData[HEAD](Table):
|
|
|
728
762
|
self._table_data = pd.DataFrame()
|
|
729
763
|
|
|
730
764
|
def drop_duplicates(self) -> TableData:
|
|
731
|
-
if self.
|
|
765
|
+
if self.is_empty():
|
|
732
766
|
raise TableEmptyError()
|
|
733
767
|
|
|
734
768
|
df = self._table_data.drop_duplicates().reset_index(drop=True)
|
|
@@ -738,7 +772,7 @@ class TableData[HEAD](Table):
|
|
|
738
772
|
"""
|
|
739
773
|
Remove as linhas em que a coluna `header` seja NaN, "", "nan" ou "NaN".
|
|
740
774
|
"""
|
|
741
|
-
if self.
|
|
775
|
+
if self.is_empty():
|
|
742
776
|
raise TableEmptyError(f"A tabela está vazia e não possui a coluna {header}")
|
|
743
777
|
|
|
744
778
|
if not self.contains_header(header):
|
|
@@ -778,9 +812,12 @@ class TableData[HEAD](Table):
|
|
|
778
812
|
return cls(hash_map.to_data_frame())
|
|
779
813
|
|
|
780
814
|
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
815
|
+
TB_TYPE = TypeVar("TB_TYPE", bound="Table")
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
def concat_tables[TB_TYPE](
|
|
819
|
+
values: list[Table], *, rt_type: type[Table | TB_TYPE] = TableData
|
|
820
|
+
) -> TableData | Table | TB_TYPE:
|
|
784
821
|
"""
|
|
785
822
|
Concatenar uma lista de tabelas, se receber uma lista vazia gera a exceção ListTablesEmptyError().
|
|
786
823
|
"""
|
|
@@ -788,29 +825,11 @@ def concat_tables(
|
|
|
788
825
|
if len(values) == 0:
|
|
789
826
|
raise ListTablesEmptyError("Não é possível concatenar uma lista vazia")
|
|
790
827
|
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
header = first.header()
|
|
795
|
-
|
|
796
|
-
for h in header:
|
|
797
|
-
final.add(ColumnV(h))
|
|
828
|
+
header = values[0].header()
|
|
829
|
+
final: Table = rt_type()
|
|
830
|
+
header.for_each(lambda h: final.add(ColumnV(h)))
|
|
798
831
|
|
|
799
832
|
current_table: Table
|
|
800
|
-
|
|
801
833
|
for current_table in values:
|
|
802
|
-
|
|
803
|
-
raise TableEmptyError(f"Não é possível concatenar uma tabela vazia!")
|
|
804
|
-
|
|
805
|
-
if current_table.header().size() != header.size():
|
|
806
|
-
raise HeadersSizeNotIqualError(
|
|
807
|
-
"As tabelas precisam ter colunas de tamanhos iguais para concatenar!"
|
|
808
|
-
)
|
|
809
|
-
|
|
810
|
-
for h in header:
|
|
811
|
-
if not current_table.header().contains(h):
|
|
812
|
-
raise ColumnNotFoundError(f"Coluna não encontrada: {h}")
|
|
813
|
-
|
|
814
|
-
final.get(h).add_all(current_table.get(h).get_elements())
|
|
815
|
-
|
|
834
|
+
final.merge(current_table)
|
|
816
835
|
return final
|
|
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
|