stouputils 1.6.1__tar.gz → 1.6.3__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.
Files changed (137) hide show
  1. {stouputils-1.6.1 → stouputils-1.6.3}/PKG-INFO +1 -1
  2. {stouputils-1.6.1 → stouputils-1.6.3}/pyproject.toml +1 -1
  3. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/io.py +153 -0
  4. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/io.pyi +64 -0
  5. {stouputils-1.6.1 → stouputils-1.6.3}/.gitignore +0 -0
  6. {stouputils-1.6.1 → stouputils-1.6.3}/LICENSE +0 -0
  7. {stouputils-1.6.1 → stouputils-1.6.3}/README.md +0 -0
  8. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/__init__.py +0 -0
  9. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/__init__.pyi +0 -0
  10. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/__main__.py +0 -0
  11. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/all_doctests.py +0 -0
  12. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/all_doctests.pyi +0 -0
  13. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/applications/__init__.py +0 -0
  14. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/applications/__init__.pyi +0 -0
  15. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/applications/automatic_docs.py +0 -0
  16. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/applications/automatic_docs.pyi +0 -0
  17. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/applications/upscaler/__init__.py +0 -0
  18. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/applications/upscaler/__init__.pyi +0 -0
  19. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/applications/upscaler/config.py +0 -0
  20. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/applications/upscaler/config.pyi +0 -0
  21. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/applications/upscaler/image.py +0 -0
  22. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/applications/upscaler/image.pyi +0 -0
  23. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/applications/upscaler/video.py +0 -0
  24. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/applications/upscaler/video.pyi +0 -0
  25. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/archive.py +0 -0
  26. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/archive.pyi +0 -0
  27. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/backup.py +0 -0
  28. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/backup.pyi +0 -0
  29. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/collections.py +0 -0
  30. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/collections.pyi +0 -0
  31. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/continuous_delivery/__init__.py +0 -0
  32. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/continuous_delivery/__init__.pyi +0 -0
  33. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/continuous_delivery/cd_utils.py +0 -0
  34. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/continuous_delivery/cd_utils.pyi +0 -0
  35. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/continuous_delivery/github.py +0 -0
  36. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/continuous_delivery/github.pyi +0 -0
  37. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/continuous_delivery/pypi.py +0 -0
  38. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/continuous_delivery/pypi.pyi +0 -0
  39. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/continuous_delivery/pyproject.py +0 -0
  40. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/continuous_delivery/pyproject.pyi +0 -0
  41. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/continuous_delivery/stubs.py +0 -0
  42. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/continuous_delivery/stubs.pyi +0 -0
  43. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/ctx.py +0 -0
  44. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/ctx.pyi +0 -0
  45. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/config/get.py +0 -0
  46. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/config/set.py +0 -0
  47. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/__init__.py +0 -0
  48. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/auto_contrast.py +0 -0
  49. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/axis_flip.py +0 -0
  50. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/bias_field_correction.py +0 -0
  51. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/binary_threshold.py +0 -0
  52. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/blur.py +0 -0
  53. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/brightness.py +0 -0
  54. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/canny.py +0 -0
  55. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/clahe.py +0 -0
  56. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/common.py +0 -0
  57. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/contrast.py +0 -0
  58. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/curvature_flow_filter.py +0 -0
  59. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/denoise.py +0 -0
  60. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/histogram_equalization.py +0 -0
  61. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/invert.py +0 -0
  62. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/laplacian.py +0 -0
  63. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/median_blur.py +0 -0
  64. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/noise.py +0 -0
  65. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/normalize.py +0 -0
  66. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/random_erase.py +0 -0
  67. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/resize.py +0 -0
  68. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/rotation.py +0 -0
  69. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/salt_pepper.py +0 -0
  70. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/sharpening.py +0 -0
  71. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/shearing.py +0 -0
  72. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/threshold.py +0 -0
  73. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/translation.py +0 -0
  74. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image/zoom.py +0 -0
  75. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image_augmentation.py +0 -0
  76. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/image_preprocess.py +0 -0
  77. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/prosthesis_detection.py +0 -0
  78. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/data_processing/technique.py +0 -0
  79. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/dataset/__init__.py +0 -0
  80. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/dataset/dataset.py +0 -0
  81. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/dataset/dataset_loader.py +0 -0
  82. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/dataset/grouping_strategy.py +0 -0
  83. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/dataset/image_loader.py +0 -0
  84. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/dataset/xy_tuple.py +0 -0
  85. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/metric_dictionnary.py +0 -0
  86. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/metric_utils.py +0 -0
  87. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/mlflow_utils.py +0 -0
  88. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/abstract_model.py +0 -0
  89. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/all.py +0 -0
  90. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/base_keras.py +0 -0
  91. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras/all.py +0 -0
  92. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras/convnext.py +0 -0
  93. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras/densenet.py +0 -0
  94. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras/efficientnet.py +0 -0
  95. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras/mobilenet.py +0 -0
  96. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras/resnet.py +0 -0
  97. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras/squeezenet.py +0 -0
  98. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras/vgg.py +0 -0
  99. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras/xception.py +0 -0
  100. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras_utils/callbacks/__init__.py +0 -0
  101. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras_utils/callbacks/colored_progress_bar.py +0 -0
  102. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras_utils/callbacks/learning_rate_finder.py +0 -0
  103. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras_utils/callbacks/model_checkpoint_v2.py +0 -0
  104. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras_utils/callbacks/progressive_unfreezing.py +0 -0
  105. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras_utils/callbacks/warmup_scheduler.py +0 -0
  106. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras_utils/losses/__init__.py +0 -0
  107. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras_utils/losses/next_generation_loss.py +0 -0
  108. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/keras_utils/visualizations.py +0 -0
  109. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/model_interface.py +0 -0
  110. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/models/sandbox.py +0 -0
  111. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/range_tuple.py +0 -0
  112. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/scripts/augment_dataset.py +0 -0
  113. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/scripts/exhaustive_process.py +0 -0
  114. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/scripts/preprocess_dataset.py +0 -0
  115. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/scripts/routine.py +0 -0
  116. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/data_science/utils.py +0 -0
  117. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/decorators.py +0 -0
  118. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/decorators.pyi +0 -0
  119. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/image.py +0 -0
  120. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/image.pyi +0 -0
  121. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/installer/__init__.py +0 -0
  122. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/installer/__init__.pyi +0 -0
  123. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/installer/common.py +0 -0
  124. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/installer/common.pyi +0 -0
  125. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/installer/downloader.py +0 -0
  126. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/installer/downloader.pyi +0 -0
  127. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/installer/linux.py +0 -0
  128. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/installer/linux.pyi +0 -0
  129. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/installer/main.py +0 -0
  130. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/installer/main.pyi +0 -0
  131. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/installer/windows.py +0 -0
  132. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/installer/windows.pyi +0 -0
  133. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/parallel.py +0 -0
  134. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/parallel.pyi +0 -0
  135. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/print.py +0 -0
  136. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/print.pyi +0 -0
  137. {stouputils-1.6.1 → stouputils-1.6.3}/stouputils/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stouputils
