tablas-python 0.1.3__py3-none-any.whl → 0.1.4__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.
tablas_python/__init__.py CHANGED
@@ -32,7 +32,7 @@ from utils.data_helpers import (
32
32
  conciliar_tablas,
33
33
  )
34
34
 
35
- __version__ = "0.1.3"
35
+ __version__ = "0.1.4"
36
36
 
37
37
  __all__ = [
38
38
  "TableManager",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tablas-python
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: Suite modular para extraer, transformar, conciliar y exportar tablas desde PDF, Excel y SQLite a pandas.
5
5
  Author: Reciba
6
6
  License: MIT
@@ -1,12 +1,12 @@
1
1
  helpers/__init__.py,sha256=hopndlywciR50FKi6W6Lo_cAOP_YyPsQV3xj8hfkH_Y,899
2
2
  helpers/display_helper.py,sha256=i0--Txkjc9__IIKwdkmpx98vzwM_Sekr0RzxvVGEPYA,7749
3
3
  helpers/table_manager.py,sha256=85OZqMdDqgBBJaln2ehb3-t7RWS1Gowo6aud_zqVHAo,19063
4
- tablas_python/__init__.py,sha256=Y-L9T9fn7gBiZdkXJ-qI9pe6bh7frMG71hgcqqcOqqM,1771
4
+ tablas_python/__init__.py,sha256=xVyYUKPzia_CaMiVFM_WxtIBx-8Y06ltIAWFD0U-cVY,1771
5
5
  tablas_python/cli.py,sha256=3BModRFfT8WFkbCSxM9cF_oBK87FetPMGm5F0GTZGNo,1957
6
- tablas_python-0.1.3.dist-info/licenses/LICENSE,sha256=DQi0EoD04d2_-pnEKrC4WmcmgR6O0WQcJdvma9ILoFQ,1063
6
+ tablas_python-0.1.4.dist-info/licenses/LICENSE,sha256=DQi0EoD04d2_-pnEKrC4WmcmgR6O0WQcJdvma9ILoFQ,1063
7
7
  utils/__init__.py,sha256=duEZSrdPZggUMdpJqJsNMQ5aLRaFcONBvhsdJuhCToo,2004
8
8
  utils/batch_processor.py,sha256=rE59qkb2sp5J0E5NU77U-CF82Aa-ukrjN2druwgS2Uk,4162
9
- utils/data_helpers.py,sha256=oJx5NPTpCNTHVvSCpqVeTnWGJsflYKl5v6lLUov08Hs,21758
9
+ utils/data_helpers.py,sha256=U6RTiJd0NpqYtk8kQa37jaJBMCay0CUnduREjaoPLM0,23526
10
10
  utils/excel_extractor.py,sha256=0WUhkV5eu9uUusU8zSHQB1ujFG7eQVqI-go4zqxmPFU,18364
11
11
  utils/excel_writer.py,sha256=zH_Mtu3Cr_ND_wSHKFyvzH3j16gjVoANpM3dVFXKpr0,6991
12
12
  utils/exporter.py,sha256=Oo9Y6dXTg_7t6n824xoxv8d9yuhdHZNWfwLLXvSvtMw,4661
@@ -15,8 +15,8 @@ utils/pdf_extractor.py,sha256=3JRMqnEfhBVaUOeYfiNH1rReC4EoSbzDwk919x6647w,4768
15
15
  utils/sqlite_extractor.py,sha256=mvKlKY-nsd5cV73nn3xFoqg5dgagPJceRDJfPLG0cbs,5033
16
16
  utils/table_cleaner.py,sha256=ncyiunqpVdKParFcRKwQbCqyKZgpyKRN0aUM0Oug9wU,10465
17
17
  utils/validator.py,sha256=0UywK_D510ZQCcSkhFRKhEuw48788NM_RFVC-bIFZkE,5837
18
- tablas_python-0.1.3.dist-info/METADATA,sha256=rJMNr3NxGAcFwaz4xgAdmZ6IKJbCHPqiKXJGF4tG2MY,13611
19
- tablas_python-0.1.3.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
20
- tablas_python-0.1.3.dist-info/entry_points.txt,sha256=l29nooItcUpsFzN5LmxM1b-j0qih61vJB9tX8KUwlMg,89
21
- tablas_python-0.1.3.dist-info/top_level.txt,sha256=Foud-Tbf5pviUJmp7wc3v24IjIyypkvbcZt7HkrWvss,28
22
- tablas_python-0.1.3.dist-info/RECORD,,
18
+ tablas_python-0.1.4.dist-info/METADATA,sha256=jpBHw3DHlXyFY2qoyOofl65SS0PTXuvRATwthrL0qZI,13611
19
+ tablas_python-0.1.4.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
20
+ tablas_python-0.1.4.dist-info/entry_points.txt,sha256=l29nooItcUpsFzN5LmxM1b-j0qih61vJB9tX8KUwlMg,89
21
+ tablas_python-0.1.4.dist-info/top_level.txt,sha256=Foud-Tbf5pviUJmp7wc3v24IjIyypkvbcZt7HkrWvss,28
22
+ tablas_python-0.1.4.dist-info/RECORD,,
utils/data_helpers.py CHANGED
@@ -141,22 +141,56 @@ def formato_moneda(val: Any, simbolo: str = "$", decimales: int = 0, separador_m
141
141
  return f"{simbolo} {texto}" if simbolo else texto
142
142
 
143
143
 
144
- def formato_porcentaje(val: Any, decimales: int = 1) -> str:
144
+ def formato_porcentaje(
145
+ val: Any,
146
+ decimales: Optional[int] = None,
147
+ multiplicar_por_100: bool = False,
148
+ separador_decimal: str = ","
149
+ ) -> str:
145
150
  """
146
- Formatea un valor a porcentaje.
147
- Ejemplo:
148
- formato_porcentaje(15.42) -> "15.4%"
149
- formato_porcentaje(0.1542, es_ratio=True)
151
+ Formatea un valor a porcentaje de manera exacta.
152
+
153
+ A diferencia de versiones anteriores, NO multiplica arbitrariamente por 100
154
+ a menos que se indique explícitamente con `multiplicar_por_100=True`.
155
+ Por lo tanto, 0.056 se muestra como 0,056% y 5.56 se muestra como 5,56%.
156
+
157
+ Ejemplos:
158
+ formato_porcentaje(5.56) -> "5,56%"
159
+ formato_porcentaje(0.056) -> "0,056%"
160
+ formato_porcentaje("0.056%") -> "0,056%"
161
+ formato_porcentaje(0.056, multiplicar_por_100=True) -> "5,6%"
162
+ formato_porcentaje(15.42, decimales=1) -> "15,4%"
150
163
  """
164
+ if pd.isna(val) or val is None or str(val).strip() == "":
165
+ return ""
166
+
167
+ s_orig = str(val).strip()
168
+ tenia_simbolo_pct = "%" in s_orig
169
+
151
170
  num = limpiar_numero(val)
152
171
  if pd.isna(num) or not isinstance(num, (int, float)):
153
- return "" if pd.isna(val) else str(val)
154
-
155
- # Si el valor está entre 0 y 1 (ratio), convertir a base 100
156
- if -1.0 <= num <= 1.0 and num != 0:
172
+ return s_orig
173
+
174
+ # Solo multiplicar por 100 si el usuario lo pide explícitamente y el valor NO traía ya el '%'
175
+ if multiplicar_por_100 and not tenia_simbolo_pct:
157
176
  num = num * 100
158
177
 
159
- return f"{num:.{decimales}f}%"
178
+ if decimales is not None:
179
+ fmt_str = f"{{:.{decimales}f}}"
180
+ txt_num = fmt_str.format(num)
181
+ else:
182
+ # Conservar los decimales significativos del número sin truncar
183
+ if isinstance(num, int) or (isinstance(num, float) and num.is_integer()):
184
+ txt_num = str(int(num))
185
+ else:
186
+ txt_num = f"{num:.6f}".rstrip('0').rstrip('.')
187
+
188
+ if separador_decimal == ",":
189
+ txt_num = txt_num.replace(".", ",")
190
+ else:
191
+ txt_num = txt_num.replace(",", ".")
192
+
193
+ return f"{txt_num}%"
160
194
 
161
195
 
162
196
  def formato_miles(val: Any, decimales: int = 0) -> str:
@@ -176,6 +210,8 @@ def formatear_dataframe(
176
210
  'Ventas': 'moneda',
177
211
  'Precio': 'moneda_2dec',
178
212
  'Margen': 'porcentaje',
213
+ 'Participacion': 'porcentaje_1dec',
214
+ 'Ratio': 'ratio_pct',
179
215
  'Cantidad': 'miles'
180
216
  })
181
217
  """
@@ -188,7 +224,13 @@ def formatear_dataframe(
188
224
  elif tipo == 'moneda_2dec':
189
225
  df_out[col] = df_out[col].apply(lambda x: formato_moneda(x, decimales=2))
190
226
  elif tipo == 'porcentaje':
191
- df_out[col] = df_out[col].apply(formato_porcentaje)
227
+ df_out[col] = df_out[col].apply(lambda x: formato_porcentaje(x))
228
+ elif tipo == 'porcentaje_1dec':
229
+ df_out[col] = df_out[col].apply(lambda x: formato_porcentaje(x, decimales=1))
230
+ elif tipo == 'porcentaje_2dec':
231
+ df_out[col] = df_out[col].apply(lambda x: formato_porcentaje(x, decimales=2))
232
+ elif tipo == 'ratio_pct':
233
+ df_out[col] = df_out[col].apply(lambda x: formato_porcentaje(x, multiplicar_por_100=True, decimales=1))
192
234
  elif tipo == 'miles':
193
235
  df_out[col] = df_out[col].apply(formato_miles)
194
236
  return df_out