numdaplot 0.1.0__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.
Files changed (474) hide show
  1. numdaplot/__init__.py +506 -0
  2. numdaplot/arrays/__init__.py +5 -0
  3. numdaplot/arrays/array.py +92 -0
  4. numdaplot/arrays/array_arithmetic.py +404 -0
  5. numdaplot/arrays/array_calculation.py +143 -0
  6. numdaplot/arrays/array_conversion.py +150 -0
  7. numdaplot/arrays/array_creation.py +371 -0
  8. numdaplot/arrays/array_data.py +281 -0
  9. numdaplot/arrays/array_layout.py +179 -0
  10. numdaplot/arrays/array_logic.py +227 -0
  11. numdaplot/arrays/array_reflected_arithmetic.py +334 -0
  12. numdaplot/arrays/array_refusals.py +339 -0
  13. numdaplot/arrays/array_selection.py +195 -0
  14. numdaplot/arrays/array_sorting.py +59 -0
  15. numdaplot/arrays/axis_number.py +58 -0
  16. numdaplot/arrays/calculation/__init__.py +5 -0
  17. numdaplot/arrays/calculation/counting_statistics.py +325 -0
  18. numdaplot/arrays/calculation/location_statistics.py +268 -0
  19. numdaplot/arrays/calculation/math_function_values.py +183 -0
  20. numdaplot/arrays/calculation/statistic_values.py +209 -0
  21. numdaplot/arrays/calculation/time_function_values.py +419 -0
  22. numdaplot/arrays/conversion/__init__.py +5 -0
  23. numdaplot/arrays/conversion/array_text.py +62 -0
  24. numdaplot/arrays/conversion/equality_check.py +72 -0
  25. numdaplot/arrays/conversion/python_values.py +70 -0
  26. numdaplot/arrays/conversion/time_text.py +290 -0
  27. numdaplot/arrays/creation/__init__.py +5 -0
  28. numdaplot/arrays/creation/date_parts.py +89 -0
  29. numdaplot/arrays/creation/date_parts_values.py +437 -0
  30. numdaplot/arrays/creation/distribution.py +54 -0
  31. numdaplot/arrays/creation/filled_values.py +58 -0
  32. numdaplot/arrays/creation/list_conversion.py +311 -0
  33. numdaplot/arrays/creation/list_shape.py +97 -0
  34. numdaplot/arrays/creation/normal.py +65 -0
  35. numdaplot/arrays/creation/numpy_conversion.py +149 -0
  36. numdaplot/arrays/creation/random_integers.py +104 -0
  37. numdaplot/arrays/creation/random_values.py +97 -0
  38. numdaplot/arrays/creation/range_values.py +73 -0
  39. numdaplot/arrays/creation/spacing.py +84 -0
  40. numdaplot/arrays/creation/spacing_values.py +63 -0
  41. numdaplot/arrays/creation/uniform.py +63 -0
  42. numdaplot/arrays/equality.py +68 -0
  43. numdaplot/arrays/layout/__init__.py +5 -0
  44. numdaplot/arrays/layout/sorting_values.py +113 -0
  45. numdaplot/arrays/layout/unique_values.py +49 -0
  46. numdaplot/arrays/mapping/__init__.py +5 -0
  47. numdaplot/arrays/mapping/mapped_values.py +286 -0
  48. numdaplot/arrays/mapping/unmatched.py +50 -0
  49. numdaplot/arrays/mapping/value_change.py +55 -0
  50. numdaplot/arrays/mapping/value_mapping.py +161 -0
  51. numdaplot/arrays/math_functions/__init__.py +5 -0
  52. numdaplot/arrays/math_functions/absolute.py +27 -0
  53. numdaplot/arrays/math_functions/cosine.py +28 -0
  54. numdaplot/arrays/math_functions/exponential.py +27 -0
  55. numdaplot/arrays/math_functions/logarithm.py +72 -0
  56. numdaplot/arrays/math_functions/math_function.py +58 -0
  57. numdaplot/arrays/math_functions/round.py +58 -0
  58. numdaplot/arrays/math_functions/sine.py +28 -0
  59. numdaplot/arrays/math_functions/square_root.py +27 -0
  60. numdaplot/arrays/operations/__init__.py +5 -0
  61. numdaplot/arrays/operations/boolean_operands.py +48 -0
  62. numdaplot/arrays/operations/combination.py +157 -0
  63. numdaplot/arrays/operations/float_errors.py +170 -0
  64. numdaplot/arrays/operations/integer_bounds.py +175 -0
  65. numdaplot/arrays/operations/integer_rules.py +397 -0
  66. numdaplot/arrays/operations/operand.py +139 -0
  67. numdaplot/arrays/operations/time_arithmetic.py +479 -0
  68. numdaplot/arrays/operations/time_bounds.py +286 -0
  69. numdaplot/arrays/operations/time_result_bounds.py +397 -0
  70. numdaplot/arrays/operations/transformation.py +54 -0
  71. numdaplot/arrays/operations/type_requirements.py +94 -0
  72. numdaplot/arrays/replacement.py +66 -0
  73. numdaplot/arrays/selection/__init__.py +5 -0
  74. numdaplot/arrays/selection/comparison_masks.py +131 -0
  75. numdaplot/arrays/selection/membership_masks.py +118 -0
  76. numdaplot/arrays/selection/missing_mask.py +50 -0
  77. numdaplot/arrays/selection/region_index.py +178 -0
  78. numdaplot/arrays/selection/replaced_values.py +120 -0
  79. numdaplot/arrays/selection/rule_mask.py +83 -0
  80. numdaplot/arrays/selection/time_reference.py +172 -0
  81. numdaplot/arrays/shape.py +74 -0
  82. numdaplot/arrays/type_match.py +51 -0
  83. numdaplot/data_types/__init__.py +5 -0
  84. numdaplot/data_types/library.py +57 -0
  85. numdaplot/data_types/numpy_mapping.py +207 -0
  86. numdaplot/data_types/pandas_mapping.py +114 -0
  87. numdaplot/data_types/time_of_day.py +292 -0
  88. numdaplot/data_types/type.py +224 -0
  89. numdaplot/data_types/value_family.py +149 -0
  90. numdaplot/data_types/value_type.py +147 -0
  91. numdaplot/dates/__init__.py +5 -0
  92. numdaplot/dates/custom_date_format.py +83 -0
  93. numdaplot/dates/date_format.py +120 -0
  94. numdaplot/dates/date_part.py +59 -0
  95. numdaplot/dates/date_part_unit.py +153 -0
  96. numdaplot/dates/date_period.py +57 -0
  97. numdaplot/dates/duration_in.py +58 -0
  98. numdaplot/dates/duration_unit.py +90 -0
  99. numdaplot/dates/period_unit.py +101 -0
  100. numdaplot/dates/time_function.py +56 -0
  101. numdaplot/dates/time_zone.py +68 -0
  102. numdaplot/dates/time_zone_change.py +71 -0
  103. numdaplot/dates/time_zone_mode.py +81 -0
  104. numdaplot/dates/to_duration.py +58 -0
  105. numdaplot/errors/__init__.py +7 -0
  106. numdaplot/errors/broadcast_warning.py +36 -0
  107. numdaplot/errors/calculation_warning.py +35 -0
  108. numdaplot/errors/cell_out_of_range_error.py +77 -0
  109. numdaplot/errors/column_not_found_error.py +64 -0
  110. numdaplot/errors/conflicting_settings_error.py +60 -0
  111. numdaplot/errors/dimension_error.py +62 -0
  112. numdaplot/errors/display_warning.py +32 -0
  113. numdaplot/errors/duplicate_column_error.py +82 -0
  114. numdaplot/errors/duplicate_label_error.py +55 -0
  115. numdaplot/errors/duplicate_statistic_error.py +55 -0
  116. numdaplot/errors/duplicate_value_error.py +54 -0
  117. numdaplot/errors/empty_array_error.py +55 -0
  118. numdaplot/errors/empty_list_error.py +52 -0
  119. numdaplot/errors/empty_region_error.py +34 -0
  120. numdaplot/errors/empty_text_error.py +34 -0
  121. numdaplot/errors/empty_total_error.py +62 -0
  122. numdaplot/errors/empty_values_error.py +34 -0
  123. numdaplot/errors/file_access_error.py +70 -0
  124. numdaplot/errors/file_exists_error.py +62 -0
  125. numdaplot/errors/file_not_found_error.py +56 -0
  126. numdaplot/errors/incompatible_charts_error.py +80 -0
  127. numdaplot/errors/incompatible_types_error.py +104 -0
  128. numdaplot/errors/integer_overflow_error.py +61 -0
  129. numdaplot/errors/invalid_base_error.py +52 -0
  130. numdaplot/errors/invalid_bin_width_error.py +66 -0
  131. numdaplot/errors/invalid_bounds_error.py +58 -0
  132. numdaplot/errors/invalid_chart_data_error.py +81 -0
  133. numdaplot/errors/invalid_color_count_error.py +63 -0
  134. numdaplot/errors/invalid_color_error.py +51 -0
  135. numdaplot/errors/invalid_column_name_error.py +52 -0
  136. numdaplot/errors/invalid_conversion_error.py +119 -0
  137. numdaplot/errors/invalid_count_error.py +61 -0
  138. numdaplot/errors/invalid_date_format_error.py +51 -0
  139. numdaplot/errors/invalid_deviation_error.py +52 -0
  140. numdaplot/errors/invalid_fraction_error.py +51 -0
  141. numdaplot/errors/invalid_label_count_error.py +61 -0
  142. numdaplot/errors/invalid_limits_error.py +111 -0
  143. numdaplot/errors/invalid_opacity_error.py +52 -0
  144. numdaplot/errors/invalid_point_size_error.py +52 -0
  145. numdaplot/errors/invalid_position_error.py +106 -0
  146. numdaplot/errors/invalid_resolution_error.py +51 -0
  147. numdaplot/errors/invalid_rotation_error.py +53 -0
  148. numdaplot/errors/invalid_seed_error.py +53 -0
  149. numdaplot/errors/invalid_separator_error.py +52 -0
  150. numdaplot/errors/invalid_shape_error.py +52 -0
  151. numdaplot/errors/invalid_sheet_name_error.py +54 -0
  152. numdaplot/errors/invalid_size_error.py +58 -0
  153. numdaplot/errors/invalid_step_error.py +77 -0
  154. numdaplot/errors/invalid_suffixes_error.py +61 -0
  155. numdaplot/errors/invalid_time_zone_change_error.py +63 -0
  156. numdaplot/errors/invalid_type_error.py +79 -0
  157. numdaplot/errors/irregular_list_error.py +36 -0
  158. numdaplot/errors/join_relation_error.py +183 -0
  159. numdaplot/errors/missing_dependency_error.py +58 -0
  160. numdaplot/errors/missing_type_error.py +36 -0
  161. numdaplot/errors/missing_value_error.py +62 -0
  162. numdaplot/errors/not_single_value_error.py +53 -0
  163. numdaplot/errors/numdaplot_error.py +25 -0
  164. numdaplot/errors/numdaplot_warning.py +34 -0
  165. numdaplot/errors/occupied_cell_error.py +63 -0
  166. numdaplot/errors/out_of_domain_error.py +70 -0
  167. numdaplot/errors/readability_warning.py +35 -0
  168. numdaplot/errors/refused_operation_error.py +64 -0
  169. numdaplot/errors/refused_setting_error.py +60 -0
  170. numdaplot/errors/rejected_dates.py +60 -0
  171. numdaplot/errors/repeated_key.py +36 -0
  172. numdaplot/errors/shape_mismatch_error.py +67 -0
  173. numdaplot/errors/time_overflow_error.py +131 -0
  174. numdaplot/errors/time_zone_mismatch_error.py +83 -0
  175. numdaplot/errors/unknown_time_zone_error.py +51 -0
  176. numdaplot/errors/unmatched_value_error.py +81 -0
  177. numdaplot/errors/unsupported_image_format_error.py +56 -0
  178. numdaplot/errors/unsupported_index_error.py +38 -0
  179. numdaplot/errors/unsupported_missing_error.py +129 -0
  180. numdaplot/errors/unsupported_type_error.py +62 -0
  181. numdaplot/errors/value_conversion_error.py +215 -0
  182. numdaplot/ordering/__init__.py +5 -0
  183. numdaplot/ordering/missing_position.py +46 -0
  184. numdaplot/ordering/order.py +46 -0
  185. numdaplot/package_version.py +36 -0
  186. numdaplot/plots/__init__.py +5 -0
  187. numdaplot/plots/chart_layer.py +47 -0
  188. numdaplot/plots/charts/__init__.py +5 -0
  189. numdaplot/plots/charts/bar_chart.py +98 -0
  190. numdaplot/plots/charts/bar_layout.py +58 -0
  191. numdaplot/plots/charts/bin_count.py +61 -0
  192. numdaplot/plots/charts/bin_width.py +78 -0
  193. numdaplot/plots/charts/box_chart.py +97 -0
  194. numdaplot/plots/charts/cell_values.py +61 -0
  195. numdaplot/plots/charts/chart.py +59 -0
  196. numdaplot/plots/charts/chart_settings.py +105 -0
  197. numdaplot/plots/charts/color_scale.py +147 -0
  198. numdaplot/plots/charts/heatmap_chart.py +92 -0
  199. numdaplot/plots/charts/histogram_chart.py +93 -0
  200. numdaplot/plots/charts/line_chart.py +100 -0
  201. numdaplot/plots/charts/line_type.py +75 -0
  202. numdaplot/plots/charts/marker_shape.py +113 -0
  203. numdaplot/plots/charts/missing_chart.py +60 -0
  204. numdaplot/plots/charts/missing_map_chart.py +27 -0
  205. numdaplot/plots/charts/orientation.py +58 -0
  206. numdaplot/plots/charts/outliers.py +49 -0
  207. numdaplot/plots/charts/percentages.py +55 -0
  208. numdaplot/plots/charts/pie_chart.py +87 -0
  209. numdaplot/plots/charts/scatter_chart.py +159 -0
  210. numdaplot/plots/charts/value_axis.py +66 -0
  211. numdaplot/plots/data/__init__.py +5 -0
  212. numdaplot/plots/data/array_values.py +128 -0
  213. numdaplot/plots/data/chart_data.py +143 -0
  214. numdaplot/plots/data/chart_values.py +109 -0
  215. numdaplot/plots/data/column_reading.py +468 -0
  216. numdaplot/plots/data/heatmap_values.py +63 -0
  217. numdaplot/plots/data/missing_cells.py +165 -0
  218. numdaplot/plots/data/pie_values.py +215 -0
  219. numdaplot/plots/data/point_values.py +249 -0
  220. numdaplot/plots/data/position_kind.py +83 -0
  221. numdaplot/plots/data/renamed_layers.py +340 -0
  222. numdaplot/plots/data/sample_values.py +160 -0
  223. numdaplot/plots/data/shown_columns.py +248 -0
  224. numdaplot/plots/data/table_values.py +256 -0
  225. numdaplot/plots/data/unique_labels.py +45 -0
  226. numdaplot/plots/drawing/__init__.py +5 -0
  227. numdaplot/plots/drawing/bar_drawing.py +316 -0
  228. numdaplot/plots/drawing/box_drawing.py +344 -0
  229. numdaplot/plots/drawing/cell_merging.py +237 -0
  230. numdaplot/plots/drawing/chart_texts.py +124 -0
  231. numdaplot/plots/drawing/color_bar.py +57 -0
  232. numdaplot/plots/drawing/color_scale_values.py +120 -0
  233. numdaplot/plots/drawing/default_labels.py +41 -0
  234. numdaplot/plots/drawing/drawn_chart.py +50 -0
  235. numdaplot/plots/drawing/grid_axes.py +75 -0
  236. numdaplot/plots/drawing/heatmap_drawing.py +313 -0
  237. numdaplot/plots/drawing/histogram_drawing.py +350 -0
  238. numdaplot/plots/drawing/label_room.py +344 -0
  239. numdaplot/plots/drawing/label_thinning.py +216 -0
  240. numdaplot/plots/drawing/layer_alignment.py +319 -0
  241. numdaplot/plots/drawing/layer_colors.py +123 -0
  242. numdaplot/plots/drawing/line_drawing.py +85 -0
  243. numdaplot/plots/drawing/marker_codes.py +20 -0
  244. numdaplot/plots/drawing/missing_drawing.py +360 -0
  245. numdaplot/plots/drawing/moment_period_formatter.py +253 -0
  246. numdaplot/plots/drawing/pie_drawing.py +185 -0
  247. numdaplot/plots/drawing/plot_axes.py +38 -0
  248. numdaplot/plots/drawing/plot_drawing.py +288 -0
  249. numdaplot/plots/drawing/plot_theme.py +45 -0
  250. numdaplot/plots/drawing/position_axis.py +278 -0
  251. numdaplot/plots/drawing/scatter_drawing.py +364 -0
  252. numdaplot/plots/drawing/series_colors.py +177 -0
  253. numdaplot/plots/drawing/size_inches.py +45 -0
  254. numdaplot/plots/drawing/style_drawing.py +410 -0
  255. numdaplot/plots/drawing/text_contrast.py +44 -0
  256. numdaplot/plots/drawing/tick_rotation.py +354 -0
  257. numdaplot/plots/drawing/time_axis.py +212 -0
  258. numdaplot/plots/drawing/whole_numbers.py +72 -0
  259. numdaplot/plots/figure/__init__.py +5 -0
  260. numdaplot/plots/figure/cell.py +95 -0
  261. numdaplot/plots/figure/figure.py +256 -0
  262. numdaplot/plots/figure/figure_drawing.py +99 -0
  263. numdaplot/plots/figure/figure_style.py +60 -0
  264. numdaplot/plots/figure/layout.py +71 -0
  265. numdaplot/plots/figure/placement.py +150 -0
  266. numdaplot/plots/layer_reading.py +166 -0
  267. numdaplot/plots/output/__init__.py +5 -0
  268. numdaplot/plots/output/image_saving.py +187 -0
  269. numdaplot/plots/output/plot_display.py +181 -0
  270. numdaplot/plots/output/shown_object.py +45 -0
  271. numdaplot/plots/overlay_checks.py +245 -0
  272. numdaplot/plots/plot.py +31 -0
  273. numdaplot/plots/plot_data.py +140 -0
  274. numdaplot/plots/plot_distribution_creation.py +237 -0
  275. numdaplot/plots/plot_output.py +124 -0
  276. numdaplot/plots/plot_overlays.py +273 -0
  277. numdaplot/plots/plot_overview_creation.py +195 -0
  278. numdaplot/plots/plot_series_creation.py +213 -0
  279. numdaplot/plots/style/__init__.py +5 -0
  280. numdaplot/plots/style/axis_settings.py +60 -0
  281. numdaplot/plots/style/color.py +168 -0
  282. numdaplot/plots/style/custom_color.py +65 -0
  283. numdaplot/plots/style/grid_lines.py +49 -0
  284. numdaplot/plots/style/image_options.py +71 -0
  285. numdaplot/plots/style/legend_position.py +149 -0
  286. numdaplot/plots/style/plot_style.py +136 -0
  287. numdaplot/plots/style/size.py +70 -0
  288. numdaplot/plots/style/size_unit.py +62 -0
  289. numdaplot/positions/__init__.py +5 -0
  290. numdaplot/positions/axis.py +54 -0
  291. numdaplot/positions/index.py +51 -0
  292. numdaplot/positions/range.py +90 -0
  293. numdaplot/positions/region.py +92 -0
  294. numdaplot/py.typed +0 -0
  295. numdaplot/ratios/__init__.py +5 -0
  296. numdaplot/ratios/fraction.py +40 -0
  297. numdaplot/ratios/measure.py +48 -0
  298. numdaplot/rules/__init__.py +5 -0
  299. numdaplot/rules/between.py +78 -0
  300. numdaplot/rules/bounds.py +83 -0
  301. numdaplot/rules/case.py +48 -0
  302. numdaplot/rules/contains.py +63 -0
  303. numdaplot/rules/equal.py +43 -0
  304. numdaplot/rules/greater.py +39 -0
  305. numdaplot/rules/greater_or_equal.py +38 -0
  306. numdaplot/rules/is_in.py +67 -0
  307. numdaplot/rules/is_missing.py +25 -0
  308. numdaplot/rules/is_present.py +25 -0
  309. numdaplot/rules/less.py +39 -0
  310. numdaplot/rules/less_or_equal.py +38 -0
  311. numdaplot/rules/not_equal.py +45 -0
  312. numdaplot/rules/rule.py +62 -0
  313. numdaplot/rules/rule_values.py +44 -0
  314. numdaplot/rules/value_rule.py +110 -0
  315. numdaplot/settings/__init__.py +5 -0
  316. numdaplot/settings/argument_types.py +327 -0
  317. numdaplot/settings/field_types.py +593 -0
  318. numdaplot/statistics/__init__.py +5 -0
  319. numdaplot/statistics/count.py +71 -0
  320. numdaplot/statistics/count_distinct.py +27 -0
  321. numdaplot/statistics/counted_missing.py +46 -0
  322. numdaplot/statistics/maximum.py +27 -0
  323. numdaplot/statistics/mean.py +27 -0
  324. numdaplot/statistics/median.py +27 -0
  325. numdaplot/statistics/minimum.py +27 -0
  326. numdaplot/statistics/most_frequent.py +27 -0
  327. numdaplot/statistics/most_frequent_count.py +27 -0
  328. numdaplot/statistics/quantile.py +61 -0
  329. numdaplot/statistics/standard_deviation.py +29 -0
  330. numdaplot/statistics/statistic.py +63 -0
  331. numdaplot/statistics/sum.py +27 -0
  332. numdaplot/tables/__init__.py +5 -0
  333. numdaplot/tables/aggregation/__init__.py +5 -0
  334. numdaplot/tables/aggregation/aggregated_frame.py +189 -0
  335. numdaplot/tables/aggregation/aggregation.py +97 -0
  336. numdaplot/tables/aggregation/calculation.py +123 -0
  337. numdaplot/tables/aggregation/result_column.py +108 -0
  338. numdaplot/tables/aggregation/row_groups.py +96 -0
  339. numdaplot/tables/aggregation/statistic_name.py +122 -0
  340. numdaplot/tables/columns/__init__.py +5 -0
  341. numdaplot/tables/columns/added_column.py +89 -0
  342. numdaplot/tables/columns/boolean_conversion.py +144 -0
  343. numdaplot/tables/columns/boolean_rule.py +59 -0
  344. numdaplot/tables/columns/bracket_end.py +50 -0
  345. numdaplot/tables/columns/bracket_names.py +346 -0
  346. numdaplot/tables/columns/bracketed_column.py +179 -0
  347. numdaplot/tables/columns/brackets.py +234 -0
  348. numdaplot/tables/columns/chosen_columns.py +55 -0
  349. numdaplot/tables/columns/column_choice.py +84 -0
  350. numdaplot/tables/columns/column_mode.py +64 -0
  351. numdaplot/tables/columns/column_names.py +186 -0
  352. numdaplot/tables/columns/conversion.py +103 -0
  353. numdaplot/tables/columns/converted_column.py +669 -0
  354. numdaplot/tables/columns/date_conversion.py +526 -0
  355. numdaplot/tables/columns/date_range.py +135 -0
  356. numdaplot/tables/columns/name_change.py +67 -0
  357. numdaplot/tables/columns/new_column.py +79 -0
  358. numdaplot/tables/columns/number_conversion.py +281 -0
  359. numdaplot/tables/columns/renamed_columns.py +60 -0
  360. numdaplot/tables/columns/renaming.py +81 -0
  361. numdaplot/tables/columns/text_conversion.py +70 -0
  362. numdaplot/tables/columns/time_conversion.py +313 -0
  363. numdaplot/tables/columns/time_zone_conversion.py +128 -0
  364. numdaplot/tables/conflict.py +68 -0
  365. numdaplot/tables/description/__init__.py +5 -0
  366. numdaplot/tables/description/described_frame.py +335 -0
  367. numdaplot/tables/description/description.py +155 -0
  368. numdaplot/tables/duplicates/__init__.py +5 -0
  369. numdaplot/tables/duplicates/deduplicated_frame.py +66 -0
  370. numdaplot/tables/duplicates/deduplication.py +88 -0
  371. numdaplot/tables/duplicates/keep.py +81 -0
  372. numdaplot/tables/files/__init__.py +5 -0
  373. numdaplot/tables/files/column_names.py +60 -0
  374. numdaplot/tables/files/csv_file.py +265 -0
  375. numdaplot/tables/files/csv_read_options.py +89 -0
  376. numdaplot/tables/files/csv_separator.py +41 -0
  377. numdaplot/tables/files/csv_write_options.py +79 -0
  378. numdaplot/tables/files/decimal_count.py +42 -0
  379. numdaplot/tables/files/encoding.py +82 -0
  380. numdaplot/tables/files/excel_file.py +171 -0
  381. numdaplot/tables/files/excel_read_options.py +79 -0
  382. numdaplot/tables/files/excel_sheet.py +50 -0
  383. numdaplot/tables/files/excel_time_cells.py +146 -0
  384. numdaplot/tables/files/excel_write_options.py +63 -0
  385. numdaplot/tables/files/file_access.py +152 -0
  386. numdaplot/tables/files/file_paths.py +106 -0
  387. numdaplot/tables/files/json_decimals.py +387 -0
  388. numdaplot/tables/files/json_file.py +203 -0
  389. numdaplot/tables/files/json_layout.py +63 -0
  390. numdaplot/tables/files/json_read_options.py +64 -0
  391. numdaplot/tables/files/json_write_options.py +71 -0
  392. numdaplot/tables/files/missing_texts.py +63 -0
  393. numdaplot/tables/files/optional_package.py +42 -0
  394. numdaplot/tables/files/pandas_backend.py +11 -0
  395. numdaplot/tables/files/parquet_file.py +91 -0
  396. numdaplot/tables/files/parquet_read_options.py +56 -0
  397. numdaplot/tables/files/sas_file.py +94 -0
  398. numdaplot/tables/files/sas_read_options.py +67 -0
  399. numdaplot/tables/files/stata_file.py +83 -0
  400. numdaplot/tables/files/stata_read_options.py +56 -0
  401. numdaplot/tables/files/xpt_read_options.py +65 -0
  402. numdaplot/tables/filtering/__init__.py +5 -0
  403. numdaplot/tables/filtering/checked_frame.py +60 -0
  404. numdaplot/tables/filtering/column_mask.py +71 -0
  405. numdaplot/tables/filtering/column_match.py +62 -0
  406. numdaplot/tables/filtering/condition.py +94 -0
  407. numdaplot/tables/filtering/filter.py +74 -0
  408. numdaplot/tables/filtering/filter_mode.py +67 -0
  409. numdaplot/tables/filtering/row_mask.py +152 -0
  410. numdaplot/tables/filtering/rule_moments.py +164 -0
  411. numdaplot/tables/frames/__init__.py +5 -0
  412. numdaplot/tables/frames/array_frame.py +95 -0
  413. numdaplot/tables/frames/cleaned_names.py +132 -0
  414. numdaplot/tables/frames/column.py +15 -0
  415. numdaplot/tables/frames/column_values.py +273 -0
  416. numdaplot/tables/frames/frame_equality.py +130 -0
  417. numdaplot/tables/frames/frame_normalization.py +459 -0
  418. numdaplot/tables/frames/named_column_errors.py +85 -0
  419. numdaplot/tables/frames/pandas_decimals.py +113 -0
  420. numdaplot/tables/frames/region_positions.py +113 -0
  421. numdaplot/tables/frames/table_text.py +222 -0
  422. numdaplot/tables/frames/time_columns.py +345 -0
  423. numdaplot/tables/frames/time_range_errors.py +117 -0
  424. numdaplot/tables/frames/time_zones.py +271 -0
  425. numdaplot/tables/joining/__init__.py +5 -0
  426. numdaplot/tables/joining/join.py +110 -0
  427. numdaplot/tables/joining/join_keys.py +367 -0
  428. numdaplot/tables/joining/join_mode.py +93 -0
  429. numdaplot/tables/joining/join_relation.py +149 -0
  430. numdaplot/tables/joining/join_suffixes.py +71 -0
  431. numdaplot/tables/joining/joined_frame.py +166 -0
  432. numdaplot/tables/joining/joined_names.py +107 -0
  433. numdaplot/tables/joining/joined_rows.py +235 -0
  434. numdaplot/tables/joining/key_types.py +57 -0
  435. numdaplot/tables/joining/relation.py +78 -0
  436. numdaplot/tables/missing/__init__.py +5 -0
  437. numdaplot/tables/missing/missing_count.py +59 -0
  438. numdaplot/tables/missing/missing_counts.py +214 -0
  439. numdaplot/tables/missing/missing_drop.py +98 -0
  440. numdaplot/tables/missing/missing_mode.py +63 -0
  441. numdaplot/tables/missing/missing_ratio.py +71 -0
  442. numdaplot/tables/missing/missing_removal.py +257 -0
  443. numdaplot/tables/missing/missing_summary.py +174 -0
  444. numdaplot/tables/missing/ratio_comparison.py +70 -0
  445. numdaplot/tables/pivot/__init__.py +5 -0
  446. numdaplot/tables/pivot/pivot_table.py +104 -0
  447. numdaplot/tables/pivot/pivoted_frame.py +244 -0
  448. numdaplot/tables/preview/__init__.py +5 -0
  449. numdaplot/tables/preview/notebook_display.py +238 -0
  450. numdaplot/tables/preview/preview.py +100 -0
  451. numdaplot/tables/preview/preview_rows.py +55 -0
  452. numdaplot/tables/preview/shown_columns.py +62 -0
  453. numdaplot/tables/preview/side.py +82 -0
  454. numdaplot/tables/sorting/__init__.py +5 -0
  455. numdaplot/tables/sorting/sort_key.py +71 -0
  456. numdaplot/tables/sorting/sorted_frame.py +81 -0
  457. numdaplot/tables/sorting/sorting.py +82 -0
  458. numdaplot/tables/table.py +71 -0
  459. numdaplot/tables/table_calculation.py +172 -0
  460. numdaplot/tables/table_columns.py +214 -0
  461. numdaplot/tables/table_conversion.py +351 -0
  462. numdaplot/tables/table_data.py +321 -0
  463. numdaplot/tables/table_display.py +56 -0
  464. numdaplot/tables/table_joining.py +80 -0
  465. numdaplot/tables/table_layout.py +105 -0
  466. numdaplot/tables/table_missing.py +146 -0
  467. numdaplot/tables/table_reading.py +451 -0
  468. numdaplot/tables/table_refusals.py +295 -0
  469. numdaplot/tables/table_selection.py +163 -0
  470. numdaplot/tables/table_writing.py +269 -0
  471. numdaplot-0.1.0.dist-info/METADATA +176 -0
  472. numdaplot-0.1.0.dist-info/RECORD +474 -0
  473. numdaplot-0.1.0.dist-info/WHEEL +4 -0
  474. numdaplot-0.1.0.dist-info/licenses/LICENSE +28 -0