3
- Version: 1.6.1
3
+ Version: 1.6.3
4
4
  Summary: Stouputils is a collection of utility modules designed to simplify and enhance the development process. It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers, and many more.
5
5
  Project-URL: Homepage, https://github.com/Stoupy51/stouputils
6
6
  Project-URL: Issues, https://github.com/Stoupy51/stouputils/issues
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
5
5
 
6
6
  [project]
7
7
  name = "stouputils"
8
- version = "1.6.1"
8
+ version = "1.6.3"
9
9
  description = "Stouputils is a collection of utility modules designed to simplify and enhance the development process. It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers, and many more."
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.10"
@@ -5,6 +5,8 @@ This module provides utilities for file management.
5
5
  - relative_path: Get the relative path of a file relative to a given directory
6
6
  - super_json_dump: Writes the provided data to a JSON file with a specified indentation depth.
7
7
  - super_json_load: Load a JSON file from the given path
8
+ - super_csv_dump: Writes data to a CSV file with customizable options
9
+ - super_csv_load: Load a CSV file from the given path
8
10
  - super_copy: Copy a file (or a folder) from the source to the destination (always create the directory)
9
11
  - super_open: Open a file with the given mode, creating the directory if it doesn't exist (only if writing)
10
12
  - replace_tilde: Replace the "~" by the user's home directory
