table-stream 0.1.9__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.1.9 → table_stream-0.2.2}/PKG-INFO +1 -1
- {table_stream-0.1.9 → table_stream-0.2.2}/pyproject.toml +1 -1
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream/__init__.py +4 -3
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream/erros.py +24 -18
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream/sysfiles.py +0 -1
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream/table.py +228 -198
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream.egg-info/PKG-INFO +1 -1
- {table_stream-0.1.9 → table_stream-0.2.2}/README.md +0 -0
- {table_stream-0.1.9 → table_stream-0.2.2}/setup.cfg +0 -0
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream/hash_map.py +0 -0
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream/notifier.py +0 -0
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream/pattner/__init__.py +0 -0
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream/pattner/adapter.py +0 -0
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream/sheet/__init__.py +0 -0
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream/sheet/check_mod.py +0 -0
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream/sheet/load.py +0 -0
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream/sheet/options.py +0 -0
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream/sheet/parse.py +0 -0
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream/sheet/save.py +0 -0
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream/state.py +0 -0
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream/thread.py +0 -0
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream/workbook.py +0 -0
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream.egg-info/SOURCES.txt +0 -0
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream.egg-info/dependency_links.txt +0 -0
- {table_stream-0.1.9 → table_stream-0.2.2}/table_stream.egg-info/requires.txt +0 -0
- {table_stream-0.1.9 → 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.
|
|
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)
|
|
@@ -6,9 +6,15 @@ from __future__ import annotations
|
|
|
6
6
|
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
|
-
ColumnNotFoudError,
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
ColumnNotFoudError,
|
|
10
|
+
ColumnExistsError,
|
|
11
|
+
RowNotExistError,
|
|
12
|
+
EmptyRowError,
|
|
13
|
+
ColumnNotFoundError,
|
|
14
|
+
HeadersSizeNotIqualError,
|
|
15
|
+
ColumnNotFoudError,
|
|
16
|
+
TableEmptyError,
|
|
17
|
+
ListTablesEmptyError,
|
|
12
18
|
)
|
|
13
19
|
from typing import Any, TypeVar, Callable
|
|
14
20
|
import pandas as pd
|
|
@@ -20,25 +26,27 @@ TP = TypeVar("TP")
|
|
|
20
26
|
|
|
21
27
|
|
|
22
28
|
class RowH[HEAD, T]:
|
|
23
|
-
|
|
29
|
+
|
|
24
30
|
def __init__(self, index: int, map: dict[HEAD, T] | None = None) -> None:
|
|
25
|
-
if map is None:
|
|
31
|
+
if map is None:
|
|
26
32
|
map = dict()
|
|
27
|
-
|
|
33
|
+
|
|
28
34
|
self.map: dict[HEAD, T] = map
|
|
29
35
|
self.index: int = index
|
|
30
36
|
|
|
31
37
|
def __repr__(self) -> str:
|
|
32
|
-
|
|
38
|
+
sep = "->"
|
|
39
|
+
default_text = f"<{__class__.__name__}()>"
|
|
40
|
+
|
|
33
41
|
if len(self.map) == 0:
|
|
34
|
-
return f"{
|
|
35
|
-
|
|
42
|
+
return f"{default_text} Size 0 {sep} []"
|
|
43
|
+
|
|
36
44
|
_values = ArrayList()
|
|
37
45
|
for k, v in self.map.items():
|
|
38
46
|
_values.add(f"{k} -> {v}")
|
|
39
|
-
|
|
40
|
-
return f"{
|
|
41
|
-
|
|
47
|
+
|
|
48
|
+
return f"{default_text} Size {len(self.map)} {sep} {_values}"
|
|
49
|
+
|
|
42
50
|
def __eq__(self, other: object) -> bool:
|
|
43
51
|
if not isinstance(other, RowH):
|
|
44
52
|
raise NotImplementedError()
|
|
@@ -46,30 +54,30 @@ class RowH[HEAD, T]:
|
|
|
46
54
|
|
|
47
55
|
def __hash__(self) -> int:
|
|
48
56
|
return hash(tuple(self.map.items()))
|
|
49
|
-
|
|
57
|
+
|
|
50
58
|
def hash(self) -> int:
|
|
51
59
|
return self.__hash__()
|
|
52
|
-
|
|
60
|
+
|
|
53
61
|
def is_empty(self) -> bool:
|
|
54
62
|
return self.header().empty()
|
|
55
|
-
|
|
63
|
+
|
|
56
64
|
def get_first(self) -> T:
|
|
57
65
|
if self.is_empty():
|
|
58
66
|
raise EmptyRowError(f"Linha vazia, adicione elementos...")
|
|
59
67
|
return self.get(self.header().get_first())
|
|
60
|
-
|
|
68
|
+
|
|
61
69
|
def get_row_index(self) -> int:
|
|
62
70
|
return self.index
|
|
63
|
-
|
|
64
|
-
def get(self, head: HEAD) ->
|
|
71
|
+
|
|
72
|
+
def get(self, head: HEAD) -> T:
|
|
65
73
|
return self.map[head]
|
|
66
|
-
|
|
74
|
+
|
|
67
75
|
def set(self, head: HEAD, v: T) -> None:
|
|
68
76
|
self.map[head] = v
|
|
69
|
-
|
|
77
|
+
|
|
70
78
|
def header(self) -> ArrayList[HEAD]:
|
|
71
79
|
return ArrayList(list(self.map.keys()))
|
|
72
|
-
|
|
80
|
+
|
|
73
81
|
def values(self) -> ArrayList[T]:
|
|
74
82
|
return ArrayList(list(self.map.values()))
|
|
75
83
|
|
|
@@ -84,15 +92,15 @@ class ColumnV[HEAD, T]:
|
|
|
84
92
|
self.head: HEAD = head
|
|
85
93
|
|
|
86
94
|
def __repr__(self) -> str:
|
|
87
|
-
|
|
88
|
-
return f"{__class__.__name__}():
|
|
89
|
-
|
|
90
|
-
|
|
95
|
+
txt = f"Head {self.head}; Size {self.size()}; Type {self.get_type()} -> {self._elements}"
|
|
96
|
+
return f"{__class__.__name__}(): {txt}"
|
|
97
|
+
|
|
98
|
+
# ---------------------------------------------------#
|
|
91
99
|
# Leitura de Dados.
|
|
92
|
-
|
|
100
|
+
# ---------------------------------------------------#
|
|
93
101
|
def get_type(self) -> type[T] | None:
|
|
94
102
|
return None if self.is_empty() else type(self.get_first())
|
|
95
|
-
|
|
103
|
+
|
|
96
104
|
def get_elements(self) -> ArrayList[T]:
|
|
97
105
|
return self._elements
|
|
98
106
|
|
|
@@ -101,60 +109,62 @@ class ColumnV[HEAD, T]:
|
|
|
101
109
|
Retorna um elemento da coluna apartir de seu índice, se o
|
|
102
110
|
índice do elemento não existir, lança a exceção RowNotExistError()
|
|
103
111
|
"""
|
|
104
|
-
|
|
112
|
+
|
|
105
113
|
if idx >= self.size():
|
|
106
|
-
raise RowNotExistError(
|
|
114
|
+
raise RowNotExistError(
|
|
115
|
+
f"{__class__.__name__} Linha não encontrada ... {idx}"
|
|
116
|
+
)
|
|
107
117
|
return self._elements.get_element_at(idx)
|
|
108
|
-
|
|
118
|
+
|
|
109
119
|
def get_first(self) -> T:
|
|
110
120
|
total = self.size()
|
|
111
|
-
|
|
121
|
+
|
|
112
122
|
if total == 0:
|
|
113
123
|
raise ValueError(f"A coluna {self.head} está vazia")
|
|
114
124
|
return self._elements[0]
|
|
115
|
-
|
|
125
|
+
|
|
116
126
|
def add(self, item: T) -> None:
|
|
117
|
-
|
|
118
|
-
|
|
127
|
+
self._elements.append(item)
|
|
128
|
+
|
|
119
129
|
def add_all(self, items: ArrayList[T]) -> None:
|
|
120
130
|
items.for_each(self.add)
|
|
121
|
-
|
|
122
|
-
|
|
131
|
+
|
|
132
|
+
# ---------------------------------------------------#
|
|
123
133
|
# Inserção/Edição de dados.
|
|
124
|
-
|
|
134
|
+
# ---------------------------------------------------#
|
|
125
135
|
def set(self, idx: int, value: T) -> None:
|
|
126
136
|
self._elements[idx] = value
|
|
127
|
-
|
|
137
|
+
|
|
128
138
|
def set_elements(self, e: ArrayList[T]) -> None:
|
|
129
|
-
|
|
139
|
+
self._elements = e
|
|
130
140
|
|
|
131
141
|
def astype[TP](self, new_type: type[TP]) -> ArrayList[TP]:
|
|
132
|
-
new = ArrayList[TP]()
|
|
142
|
+
new = ArrayList[TP]()
|
|
133
143
|
for e in self._elements:
|
|
134
144
|
new.append(new_type(e))
|
|
135
145
|
return new
|
|
136
|
-
|
|
146
|
+
|
|
137
147
|
def replace_value(self, old: T, new: T) -> None:
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
148
|
+
"""
|
|
149
|
+
Substitui old por new em todas as ocorrências.
|
|
150
|
+
"""
|
|
151
|
+
list_index = self.find_all(old)
|
|
152
|
+
|
|
153
|
+
if list_index.empty():
|
|
154
|
+
return
|
|
155
|
+
|
|
156
|
+
for num in list_index:
|
|
157
|
+
self._elements.replace(num, new)
|
|
158
|
+
|
|
149
159
|
def replace_at(self, idx: int, new: T) -> None:
|
|
150
160
|
self._elements.replace(idx, new)
|
|
151
|
-
|
|
161
|
+
|
|
152
162
|
def merge(self, col: ColumnV) -> None:
|
|
153
163
|
self.add_all(col.get_elements())
|
|
154
164
|
|
|
155
|
-
|
|
165
|
+
# ---------------------------------------------------#
|
|
156
166
|
# Verificação/Validação de dados.
|
|
157
|
-
|
|
167
|
+
# ---------------------------------------------------#
|
|
158
168
|
def is_empty(self) -> bool:
|
|
159
169
|
return self._elements.empty()
|
|
160
170
|
|
|
@@ -164,37 +174,39 @@ class ColumnV[HEAD, T]:
|
|
|
164
174
|
def contains(self, element: T) -> bool:
|
|
165
175
|
return self._elements.contains(element)
|
|
166
176
|
|
|
167
|
-
|
|
177
|
+
# ---------------------------------------------------#
|
|
168
178
|
# Exclusão de dados.
|
|
169
|
-
|
|
179
|
+
# ---------------------------------------------------#
|
|
170
180
|
def remove(self, v: T) -> None:
|
|
171
181
|
self._elements.remove(v)
|
|
172
|
-
|
|
173
|
-
def remove_all(
|
|
174
|
-
|
|
182
|
+
|
|
183
|
+
def remove_all(
|
|
184
|
+
self, values: ArrayList[T], *, inplace: bool = False
|
|
185
|
+
) -> ColumnV[HEAD, T]:
|
|
186
|
+
|
|
175
187
|
new_elements = ArrayList[T]()
|
|
176
|
-
|
|
188
|
+
|
|
177
189
|
for e in self._elements:
|
|
178
190
|
if not values.contains(e):
|
|
179
191
|
new_elements.add(e)
|
|
180
|
-
|
|
192
|
+
|
|
181
193
|
if inplace:
|
|
182
194
|
self.set_elements(new_elements)
|
|
183
|
-
|
|
195
|
+
|
|
184
196
|
return ColumnV(self.head, new_elements)
|
|
185
|
-
|
|
186
|
-
|
|
197
|
+
|
|
198
|
+
# ---------------------------------------------------#
|
|
187
199
|
# Comandos
|
|
188
|
-
|
|
200
|
+
# ---------------------------------------------------#
|
|
189
201
|
def for_each(self, fn: Callable[[T], None]) -> None:
|
|
190
202
|
self._elements.for_each(fn)
|
|
191
203
|
|
|
192
|
-
def apply_command(self, fn: Callable[[T], None]) -> ColumnV[HEAD, Any]:
|
|
204
|
+
def apply_command(self, fn: Callable[[T], None]) -> ColumnV[HEAD, Any]:
|
|
193
205
|
return ColumnV(self.head, self._elements.apply_command(fn))
|
|
194
|
-
|
|
195
|
-
|
|
206
|
+
|
|
207
|
+
# ---------------------------------------------------#
|
|
196
208
|
# Pesquisar/Buscar informações.
|
|
197
|
-
|
|
209
|
+
# ---------------------------------------------------#
|
|
198
210
|
def select(self, list_index: ArrayList[int]) -> ColumnV[HEAD, T]:
|
|
199
211
|
new_col = ColumnV[HEAD, T](self.head)
|
|
200
212
|
list_index.for_each(lambda num: new_col.add(self.get(num)))
|
|
@@ -220,7 +232,7 @@ class ColumnV[HEAD, T]:
|
|
|
220
232
|
return final
|
|
221
233
|
|
|
222
234
|
def filter_value(self, value: T, iqual: bool = False) -> ColumnV[HEAD, T]:
|
|
223
|
-
list_index: ArrayList[int]
|
|
235
|
+
list_index: ArrayList[int]
|
|
224
236
|
|
|
225
237
|
if iqual:
|
|
226
238
|
list_index = self.find_all(value)
|
|
@@ -239,27 +251,25 @@ class ColumnV[HEAD, T]:
|
|
|
239
251
|
for idx in list_index:
|
|
240
252
|
final_elements.append(self._elements[idx])
|
|
241
253
|
return ColumnV(self.head, final_elements)
|
|
242
|
-
|
|
254
|
+
|
|
243
255
|
def filter_all(self, values: ArrayList[T]) -> ColumnV[HEAD, T]:
|
|
244
256
|
final = ColumnV[HEAD, T](self.head)
|
|
245
|
-
|
|
246
|
-
values.for_each(
|
|
247
|
-
lambda item: final.merge(self.filter_value(item))
|
|
248
|
-
)
|
|
257
|
+
|
|
258
|
+
values.for_each(lambda item: final.merge(self.filter_value(item)))
|
|
249
259
|
return final
|
|
250
260
|
|
|
251
261
|
def drop_duplicates(self) -> ColumnV[HEAD, T]:
|
|
252
262
|
final_list = ArrayList()
|
|
253
|
-
|
|
263
|
+
|
|
254
264
|
for e in self._elements:
|
|
255
265
|
if not final_list.contains(e):
|
|
256
266
|
final_list.append(e)
|
|
257
267
|
return ColumnV(self.head, final_list)
|
|
258
|
-
|
|
268
|
+
|
|
259
269
|
@classmethod
|
|
260
270
|
def create_from_list(cls, h: HEAD, values: list[T]) -> ColumnV:
|
|
261
271
|
return cls(h, ArrayList(values))
|
|
262
|
-
|
|
272
|
+
|
|
263
273
|
@classmethod
|
|
264
274
|
def create_from_series(cls, h: HEAD, s: pd.Series) -> ColumnV:
|
|
265
275
|
return cls(h, ArrayList(s.values.tolist()))
|
|
@@ -281,7 +291,7 @@ class Table[HEAD](ABC):
|
|
|
281
291
|
Adiciona uma nova coluna com texto padrão NULL_TEXT.
|
|
282
292
|
"""
|
|
283
293
|
|
|
284
|
-
if self.
|
|
294
|
+
if self.is_empty():
|
|
285
295
|
self.add(ColumnV(h))
|
|
286
296
|
return
|
|
287
297
|
|
|
@@ -289,29 +299,14 @@ class Table[HEAD](ABC):
|
|
|
289
299
|
values = [Table.NULL_STRING] * total
|
|
290
300
|
self.add(ColumnV(h, ArrayList(values)))
|
|
291
301
|
|
|
302
|
+
@abstractmethod
|
|
292
303
|
def merge(self, tb: Table) -> None:
|
|
293
|
-
|
|
294
|
-
raise TableEmptyError(f"Não é possível unir uma tabela vazia!")
|
|
295
|
-
|
|
296
|
-
if self.header().size() != tb.header().size():
|
|
297
|
-
raise HeadersSizeNotIqualError(
|
|
298
|
-
"Não é possível juntar tabelas com cabeçalhos diferentes!"
|
|
299
|
-
)
|
|
300
|
-
|
|
301
|
-
header = self.header()
|
|
302
|
-
# print(f"[UNINDO TABELAS] Atual: {self} Incrementando: {tb}")
|
|
303
|
-
|
|
304
|
-
for h in header:
|
|
305
|
-
if not tb.contains_header(h):
|
|
306
|
-
raise ColumnNotFoundError(f"Coluna inexistente ... {h}")
|
|
307
|
-
|
|
308
|
-
current_col: ColumnV = tb.get(h)
|
|
309
|
-
self.get(h).add_all(current_col._elements)
|
|
304
|
+
pass
|
|
310
305
|
|
|
311
306
|
@abstractmethod
|
|
312
307
|
def set(self, col: ColumnV[HEAD, ArrayList[T]]):
|
|
313
308
|
pass
|
|
314
|
-
|
|
309
|
+
|
|
315
310
|
@abstractmethod
|
|
316
311
|
def set_data(self, df: pd.DataFrame) -> None:
|
|
317
312
|
pass
|
|
@@ -319,53 +314,31 @@ class Table[HEAD](ABC):
|
|
|
319
314
|
@abstractmethod
|
|
320
315
|
def add(self, col: ColumnV) -> None:
|
|
321
316
|
"""
|
|
322
|
-
|
|
317
|
+
Adiciona uma coluna na tabela, se já existir uma coluna com o mesmo nome lança uma
|
|
318
|
+
exceção ColumnExistsError()
|
|
323
319
|
"""
|
|
324
320
|
pass
|
|
325
321
|
|
|
322
|
+
@abstractmethod
|
|
326
323
|
def add_row(self, row: RowH[HEAD, Any]):
|
|
327
324
|
"""
|
|
328
325
|
Adiciona uma linha a tabela se a linha não estiver vazia.
|
|
329
326
|
"""
|
|
330
|
-
|
|
331
|
-
return None
|
|
332
|
-
|
|
333
|
-
if self.empty():
|
|
334
|
-
for row_header in row.header():
|
|
335
|
-
self.add(ColumnV(row_header))
|
|
336
|
-
|
|
337
|
-
header: ArrayList[HEAD] = self.header()
|
|
338
|
-
|
|
339
|
-
if row.header().size() < header.size():
|
|
340
|
-
raise HeadersSizeNotIqualError(
|
|
341
|
-
"A linha que você está tentando adicionar tem cabeçalho menor que o da tabela!!!"
|
|
342
|
-
)
|
|
343
|
-
|
|
344
|
-
for h in header:
|
|
345
|
-
if not row.header().contains(h):
|
|
346
|
-
msg = f"Você está tentando adicionar uma linha que não possui o cabeçalho >> [{h}] <<"
|
|
347
|
-
|
|
348
|
-
raise HeaderNotFoundError(
|
|
349
|
-
f"{msg} \nCabeçalhos existentes na linha => {row.header()}\n\nCabeçalhos da tabela => {header}"
|
|
350
|
-
)
|
|
351
|
-
|
|
352
|
-
# self.tb_map[h].add(row.get(h))
|
|
353
|
-
self.get(h).add(row.get(h))
|
|
354
|
-
return None
|
|
327
|
+
pass
|
|
355
328
|
|
|
356
|
-
|
|
329
|
+
# ---------------------------------------------------#
|
|
357
330
|
# Leitura de dados - READ
|
|
358
|
-
|
|
331
|
+
# ---------------------------------------------------#
|
|
359
332
|
@abstractmethod
|
|
360
333
|
def get_data(self) -> pd.DataFrame:
|
|
361
334
|
pass
|
|
362
|
-
|
|
335
|
+
|
|
363
336
|
@abstractmethod
|
|
364
337
|
def get(self, h: HEAD) -> ColumnV[HEAD, Any]:
|
|
365
338
|
pass
|
|
366
339
|
|
|
367
340
|
def get_row_at(self, idx: int) -> RowH[HEAD, Any]:
|
|
368
|
-
if self.
|
|
341
|
+
if self.is_empty():
|
|
369
342
|
raise TableEmptyError("A tabela está vazia")
|
|
370
343
|
|
|
371
344
|
total = self.get_first().size()
|
|
@@ -390,7 +363,7 @@ class Table[HEAD](ABC):
|
|
|
390
363
|
def rows(self) -> ArrayList[RowH[HEAD, Any]]:
|
|
391
364
|
final = ArrayList[RowH]()
|
|
392
365
|
|
|
393
|
-
if self.
|
|
366
|
+
if self.is_empty():
|
|
394
367
|
return final
|
|
395
368
|
|
|
396
369
|
total = self.get(self.header().get_first()).size()
|
|
@@ -405,7 +378,7 @@ class Table[HEAD](ABC):
|
|
|
405
378
|
|
|
406
379
|
def get_last(self) -> ColumnV:
|
|
407
380
|
return self.get(self.header().get_last())
|
|
408
|
-
|
|
381
|
+
|
|
409
382
|
@abstractmethod
|
|
410
383
|
def select_columns(self, header: list[HEAD]) -> Table:
|
|
411
384
|
pass
|
|
@@ -418,7 +391,7 @@ class Table[HEAD](ABC):
|
|
|
418
391
|
header = self.header()
|
|
419
392
|
h: HEAD
|
|
420
393
|
|
|
421
|
-
if self.
|
|
394
|
+
if self.is_empty():
|
|
422
395
|
if header.empty():
|
|
423
396
|
print(f"{self}")
|
|
424
397
|
else:
|
|
@@ -450,14 +423,21 @@ class Table[HEAD](ABC):
|
|
|
450
423
|
def search(self, h: HEAD, value: Any) -> Table[HEAD]:
|
|
451
424
|
pass
|
|
452
425
|
|
|
453
|
-
|
|
426
|
+
@abstractmethod
|
|
427
|
+
def search_all(self, h: HEAD, values: list[T]) -> Table[HEAD] | None:
|
|
428
|
+
pass
|
|
429
|
+
|
|
430
|
+
# ---------------------------------------------------#
|
|
454
431
|
# Verificação/validação de dados
|
|
455
|
-
|
|
432
|
+
# ---------------------------------------------------#
|
|
456
433
|
def size(self) -> int:
|
|
457
|
-
if self.
|
|
434
|
+
if self.is_empty():
|
|
458
435
|
return 0
|
|
459
436
|
return self.get_first().size()
|
|
460
437
|
|
|
438
|
+
def size_header(self) -> int:
|
|
439
|
+
return self.header().size()
|
|
440
|
+
|
|
461
441
|
def contains_header(self, h: HEAD) -> bool:
|
|
462
442
|
return self.header().contains(h)
|
|
463
443
|
|
|
@@ -468,23 +448,33 @@ class Table[HEAD](ABC):
|
|
|
468
448
|
return self.get(h).contains(value)
|
|
469
449
|
|
|
470
450
|
@abstractmethod
|
|
471
|
-
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
|
+
"""
|
|
472
455
|
pass
|
|
473
456
|
|
|
474
|
-
|
|
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
|
+
|
|
464
|
+
# ---------------------------------------------------#
|
|
475
465
|
# Exclusão de dados - DELETE
|
|
476
|
-
|
|
466
|
+
# ---------------------------------------------------#
|
|
477
467
|
@abstractmethod
|
|
478
468
|
def clear(self) -> None:
|
|
479
469
|
pass
|
|
480
|
-
|
|
470
|
+
|
|
481
471
|
@abstractmethod
|
|
482
472
|
def remove_null(self, header: HEAD) -> Table:
|
|
483
473
|
pass
|
|
484
474
|
|
|
485
|
-
|
|
475
|
+
# ---------------------------------------------------#
|
|
486
476
|
# Conversão de dados
|
|
487
|
-
|
|
477
|
+
# ---------------------------------------------------#
|
|
488
478
|
def to_string(self, h: HEAD) -> str:
|
|
489
479
|
return " ".join(self.get(h).astype(str))
|
|
490
480
|
|
|
@@ -533,13 +523,27 @@ class TableData[HEAD](Table):
|
|
|
533
523
|
self._table_data: pd.DataFrame = data
|
|
534
524
|
|
|
535
525
|
def __repr__(self) -> str:
|
|
536
|
-
|
|
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}"
|
|
537
533
|
|
|
538
534
|
# ---------------------------------------------------------- #
|
|
539
535
|
# Verificação/Validação de dados.
|
|
540
536
|
# ---------------------------------------------------------- #
|
|
541
|
-
def
|
|
542
|
-
|
|
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()
|
|
543
547
|
|
|
544
548
|
def size(self) -> int:
|
|
545
549
|
return len(self._table_data)
|
|
@@ -547,25 +551,25 @@ class TableData[HEAD](Table):
|
|
|
547
551
|
# ---------------------------------------------------------- #
|
|
548
552
|
# Leitura de dados - READ
|
|
549
553
|
# ---------------------------------------------------------- #
|
|
550
|
-
|
|
554
|
+
|
|
551
555
|
def get_data(self) -> pd.DataFrame:
|
|
552
556
|
return self._table_data
|
|
553
|
-
|
|
554
|
-
def get_row_at(self, idx: int) -> RowH[HEAD, Any]:
|
|
555
|
-
if self.empty():
|
|
556
|
-
raise TableEmptyError("A tabela está vazia")
|
|
557
557
|
|
|
558
|
-
|
|
559
|
-
|
|
558
|
+
def get_row_at(self, idx: int) -> RowH[HEAD, Any]:
|
|
559
|
+
total = self.size()
|
|
560
|
+
if idx >= total:
|
|
561
|
+
raise RowNotExistError(f"A linha {idx} não existe ... Total {total}")
|
|
560
562
|
|
|
561
|
-
|
|
562
|
-
|
|
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
|
|
563
567
|
|
|
564
568
|
def get_data_columns(self) -> pd.Index:
|
|
565
569
|
return TableData._object_index(self._table_data.columns)
|
|
566
570
|
|
|
567
571
|
def header(self) -> ArrayList[HEAD]:
|
|
568
|
-
return ArrayList(self._table_data.columns.tolist())
|
|
572
|
+
return ArrayList(self._table_data.columns.tolist()) # type: ignore > não falha apartir do pandas 3.x
|
|
569
573
|
|
|
570
574
|
def select_columns(self, header: list[HEAD]) -> TableData:
|
|
571
575
|
current = self.header()
|
|
@@ -573,9 +577,7 @@ class TableData[HEAD](Table):
|
|
|
573
577
|
if not current.contains(h):
|
|
574
578
|
raise ColumnNotFoundError(f"Coluna não encontrada: {h}")
|
|
575
579
|
|
|
576
|
-
return TableData(
|
|
577
|
-
self._table_data[list(header)].copy()
|
|
578
|
-
)
|
|
580
|
+
return TableData(self._table_data[list(header)].copy())
|
|
579
581
|
|
|
580
582
|
def get(self, h: HEAD) -> ColumnV[HEAD, Any]:
|
|
581
583
|
"""
|
|
@@ -592,13 +594,15 @@ class TableData[HEAD](Table):
|
|
|
592
594
|
# ---------------------------------------------------------- #
|
|
593
595
|
def add_row(self, row: RowH[HEAD, Any]) -> None:
|
|
594
596
|
"""
|
|
595
|
-
|
|
597
|
+
Adiciona uma linha a tabela se a linha não estiver vazia.
|
|
596
598
|
"""
|
|
597
599
|
if row.is_empty():
|
|
598
600
|
return None
|
|
599
601
|
|
|
600
|
-
|
|
602
|
+
# Tabela completamente vazia, criar o cabeçalho com base na linha recebida.
|
|
603
|
+
if self.is_void():
|
|
601
604
|
self._table_data = pd.DataFrame(columns=row.header())
|
|
605
|
+
row.index = 0
|
|
602
606
|
|
|
603
607
|
header: ArrayList[HEAD] = self.header()
|
|
604
608
|
|
|
@@ -611,7 +615,7 @@ class TableData[HEAD](Table):
|
|
|
611
615
|
if not row.header().contains(h):
|
|
612
616
|
msg = f"Você está tentando adicionar uma linha que não possui o cabeçalho >> [{h}] <<"
|
|
613
617
|
|
|
614
|
-
raise
|
|
618
|
+
raise ColumnNotFoudError(
|
|
615
619
|
f"{msg} \nCabeçalhos existentes na linha => {row.header()}\nCabeçalhos da tabela => {header}"
|
|
616
620
|
)
|
|
617
621
|
|
|
@@ -627,19 +631,28 @@ class TableData[HEAD](Table):
|
|
|
627
631
|
return None
|
|
628
632
|
|
|
629
633
|
def merge(self, tb: Table) -> None:
|
|
630
|
-
if tb.
|
|
634
|
+
if tb.is_empty():
|
|
631
635
|
raise TableEmptyError("Não é possível unir uma tabela vazia!")
|
|
632
636
|
|
|
633
|
-
|
|
634
|
-
|
|
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()}"
|
|
635
647
|
raise HeadersSizeNotIqualError(
|
|
636
648
|
f"Não é possível juntar tabelas com cabeçalhos diferentes.\n{msg}"
|
|
637
649
|
)
|
|
638
650
|
|
|
639
|
-
header = self.header()
|
|
640
651
|
for h in header:
|
|
641
652
|
if not tb.contains_header(h):
|
|
642
|
-
raise ColumnNotFoundError(
|
|
653
|
+
raise ColumnNotFoundError(
|
|
654
|
+
f"Coluna inexistente ... {h} ... Colunas disponíveis ... {self.header()}"
|
|
655
|
+
)
|
|
643
656
|
|
|
644
657
|
other = tb.to_dataframe()[list(header)]
|
|
645
658
|
|
|
@@ -649,36 +662,48 @@ class TableData[HEAD](Table):
|
|
|
649
662
|
self._table_data = pd.concat([self._table_data, other], ignore_index=True)
|
|
650
663
|
|
|
651
664
|
def add(self, col: ColumnV) -> None:
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
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())
|
|
656
681
|
|
|
657
682
|
def set(self, col: ColumnV[HEAD, ArrayList[T]]) -> None:
|
|
683
|
+
|
|
658
684
|
values: ArrayList = col.get_elements()
|
|
659
685
|
|
|
660
|
-
if self.
|
|
686
|
+
if self.header().empty():
|
|
661
687
|
# Tabela sem colunas: cria o DataFrame a partir da primeira coluna.
|
|
662
688
|
self._table_data = pd.DataFrame({col.head: values})
|
|
689
|
+
self._table_data.columns = self.get_data_columns()
|
|
663
690
|
return
|
|
664
691
|
|
|
665
692
|
total = self.size()
|
|
666
693
|
total_values = values.size()
|
|
667
694
|
|
|
668
695
|
if total == 0 and total_values > 0:
|
|
669
|
-
# Tabela só com cabeçalho (0 linhas): estende o índice.
|
|
670
696
|
self._table_data = self._table_data.reindex(range(total_values))
|
|
671
697
|
total = total_values
|
|
672
698
|
|
|
673
699
|
if total_values != total:
|
|
674
|
-
|
|
675
700
|
raise HeadersSizeNotIqualError(
|
|
676
701
|
f"{__class__.__name__}() Não é possível adicionar uma coluna com tamanho "
|
|
677
|
-
f"diferente da tabela. Tabela {total} | Coluna {
|
|
702
|
+
f"diferente da tabela. Tabela {total} | Coluna {total_values} {col.head}"
|
|
678
703
|
)
|
|
679
704
|
self._table_data[col.head] = values
|
|
680
705
|
self._table_data.columns = self.get_data_columns()
|
|
681
|
-
|
|
706
|
+
|
|
682
707
|
def set_data(self, df: pd.DataFrame) -> None:
|
|
683
708
|
self._table_data = df
|
|
684
709
|
|
|
@@ -704,7 +729,6 @@ class TableData[HEAD](Table):
|
|
|
704
729
|
# Pesquisar/Buscar dados - SEARCH
|
|
705
730
|
# ---------------------------------------------------------- #
|
|
706
731
|
def search(self, h: HEAD, value: Any) -> TableData[HEAD]:
|
|
707
|
-
|
|
708
732
|
"""
|
|
709
733
|
Retorna uma nova tabela apenas com as linhas onde a coluna `h` == value.
|
|
710
734
|
Se nada for encontrado, retorna uma tabela com o mesmo cabeçalho e 0 linhas.
|
|
@@ -715,6 +739,22 @@ class TableData[HEAD](Table):
|
|
|
715
739
|
df = self._table_data[self._table_data[h] == value].reset_index(drop=True)
|
|
716
740
|
return TableData(df)
|
|
717
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
|
+
|
|
718
758
|
# ---------------------------------------------------------- #
|
|
719
759
|
# Exclusão de dados - DELETE
|
|
720
760
|
# ---------------------------------------------------------- #
|
|
@@ -722,7 +762,7 @@ class TableData[HEAD](Table):
|
|
|
722
762
|
self._table_data = pd.DataFrame()
|
|
723
763
|
|
|
724
764
|
def drop_duplicates(self) -> TableData:
|
|
725
|
-
if self.
|
|
765
|
+
if self.is_empty():
|
|
726
766
|
raise TableEmptyError()
|
|
727
767
|
|
|
728
768
|
df = self._table_data.drop_duplicates().reset_index(drop=True)
|
|
@@ -730,9 +770,9 @@ class TableData[HEAD](Table):
|
|
|
730
770
|
|
|
731
771
|
def remove_null(self, header: HEAD) -> TableData[HEAD]:
|
|
732
772
|
"""
|
|
733
|
-
|
|
773
|
+
Remove as linhas em que a coluna `header` seja NaN, "", "nan" ou "NaN".
|
|
734
774
|
"""
|
|
735
|
-
if self.
|
|
775
|
+
if self.is_empty():
|
|
736
776
|
raise TableEmptyError(f"A tabela está vazia e não possui a coluna {header}")
|
|
737
777
|
|
|
738
778
|
if not self.contains_header(header):
|
|
@@ -771,7 +811,13 @@ class TableData[HEAD](Table):
|
|
|
771
811
|
def create_from_map(cls, hash_map: HashMap[HEAD, list[Any]]) -> TableData:
|
|
772
812
|
return cls(hash_map.to_data_frame())
|
|
773
813
|
|
|
774
|
-
|
|
814
|
+
|
|
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:
|
|
775
821
|
"""
|
|
776
822
|
Concatenar uma lista de tabelas, se receber uma lista vazia gera a exceção ListTablesEmptyError().
|
|
777
823
|
"""
|
|
@@ -779,27 +825,11 @@ def concat_tables(values: list[Table], *, rt_type: type[TableData | TableMap] =
|
|
|
779
825
|
if len(values) == 0:
|
|
780
826
|
raise ListTablesEmptyError("Não é possível concatenar uma lista vazia")
|
|
781
827
|
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
header = first.header()
|
|
786
|
-
|
|
787
|
-
for h in header:
|
|
788
|
-
final.add(ColumnV(h))
|
|
828
|
+
header = values[0].header()
|
|
829
|
+
final: Table = rt_type()
|
|
830
|
+
header.for_each(lambda h: final.add(ColumnV(h)))
|
|
789
831
|
|
|
790
832
|
current_table: Table
|
|
791
|
-
|
|
792
833
|
for current_table in values:
|
|
793
|
-
|
|
794
|
-
raise TableEmptyError(f"Não é possível concatenar uma tabela vazia!")
|
|
795
|
-
|
|
796
|
-
if current_table.header().size() != header.size():
|
|
797
|
-
raise HeadersSizeNotIqualError("As tabelas precisam ter colunas de tamanhos iguais para concatenar!")
|
|
798
|
-
|
|
799
|
-
for h in header:
|
|
800
|
-
if not current_table.header().contains(h):
|
|
801
|
-
raise ColumnNotFoundError(f'Coluna não encontrada: {h}')
|
|
802
|
-
|
|
803
|
-
final.get(h).add_all(current_table.get(h).get_elements())
|
|
804
|
-
|
|
834
|
+
final.merge(current_table)
|
|
805
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
|