@@ -0,0 +1,81 @@
1
+ """
2
+ Which row of a group of duplicated rows is kept.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from enum import Enum, auto
8
+
9
+
10
+ class Keep(Enum):
11
+ """
12
+ Which row of a group of duplicated rows is kept, used by ``Deduplication``.
13
+
14
+ .. versionadded:: 0.1.0
15
+
16
+ Examples
17
+ --------
18
+ >>> import numdaplot as ndp
19
+ >>> cities = ndp.Array.from_list(["Paris", "Lyon", "Paris"])
20
+ >>> prices = ndp.Array.from_list([120.0, 80.0, 150.0])
21
+ >>> sales = ndp.Table.from_arrays({"city": cities, "price": prices})
22
+ >>> sales.drop_duplicates(ndp.Deduplication(columns=["city"], keep=ndp.Keep.LAST))
23
+ city price
24
+ TEXT FLOAT64
25
+ 0 Lyon 80.0
26
+ 1 Paris 150.0
27
+ >>> sales.drop_duplicates(ndp.Deduplication(columns=["city"], keep=ndp.Keep.NONE))
28
+ city price
29
+ TEXT FLOAT64
30
+ 0 Lyon 80.0
31
+ """
32
+
33
+ FIRST = auto()
34
+ """
35
+ The first row of each group is kept. Default value.
36
+
37
+ Examples
38
+ --------
39
+ >>> import numdaplot as ndp
40
+ >>> cities = ndp.Array.from_list(["Paris", "Lyon", "Paris"])
41
+ >>> prices = ndp.Array.from_list([120.0, 80.0, 150.0])
42
+ >>> sales = ndp.Table.from_arrays({"city": cities, "price": prices})
43
+ >>> sales.drop_duplicates(ndp.Deduplication(columns=["city"], keep=ndp.Keep.FIRST))
44
+ city price
45
+ TEXT FLOAT64
46
+ 0 Paris 120.0
47
+ 1 Lyon 80.0
48
+ """
49
+
50
+ LAST = auto()
51
+ """
52
+ The last row of each group is kept.
53
+
54
+ Examples
55
+ --------
56
+ >>> import numdaplot as ndp
57
+ >>> cities = ndp.Array.from_list(["Paris", "Lyon", "Paris"])
58
+ >>> prices = ndp.Array.from_list([120.0, 80.0, 150.0])
59
+ >>> sales = ndp.Table.from_arrays({"city": cities, "price": prices})
60
+ >>> sales.drop_duplicates(ndp.Deduplication(columns=["city"], keep=ndp.Keep.LAST))
61
+ city price
62
+ TEXT FLOAT64
63
+ 0 Lyon 80.0
64
+ 1 Paris 150.0
65
+ """
66
+
67
+ NONE = auto()
68
+ """
69
+ No row of a duplicated group is kept, only rows that appear once remain.
70
+
71
+ Examples
72
+ --------
73
+ >>> import numdaplot as ndp
74
+ >>> cities = ndp.Array.from_list(["Paris", "Lyon", "Paris"])
75
+ >>> prices = ndp.Array.from_list([120.0, 80.0, 150.0])
76
+ >>> sales = ndp.Table.from_arrays({"city": cities, "price": prices})
77
+ >>> sales.drop_duplicates(ndp.Deduplication(columns=["city"], keep=ndp.Keep.NONE))
78
+ city price
79
+ TEXT FLOAT64
80
+ 0 Lyon 80.0
81
+ """
@@ -0,0 +1,5 @@
1
+ """
2
+ Reading and writing Tables in files: CSV, JSON, Excel, Parquet, Stata, SAS and XPT.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
@@ -0,0 +1,60 @@
1
+ r"""
2
+ Whether a Table cleans the column names it reads.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from enum import Enum, auto
8
+
9
+
10
+ class ColumnNames(Enum):
11
+ r"""
12
+ Whether the column names read from a file or a pandas DataFrame are cleaned.
13
+
14
+ Cleaning removes what ``str.strip`` removes at the start and the end of each name: spaces, tabs, line breaks and
15
+ non-breaking spaces. The inside of a name is never changed.
16
+
17
+ .. versionadded:: 0.1.0
18
+
19
+ Examples
20
+ --------
21
+ >>> import tempfile
22
+ >>> from pathlib import Path
23
+ >>> import numdaplot as ndp
24
+ >>> path = Path(tempfile.mkdtemp()) / "vehicles.csv"
25
+ >>> _ = path.write_text('"id_vehicule\n";speed\n1;50\n')
26
+ >>> ndp.Table.from_csv(path, ndp.CsvReadOptions(separator=";")).column_names
27
+ ['id_vehicule', 'speed']
28
+ """
29
+
30
+ CLEANED = auto()
31
+ r"""
32
+ The spaces, tabs and line breaks at the start and the end of each name are removed. Default value.
33
+
34
+ Examples
35
+ --------
36
+ >>> import tempfile
37
+ >>> from pathlib import Path
38
+ >>> import numdaplot as ndp
39
+ >>> path = Path(tempfile.mkdtemp()) / "vehicles.csv"
40
+ >>> _ = path.write_text('" id_vehicule\n";speed\n1;50\n')
41
+ >>> options = ndp.CsvReadOptions(separator=";", column_names=ndp.ColumnNames.CLEANED)
42
+ >>> ndp.Table.from_csv(path, options).column_names
43
+ ['id_vehicule', 'speed']
44
+ """
45
+
46
+ KEPT = auto()
47
+ r"""
48
+ Each name is kept as written.
49
+
50
+ Examples
51
+ --------
52
+ >>> import tempfile
53
+ >>> from pathlib import Path
54
+ >>> import numdaplot as ndp
55
+ >>> path = Path(tempfile.mkdtemp()) / "vehicles.csv"
56
+ >>> _ = path.write_text('" id_vehicule\n";speed\n1;50\n')
57
+ >>> options = ndp.CsvReadOptions(separator=";", column_names=ndp.ColumnNames.KEPT)
58
+ >>> ndp.Table.from_csv(path, options).column_names
59
+ [' id_vehicule\n', 'speed']
60
+ """
@@ -0,0 +1,265 @@
1
+ """
2
+ Reading and writing CSV files.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ import csv
8
+ import warnings
9
+ from pathlib import Path
10
+ from typing import Any, cast
11
+
12
+ import pandas
13
+ from pandas.api.types import infer_dtype
14
+
15
+ from numdaplot.tables.columns.column_names import require_column_names
16
+ from numdaplot.tables.files.csv_read_options import CsvReadOptions
17
+ from numdaplot.tables.files.csv_write_options import CsvWriteOptions
18
+ from numdaplot.tables.files.missing_texts import find_missing_settings
19
+ from numdaplot.tables.files.pandas_backend import NULLABLE_DTYPE_BACKEND
20
+ from numdaplot.tables.frames.frame_normalization import PYTHON_OBJECT_DTYPE
21
+ from numdaplot.tables.frames.pandas_decimals import find_exact_csv_settings
22
+
23
+ CSV_NEWLINE = ""
24
+ DECIMAL_FORMAT = "%.{decimals}f"
25
+ IGNORE_ACTION = "ignore"
26
+ # The kinds pandas infers for a column whose blocks were read as numbers or booleans in one place and texts in another.
27
+ MIXED_BLOCK_KINDS = frozenset({"mixed", "mixed-integer"})
28
+ TEXT_COLUMNS_SETTING = "usecols"
29
+ TEXT_DTYPE_SETTING = "dtype"
30
+
31
+
32
+ def read_csv_file(path: Path, options: CsvReadOptions) -> pandas.DataFrame:
33
+ r"""
34
+ Return the columns of a CSV file whose first row holds the column names, with the exact value of each decimal.
35
+
36
+ pandas reads a long file in blocks, each block guessing its own types. A column whose blocks get different types,
37
+ such as numbers then texts, is read again as texts, so every value keeps the text of the file, such as ``01``.
38
+
39
+ .. versionadded:: 0.1.0
40
+
41
+ Parameters
42
+ ----------
43
+ path
44
+ The path of an existing CSV file.
45
+ options
46
+ The separator and the encoding of the file.
47
+
48
+ Returns
49
+ -------
50
+ pandas.DataFrame
51
+ The columns as pandas reads them, empty for an empty file.
52
+
53
+ Raises
54
+ ------
55
+ InvalidColumnNameError
56
+ When a column name is empty.
57
+ DuplicateColumnError
58
+ When a column name appears twice.
59
+
60
+ Examples
61
+ --------
62
+ >>> import tempfile
63
+ >>> from pathlib import Path
64
+ >>> import numdaplot as ndp
65
+ >>> from numdaplot.tables.files.csv_file import read_csv_file
66
+ >>> folder = Path(tempfile.mkdtemp())
67
+ >>> path = folder / "sales.csv"
68
+ >>> _ = path.write_text("city;price\nParis;1.5\n")
69
+ >>> read_csv_file(path, ndp.CsvReadOptions(separator=";"))
70
+ city price
71
+ 0 Paris 1.5
72
+ """
73
+ header = read_csv_header(path, options)
74
+ if header is None:
75
+ empty_frame = pandas.DataFrame()
76
+ return empty_frame
77
+
78
+ require_column_names(header)
79
+ block_frame = read_pandas_csv(path, options, {})
80
+ mixed_names = find_mixed_columns(block_frame)
81
+ if mixed_names == []:
82
+ return block_frame
83
+
84
+ text_settings = {TEXT_COLUMNS_SETTING: mixed_names, TEXT_DTYPE_SETTING: str}
85
+ text_frame = read_pandas_csv(path, options, text_settings)
86
+ text_columns = {name: text_frame[name] for name in mixed_names}
87
+ frame = block_frame.assign(**text_columns)
88
+
89
+ return frame
90
+
91
+
92
+ def read_pandas_csv(path: Path, options: CsvReadOptions, column_settings: dict[str, Any]) -> pandas.DataFrame:
93
+ r"""
94
+ Return the columns of a CSV file as ``pandas.read_csv`` reads them in blocks, with the exact value of each decimal.
95
+
96
+ The ``DtypeWarning`` pandas emits when the blocks of a column get different types is not shown, as
97
+ ``read_csv_file`` reads such a column again as texts.
98
+
99
+ .. versionadded:: 0.1.0
100
+
101
+ Parameters
102
+ ----------
103
+ path
104
+ The path of an existing CSV file whose first row holds the column names.
105
+ options
106
+ The separator, the encoding and the texts read as missing.
107
+ column_settings
108
+ Other settings of ``pandas.read_csv``, such as the columns to read and their dtype.
109
+
110
+ Returns
111
+ -------
112
+ pandas.DataFrame
113
+ The columns as pandas reads them.
114
+
115
+ Examples
116
+ --------
117
+ >>> import tempfile
118
+ >>> from pathlib import Path
119
+ >>> import numdaplot as ndp
120
+ >>> from numdaplot.tables.files.csv_file import read_pandas_csv
121
+ >>> path = Path(tempfile.mkdtemp()) / "codes.csv"
122
+ >>> _ = path.write_text("code;price\n01;1.5\n")
123
+ >>> read_pandas_csv(path, ndp.CsvReadOptions(separator=";"), {"usecols": ["code"], "dtype": str})
124
+ code
125
+ 0 01
126
+ """
127
+ # Some versions of the pandas stubs leave the parameter types of read_csv unknown.
128
+ csv_pandas = cast(Any, pandas)
129
+ exact_settings = find_exact_csv_settings()
130
+ missing_settings = find_missing_settings(options.missing_texts)
131
+ with warnings.catch_warnings():
132
+ warnings.simplefilter(IGNORE_ACTION, pandas.errors.DtypeWarning)
133
+ raw_frame = csv_pandas.read_csv(
134
+ path,
135
+ sep=options.separator,
136
+ encoding=options.encoding.value,
137
+ dtype_backend=NULLABLE_DTYPE_BACKEND,
138
+ **exact_settings,
139
+ **missing_settings,
140
+ **column_settings,
141
+ )
142
+
143
+ frame = cast(pandas.DataFrame, raw_frame)
144
+
145
+ return frame
146
+
147
+
148
+ def find_mixed_columns(frame: pandas.DataFrame) -> list[str]:
149
+ """
150
+ Return the names of the columns whose blocks pandas read with different types, such as numbers then texts.
151
+
152
+ A block holding only ``01`` is read as the number 1, so the text of such a column is no longer the one of the file.
153
+
154
+ .. versionadded:: 0.1.0
155
+
156
+ Parameters
157
+ ----------
158
+ frame
159
+ The columns of a CSV file as ``pandas.read_csv`` reads them in blocks.
160
+
161
+ Returns
162
+ -------
163
+ list[str]
164
+ The names of the mixed columns, in the order of the file.
165
+
166
+ Examples
167
+ --------
168
+ >>> import pandas
169
+ >>> from numdaplot.tables.files.csv_file import find_mixed_columns
170
+ >>> codes = pandas.Series([1, "2A"], dtype=object)
171
+ >>> prices = pandas.Series([1.5, 2.0])
172
+ >>> find_mixed_columns(pandas.DataFrame({"code": codes, "price": prices}))
173
+ ['code']
174
+ """
175
+ mixed_names = list[str]()
176
+ for column_name, column in frame.items():
177
+ if column.dtype != PYTHON_OBJECT_DTYPE:
178
+ continue
179
+
180
+ inferred_kind = infer_dtype(column, skipna=True)
181
+ if inferred_kind in MIXED_BLOCK_KINDS:
182
+ mixed_names.append(str(column_name))
183
+
184
+ return mixed_names
185
+
186
+
187
+ def read_csv_header(path: Path, options: CsvReadOptions) -> list[str] | None:
188
+ r"""
189
+ Return the column names written on the first row of a CSV file, before pandas renames repeated ones.
190
+
191
+ .. versionadded:: 0.1.0
192
+
193
+ Parameters
194
+ ----------
195
+ path
196
+ The path of an existing CSV file.
197
+ options
198
+ The separator and the encoding of the file.
199
+
200
+ Returns
201
+ -------
202
+ list[str] or None
203
+ The names of the first row, ``None`` for an empty file.
204
+
205
+ Examples
206
+ --------
207
+ >>> import tempfile
208
+ >>> from pathlib import Path
209
+ >>> import numdaplot as ndp
210
+ >>> from numdaplot.tables.files.csv_file import read_csv_header
211
+ >>> folder = Path(tempfile.mkdtemp())
212
+ >>> path = folder / "sales.csv"
213
+ >>> _ = path.write_text("price,price\n1,2\n")
214
+ >>> read_csv_header(path, ndp.CsvReadOptions())
215
+ ['price', 'price']
216
+ """
217
+ with path.open(encoding=options.encoding.value, newline=CSV_NEWLINE) as file:
218
+ rows = csv.reader(file, delimiter=options.separator)
219
+ header = next(rows, None)
220
+
221
+ return header
222
+
223
+
224
+ def write_csv_file(frame: pandas.DataFrame, path: Path, options: CsvWriteOptions) -> None:
225
+ """
226
+ Write the columns of a Table in a CSV file, column names on the first row and without row numbers.
227
+
228
+ Missing values are written as empty values.
229
+
230
+ .. versionadded:: 0.1.0
231
+
232
+ Parameters
233
+ ----------
234
+ frame
235
+ The columns of a Table.
236
+ path
237
+ The path of the file, replaced when it exists.
238
+ options
239
+ The separator and the encoding of the file.
240
+
241
+ Examples
242
+ --------
243
+ >>> import tempfile
244
+ >>> from pathlib import Path
245
+ >>> import pandas
246
+ >>> import numdaplot as ndp
247
+ >>> from numdaplot.tables.files.csv_file import write_csv_file
248
+ >>> path = Path(tempfile.mkdtemp()) / "sales.csv"
249
+ >>> write_csv_file(pandas.DataFrame({"price": [1.5]}), path, ndp.CsvWriteOptions())
250
+ >>> print(path.read_text())
251
+ price
252
+ 1.5
253
+ <BLANKLINE>
254
+ """
255
+ decimal_format = None
256
+ if options.decimals is not None:
257
+ decimal_format = DECIMAL_FORMAT.format(decimals=options.decimals)
258
+
259
+ frame.to_csv(
260
+ path,
261
+ sep=options.separator,
262
+ encoding=options.encoding.value,
263
+ index=False,
264
+ float_format=decimal_format,
265
+ )
@@ -0,0 +1,89 @@
1
+ """
2
+ Settings of the CSV files a Table reads.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+
9
+ from numdaplot.settings.field_types import require_field_types
10
+ from numdaplot.tables.files.column_names import ColumnNames
11
+ from numdaplot.tables.files.csv_separator import DEFAULT_SEPARATOR, require_separator
12
+ from numdaplot.tables.files.encoding import Encoding
13
+
14
+
15
+ @dataclass(frozen=True)
16
+ class CsvReadOptions:
17
+ r"""
18
+ Settings of a CSV file read by ``Table.from_csv``.
19
+
20
+ .. versionadded:: 0.1.0
21
+
22
+ Parameters
23
+ ----------
24
+ separator
25
+ The character between two values of a row, ``","`` by default.
26
+ encoding
27
+ The text encoding of the file, UTF-8 by default.
28
+ column_names
29
+ Whether the column names are cleaned, ``ColumnNames.CLEANED`` by default: the spaces, tabs and line breaks at
30
+ the start and the end of each name are removed. ``ColumnNames.KEPT`` keeps the names as written.
31
+ missing_texts
32
+ The texts read as missing values, compared with the whole value of each cell. When omitted, the texts pandas
33
+ reads as missing: ``""``, ``"#N/A"``, ``"#N/A N/A"``, ``"#NA"``, ``"-1.#IND"``, ``"-1.#QNAN"``, ``"-NaN"``,
34
+ ``"-nan"``, ``"1.#IND"``, ``"1.#QNAN"``, ``"<NA>"``, ``"N/A"``, ``"NA"``, ``"NULL"``, ``"NaN"``, ``"None"``,
35
+ ``"n/a"``, ``"nan"`` and ``"null"``. A given list replaces them: ``[]`` reads no value as missing, not even
36
+ an empty one, so a column of numbers with an empty value is read as texts.
37
+
38
+ Raises
39
+ ------
40
+ InvalidTypeError
41
+ When a setting is not of the type its annotation names.
42
+ InvalidSeparatorError
43
+ When the separator is not exactly one character.
44
+
45
+ Examples
46
+ --------
47
+ >>> import tempfile
48
+ >>> from pathlib import Path
49
+ >>> import numdaplot as ndp
50
+ >>> path = Path(tempfile.mkdtemp()) / "sales.csv"
51
+ >>> _ = path.write_text("city;price\nParis;1.5\nLyon;8.0\n")
52
+ >>> ndp.Table.from_csv(path, ndp.CsvReadOptions(separator=";"))
53
+ city price
54
+ TEXT FLOAT64
55
+ 0 Paris 1.5
56
+ 1 Lyon 8.0
57
+ >>> _ = path.write_text("city;code\nParis;N/A\nLyon;\n")
58
+ >>> ndp.Table.from_csv(path, ndp.CsvReadOptions(separator=";", missing_texts=[""]))
59
+ city code
60
+ TEXT TEXT
61
+ 0 Paris N/A
62
+ 1 Lyon <NA>
63
+ """
64
+
65
+ separator: str = DEFAULT_SEPARATOR
66
+ encoding: Encoding = Encoding.UTF_8
67
+ column_names: ColumnNames = ColumnNames.CLEANED
68
+ missing_texts: list[str] | None = None
69
+
70
+ def __post_init__(self) -> None:
71
+ """
72
+ Check the type of every setting, and that the separator is exactly one character.
73
+
74
+ .. versionadded:: 0.1.0
75
+
76
+ Raises
77
+ ------
78
+ InvalidTypeError
79
+ When a setting is not of the type its annotation names.
80
+ InvalidSeparatorError
81
+ When the separator is not exactly one character.
82
+ """
83
+ require_field_types(self)
84
+
85
+ require_separator(self.separator)
86
+
87
+ if self.missing_texts is not None:
88
+ missing_texts_copy = list(self.missing_texts)
89
+ object.__setattr__(self, "missing_texts", missing_texts_copy)
@@ -0,0 +1,41 @@
1
+ """
2
+ Check of the separator of a CSV file.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from numdaplot.errors.invalid_separator_error import InvalidSeparatorError
8
+
9
+ DEFAULT_SEPARATOR = ","
10
+ SEPARATOR_LENGTH = 1
11
+
12
+
13
+ def require_separator(separator: str) -> None:
14
+ """
15
+ Check that the separator of a CSV file is exactly one character.
16
+
17
+ .. versionadded:: 0.1.0
18
+
19
+ Parameters
20
+ ----------
21
+ separator
22
+ The character between two values of a row.
23
+
24
+ Raises
25
+ ------
26
+ InvalidSeparatorError
27
+ When the separator is empty or longer than one character.
28
+
29
+ Examples
30
+ --------
31
+ >>> import numdaplot as ndp
32
+ >>> from numdaplot.tables.files.csv_separator import require_separator
33
+ >>> try:
34
+ ... require_separator(";;")
35
+ ... except ndp.InvalidSeparatorError as error:
36
+ ... print(error)
37
+ Expected a separator of exactly one character, got ';;'.
38
+ """
39
+ separator_length = len(separator)
40
+ if separator_length != SEPARATOR_LENGTH:
41
+ raise InvalidSeparatorError(separator)
@@ -0,0 +1,79 @@
1
+ """
2
+ Settings of the CSV files a Table writes.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+
9
+ from numdaplot.settings.field_types import require_field_types
10
+ from numdaplot.tables.files.csv_separator import DEFAULT_SEPARATOR, require_separator
11
+ from numdaplot.tables.files.decimal_count import require_decimal_count
12
+ from numdaplot.tables.files.encoding import Encoding
13
+
14
+
15
+ @dataclass(frozen=True)
16
+ class CsvWriteOptions:
17
+ """
18
+ Settings of a CSV file written by ``Table.to_csv``.
19
+
20
+ .. versionadded:: 0.1.0
21
+
22
+ Parameters
23
+ ----------
24
+ separator
25
+ The character between two values of a row, ``","`` by default.
26
+ encoding
27
+ The text encoding of the file, UTF-8 by default.
28
+ decimals
29
+ The number of decimals written for every decimal column, 0 or more. Each value is rounded and keeps its
30
+ zeros, such as ``1.50``, so the file no longer holds the exact values. When omitted, a decimal is written
31
+ with every digit of its value.
32
+
33
+ Raises
34
+ ------
35
+ InvalidTypeError
36
+ When a setting is not of the type its annotation names.
37
+ InvalidSeparatorError
38
+ When the separator is not exactly one character.
39
+ InvalidCountError
40
+ When ``decimals`` is negative.
41
+
42
+ Examples
43
+ --------
44
+ >>> import tempfile
45
+ >>> from pathlib import Path
46
+ >>> import numdaplot as ndp
47
+ >>> path = Path(tempfile.mkdtemp()) / "sales.csv"
48
+ >>> prices = ndp.Table.from_arrays({"price": ndp.Array.from_list([1.5, 8.0])})
49
+ >>> prices.to_csv(path, ndp.CsvWriteOptions(separator=";", decimals=2))
50
+ >>> print(path.read_text())
51
+ price
52
+ 1.50
53
+ 8.00
54
+ <BLANKLINE>
55
+ """
56
+
57
+ separator: str = DEFAULT_SEPARATOR
58
+ encoding: Encoding = Encoding.UTF_8
59
+ decimals: int | None = None
60
+
61
+ def __post_init__(self) -> None:
62
+ """
63
+ Check every setting: its type, a separator of exactly one character and ``decimals`` not negative.
64
+
65
+ .. versionadded:: 0.1.0
66
+
67
+ Raises
68
+ ------
69
+ InvalidTypeError
70
+ When a setting is not of the type its annotation names.
71
+ InvalidSeparatorError
72
+ When the separator is not exactly one character.
73
+ InvalidCountError
74
+ When ``decimals`` is negative.
75
+ """
76
+ require_field_types(self)
77
+
78
+ require_separator(self.separator)
79
+ require_decimal_count(self.decimals)
@@ -0,0 +1,42 @@
1
+ """
2
+ Check of the number of decimals written in a file.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from numdaplot.errors.invalid_count_error import InvalidCountError
8
+
9
+ MINIMUM_DECIMAL_COUNT = 0
10
+
11
+
12
+ def require_decimal_count(decimals: int | None) -> None:
13
+ """
14
+ Check that a number of written decimals, when given, is 0 or more.
15
+
16
+ .. versionadded:: 0.1.0
17
+
18
+ Parameters
19
+ ----------
20
+ decimals
21
+ The number of decimals, or None when every digit is written.
22
+
23
+ Raises
24
+ ------
25
+ InvalidCountError
26
+ When the number is negative.
27
+
28
+ Examples
29
+ --------
30
+ >>> import numdaplot as ndp
31
+ >>> from numdaplot.tables.files.decimal_count import require_decimal_count
32
+ >>> try:
33
+ ... require_decimal_count(-1)
34
+ ... except ndp.InvalidCountError as error:
35
+ ... print(error)
36
+ Expected a count of at least 0, got -1.
37
+ """
38
+ if decimals is None:
39
+ return
40
+
41
+ if decimals < MINIMUM_DECIMAL_COUNT:
42
+ raise InvalidCountError(decimals, MINIMUM_DECIMAL_COUNT)