@@ -15,9 +17,11 @@ This module provides utilities for file management.
15
17
  """
16
18
 
17
19
  # Imports
20
+ import csv
18
21
  import os
19
22
  import re
20
23
  import shutil
24
+ from io import StringIO
21
25
  from typing import IO, Any
22
26
 
23
27
  import orjson
@@ -139,6 +143,155 @@ def super_json_load(file_path: str) -> Any:
139
143
  with super_open(file_path, "r") as f:
140
144
  return orjson.loads(f.read())
141
145
 
146
+ # CSV dump to file
147
+ def super_csv_dump(data: Any, file: IO[Any] | None = None, delimiter: str = ',', has_header: bool = True, index: bool = False, *args: Any, **kwargs: Any) -> str:
148
+ """ Writes data to a CSV file with customizable options
149
+
150
+ Args:
151
+ data (list[list[Any]] | list[dict[str, Any]] | pd.DataFrame | pl.DataFrame): The data to write, either a list of lists, list of dicts, pandas DataFrame, or Polars DataFrame
152
+ file (IO[Any]): The file to dump the data to, if None, the data is returned as a string
153
+ delimiter (str): The delimiter to use (default: ',')
154
+ has_header (bool): Whether to include headers (default: True, applies to dict and DataFrame data)
155
+ index (bool): Whether to include the index (default: False, only applies to pandas DataFrame)
156
+ *args: Additional positional arguments to pass to the underlying CSV writer or DataFrame method
157
+ **kwargs: Additional keyword arguments to pass to the underlying CSV writer or DataFrame method
158
+ Returns:
159
+ str: The CSV content as a string
160
+
161
+ Examples:
162
+
163
+ >>> super_csv_dump([["a", "b", "c"], [1, 2, 3], [4, 5, 6]])
164
+ 'a,b,c\\r\\n1,2,3\\r\\n4,5,6\\r\\n'
165
+
166
+ >>> super_csv_dump([{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}])
167
+ 'name,age\\r\\nAlice,30\\r\\nBob,25\\r\\n'
168
+ """
169
+ if not data:
170
+ return ""
171
+ if isinstance(data, str | bytes | dict):
172
+ raise ValueError("Data must be a list of lists, list of dicts, pandas DataFrame, or Polars DataFrame")
173
+ output = StringIO()
174
+
175
+ # Handle Polars DataFrame
176
+ try:
177
+ import polars as pl # type: ignore # noqa: F401
178
+ copy_kwargs = kwargs.copy()
179
+ copy_kwargs.setdefault("separator", delimiter)
180
+ copy_kwargs.setdefault("include_header", has_header)
181
+ copy_kwargs.setdefault("line_terminator", "\r\n")
182
+ data.write_csv(output, *args, **copy_kwargs)
183
+ except AttributeError:
184
+ pass
185
+
186
+ # Handle pandas DataFrame
187
+ try:
188
+ import pandas as pd # type: ignore # noqa: F401
189
+ copy_kwargs = kwargs.copy()
190
+ copy_kwargs.setdefault("index", index)
191
+ copy_kwargs.setdefault("sep", delimiter)
192
+ copy_kwargs.setdefault("header", has_header)
193
+ copy_kwargs.setdefault("lineterminator", "\r\n")
194
+ data.to_csv(output, *args, **copy_kwargs)
195
+ except AttributeError:
196
+ pass
197
+
198
+ # Handle list of dicts
199
+ if isinstance(data[0], dict):
200
+ fieldnames = list(data[0].keys())
201
+ kwargs.setdefault("fieldnames", fieldnames)
202
+ kwargs.setdefault("delimiter", delimiter)
203
+ kwargs.setdefault("lineterminator", "\r\n")
204
+ dict_writer = csv.DictWriter(output, *args, **kwargs)
205
+ if has_header:
206
+ dict_writer.writeheader()
207
+ dict_writer.writerows(data) # type: ignore
208
+
209
+ # Handle list of lists
210
+ else:
211
+ kwargs.setdefault("delimiter", delimiter)
212
+ kwargs.setdefault("lineterminator", "\r\n")
213
+ list_writer = csv.writer(output, *args, **kwargs)
214
+ list_writer.writerows(data)
215
+
216
+ content: str = output.getvalue()
217
+ if file:
218
+ file.write(content)
219
+ output.close()
220
+ return content
221
+
222
+ # CSV load from file path
223
+ def super_csv_load(file_path: str, delimiter: str = ',', has_header: bool = True, as_dict: bool = False, as_dataframe: bool = False, use_polars: bool = False, *args: Any, **kwargs: Any) -> Any:
224
+ """ Load a CSV file from the given path
225
+
226
+ Args:
227
+ file_path (str): The path to the CSV file
228
+ delimiter (str): The delimiter used in the CSV (default: ',')
229
+ has_header (bool): Whether the CSV has a header row (default: True)
230
+ as_dict (bool): Whether to return data as list of dicts (default: False)
231
+ as_dataframe (bool): Whether to return data as a DataFrame (default: False)
232
+ use_polars (bool): Whether to use Polars instead of pandas for DataFrame (default: False, requires polars)
233
+ *args: Additional positional arguments to pass to the underlying CSV reader or DataFrame method
234
+ **kwargs: Additional keyword arguments to pass to the underlying CSV reader or DataFrame method
235
+ Returns:
236
+ list[list[str]] | list[dict[str, str]] | pd.DataFrame | pl.DataFrame: The content of the CSV file
237
+
238
+ Examples:
239
+
240
+ .. code-block:: python
241
+
242
+ > Assuming "test.csv" contains: a,b,c\\n1,2,3\\n4,5,6
243
+ > super_csv_load("test.csv")
244
+ [['1', '2', '3'], ['4', '5', '6']]
245
+
246
+ > super_csv_load("test.csv", as_dict=True)
247
+ [{'a': '1', 'b': '2', 'c': '3'}, {'a': '4', 'b': '5', 'c': '6'}]
248
+
249
+ > super_csv_load("test.csv", as_dataframe=True)
250
+ a b c
251
+ 0 1 2 3
252
+ 1 4 5 6
253
+
254
+ > super_csv_load("test.csv", as_dataframe=True, use_polars=True)
255
+ shape: (2, 3)
256
+ ┌─────┬─────┬─────┐
257
+ │ a ┆ b ┆ c │
258
+ │ --- ┆ --- ┆ --- │
259
+ │ i64 ┆ i64 ┆ i64 │
260
+ ╞═════╪═════╪═════╡
261
+ │ 1 ┆ 2 ┆ 3 │
262
+ │ 4 ┆ 5 ┆ 6 │
263
+ └─────┴─────┴─────┘
264
+ """ # noqa: E101
265
+ # Handle DataFrame loading
266
+ if as_dataframe:
267
+ if use_polars:
268
+ import polars as pl # type: ignore
269
+ if not os.path.exists(file_path):
270
+ return pl.DataFrame()
271
+ kwargs.setdefault("separator", delimiter)
272
+ kwargs.setdefault("has_header", has_header)
273
+ return pl.read_csv(file_path, *args, **kwargs)
274
+ else:
275
+ import pandas as pd # type: ignore
276
+ if not os.path.exists(file_path):
277
+ return pd.DataFrame()
278
+ kwargs.setdefault("sep", delimiter)
279
+ kwargs.setdefault("header", 0 if has_header else None)
280
+ return pd.read_csv(file_path, *args, **kwargs) # type: ignore
281
+
282
+ # Handle dict or list
283
+ if not os.path.exists(file_path):
284
+ return []
285
+ with super_open(file_path, "r") as f:
286
+ if as_dict or has_header:
287
+ kwargs.setdefault("delimiter", delimiter)
288
+ reader = csv.DictReader(f, *args, **kwargs)
289
+ return list(reader)
290
+ else:
291
+ kwargs.setdefault("delimiter", delimiter)
292
+ reader = csv.reader(f, *args, **kwargs)
293
+ return list(reader)
294
+
142
295
  # For easy file copy
143
296
  def super_copy(src: str, dst: str, create_dir: bool = True, symlink: bool = False) -> str:
144
297
  """ Copy a file (or a folder) from the source to the destination
@@ -65,6 +65,70 @@ def super_json_load(file_path: str) -> Any:
65
65
  \tReturns:
66
66
  \t\tAny: The content of the JSON file
67
67
  \t"""
68
+ def super_csv_dump(data: Any, file: IO[Any] | None = None, delimiter: str = ',', has_header: bool = True, index: bool = False, *args: Any, **kwargs: Any) -> str:
69
+ ''' Writes data to a CSV file with customizable options
70
+
71
+ \tArgs:
72
+ \t\tdata (list[list[Any]] | list[dict[str, Any]] | pd.DataFrame | pl.DataFrame): The data to write, either a list of lists, list of dicts, pandas DataFrame, or Polars DataFrame
73
+ \t\tfile (IO[Any]): The file to dump the data to, if None, the data is returned as a string
74
+ \t\tdelimiter (str): The delimiter to use (default: \',\')
75
+ \t\thas_header (bool): Whether to include headers (default: True, applies to dict and DataFrame data)
76
+ \t\tindex (bool): Whether to include the index (default: False, only applies to pandas DataFrame)
77
+ \t\t*args: Additional positional arguments to pass to the underlying CSV writer or DataFrame method
78
+ \t\t**kwargs: Additional keyword arguments to pass to the underlying CSV writer or DataFrame method
79
+ \tReturns:
80
+ \t\tstr: The CSV content as a string
81
+
82
+ \tExamples:
83
+
84
+ \t\t>>> super_csv_dump([["a", "b", "c"], [1, 2, 3], [4, 5, 6]])
85
+ \t\t\'a,b,c\\r\\n1,2,3\\r\\n4,5,6\\r\\n\'
86
+
87
+ \t\t>>> super_csv_dump([{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}])
88
+ \t\t\'name,age\\r\\nAlice,30\\r\\nBob,25\\r\\n\'
89
+ \t'''
90
+ def super_csv_load(file_path: str, delimiter: str = ',', has_header: bool = True, as_dict: bool = False, as_dataframe: bool = False, use_polars: bool = False, *args: Any, **kwargs: Any) -> Any:
91
+ ''' Load a CSV file from the given path
92
+
93
+ \tArgs:
94
+ \t\tfile_path (str): The path to the CSV file
95
+ \t\tdelimiter (str): The delimiter used in the CSV (default: \',\')
96
+ \t\thas_header (bool): Whether the CSV has a header row (default: True)
97
+ \t\tas_dict (bool): Whether to return data as list of dicts (default: False)
98
+ \t\tas_dataframe (bool): Whether to return data as a DataFrame (default: False)
99
+ \t\tuse_polars (bool): Whether to use Polars instead of pandas for DataFrame (default: False, requires polars)
100
+ \t\t*args: Additional positional arguments to pass to the underlying CSV reader or DataFrame method
101
+ \t\t**kwargs: Additional keyword arguments to pass to the underlying CSV reader or DataFrame method
102
+ \tReturns:
103
+ \t\tlist[list[str]] | list[dict[str, str]] | pd.DataFrame | pl.DataFrame: The content of the CSV file
104
+
105
+ \tExamples:
106
+
107
+ \t\t.. code-block:: python
108
+
109
+ \t\t\t> Assuming "test.csv" contains: a,b,c\\n1,2,3\\n4,5,6
110
+ \t\t\t> super_csv_load("test.csv")
111
+ \t\t\t[[\'1\', \'2\', \'3\'], [\'4\', \'5\', \'6\']]
112
+
113
+ \t\t\t> super_csv_load("test.csv", as_dict=True)
114
+ \t\t\t[{\'a\': \'1\', \'b\': \'2\', \'c\': \'3\'}, {\'a\': \'4\', \'b\': \'5\', \'c\': \'6\'}]
115
+
116
+ \t\t\t> super_csv_load("test.csv", as_dataframe=True)
117
+ \t\t\t a b c
118
+ \t\t\t0 1 2 3
119
+ \t\t\t1 4 5 6
120
+
121
+ \t\t\t> super_csv_load("test.csv", as_dataframe=True, use_polars=True)
122
+ \t\t\tshape: (2, 3)
123
+ \t\t\t┌─────┬─────┬─────┐
124
+ \t\t\t│ a ┆ b ┆ c │
125
+ \t\t\t│ --- ┆ --- ┆ --- │
126
+ \t\t\t│ i64 ┆ i64 ┆ i64 │
127
+ \t\t\t╞═════╪═════╪═════╡
128
+ \t\t\t│ 1 ┆ 2 ┆ 3 │
129
+ \t\t\t│ 4 ┆ 5 ┆ 6 │
130
+ \t\t\t└─────┴─────┴─────┘
131
+ \t'''
68
132
  def super_copy(src: str, dst: str, create_dir: bool = True, symlink: bool = False) -> str:
69
133
  """ Copy a file (or a folder) from the source to the destination
70
134
 
File without changes
File without changes
File without changes
File without changes