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,234 @@
1
+ """
2
+ Brackets cutting a number column into categories.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+
9
+ from numdaplot.arrays.mapping.unmatched import Unmatched
10
+ from numdaplot.errors.duplicate_label_error import DuplicateLabelError
11
+ from numdaplot.errors.empty_list_error import EmptyListError
12
+ from numdaplot.errors.invalid_label_count_error import InvalidLabelCountError
13
+ from numdaplot.errors.invalid_limits_error import InvalidLimitsError
14
+ from numdaplot.errors.refused_setting_error import RefusedSettingError
15
+ from numdaplot.rules.bounds import Bounds
16
+ from numdaplot.settings.field_types import require_field_types
17
+ from numdaplot.tables.columns.bracket_end import BracketEnd
18
+
19
+ LIMIT_ITEM_NAME = "limit"
20
+ BRACKETS_NAME = "Brackets"
21
+ ACCEPTED_BOUNDS = frozenset({Bounds.LOW_ONLY, Bounds.HIGH_ONLY})
22
+ REFUSED_BOUNDS_NAME = "Bounds.{bounds_name}"
23
+
24
+
25
+ @dataclass(frozen=True)
26
+ class Brackets:
27
+ """
28
+ Brackets cutting a number column into categories, used as the ``format`` of a ``Conversion`` to ``CATEGORY``.
29
+
30
+ The categories keep the order of the brackets, so that sorting and plots follow it. A missing value stays missing.
31
+
32
+ .. versionadded:: 0.1.0
33
+
34
+ Parameters
35
+ ----------
36
+ limits
37
+ The limits between the brackets, at least one, in strictly increasing order. Two limits make one bracket.
38
+ bounds
39
+ Which limit of each bracket it holds: ``Bounds.LOW_ONLY`` by default, ``0 <= x < 10``, or
40
+ ``Bounds.HIGH_ONLY``, ``0 < x <= 10``. The other members are refused, as they would put a value in two
41
+ brackets or in none.
42
+ labels
43
+ The name of each bracket, in order. When omitted, each name gives the values the bracket holds: ``0 to 9`` for
44
+ integers, ``0 to under 10`` for decimals, ``80 or more`` or ``under 0`` for an open bracket. Whole limits are
45
+ written without decimals.
46
+ first
47
+ Whether the first bracket stops at the first limit, ``BracketEnd.CLOSED`` by default, or holds every value
48
+ below it with ``BracketEnd.OPEN``.
49
+ last
50
+ Whether the last bracket stops at the last limit, ``BracketEnd.CLOSED`` by default, or holds every value
51
+ above it with ``BracketEnd.OPEN``.
52
+ others
53
+ What happens to a value in no bracket, ``Unmatched.ERROR`` by default.
54
+
55
+ Raises
56
+ ------
57
+ InvalidTypeError
58
+ When a setting is not of the type its annotation names.
59
+ EmptyListError
60
+ When ``limits`` is an empty list.
61
+ RefusedSettingError
62
+ When ``bounds`` is ``Bounds.INCLUDED`` or ``Bounds.EXCLUDED``.
63
+ InvalidLimitsError
64
+ When the limits do not strictly increase, or a single limit has no open end.
65
+ InvalidLabelCountError
66
+ When ``labels`` does not give one name per bracket.
67
+ DuplicateLabelError
68
+ When a label appears twice.
69
+
70
+ Examples
71
+ --------
72
+ >>> import numdaplot as ndp
73
+ >>> ages = ndp.Array.from_list([4, 17, 30, 92])
74
+ >>> victims = ndp.Table.from_arrays({"age": ages})
75
+ >>> brackets = ndp.Brackets(limits=[0, 10, 20], last=ndp.BracketEnd.OPEN)
76
+ >>> victims.convert(ndp.Conversion(column="age", dtype=ndp.Type.CATEGORY, format=brackets))
77
+ age
78
+ CATEGORY
79
+ 0 0 to 9
80
+ 1 10 to 19
81
+ 2 20 or more
82
+ 3 20 or more
83
+ """
84
+
85
+ limits: list[int | float]
86
+ bounds: Bounds = Bounds.LOW_ONLY
87
+ labels: list[str] | None = None
88
+ first: BracketEnd = BracketEnd.CLOSED
89
+ last: BracketEnd = BracketEnd.CLOSED
90
+ others: Unmatched = Unmatched.ERROR
91
+
92
+ def __post_init__(self) -> None:
93
+ """
94
+ Check the limits, the bounds and the labels.
95
+
96
+ .. versionadded:: 0.1.0
97
+
98
+ Raises
99
+ ------
100
+ InvalidTypeError
101
+ When a setting is not of the type its annotation names.
102
+ EmptyListError
103
+ When ``limits`` is an empty list.
104
+ RefusedSettingError
105
+ When ``bounds`` is ``Bounds.INCLUDED`` or ``Bounds.EXCLUDED``.
106
+ InvalidLimitsError
107
+ When the limits do not strictly increase, or a single limit has no open end.
108
+ InvalidLabelCountError
109
+ When ``labels`` does not give one name per bracket.
110
+ DuplicateLabelError
111
+ When a label appears twice.
112
+ """
113
+ require_field_types(self)
114
+
115
+ if self.limits == []:
116
+ raise EmptyListError(LIMIT_ITEM_NAME)
117
+
118
+ if self.bounds not in ACCEPTED_BOUNDS:
119
+ bounds_name = REFUSED_BOUNDS_NAME.format(bounds_name=self.bounds.name)
120
+ raise RefusedSettingError(bounds_name, BRACKETS_NAME)
121
+
122
+ require_increasing_limits(self.limits)
123
+ bracket_count = self.count_brackets()
124
+ if bracket_count == 0:
125
+ raise InvalidLimitsError(self.limits)
126
+
127
+ if self.labels is not None:
128
+ require_bracket_labels(self.labels, bracket_count)
129
+ labels_copy = list(self.labels)
130
+ object.__setattr__(self, "labels", labels_copy)
131
+
132
+ limits_copy = list(self.limits)
133
+ object.__setattr__(self, "limits", limits_copy)
134
+
135
+ def count_brackets(self) -> int:
136
+ """
137
+ Return the number of brackets: one between two limits, plus one per open end.
138
+
139
+ .. versionadded:: 0.1.0
140
+
141
+ Returns
142
+ -------
143
+ int
144
+ The number of brackets.
145
+
146
+ Examples
147
+ --------
148
+ >>> import numdaplot as ndp
149
+ >>> ndp.Brackets(limits=[0, 18, 65], last=ndp.BracketEnd.OPEN).count_brackets()
150
+ 3
151
+ """
152
+ limit_count = len(self.limits)
153
+ bracket_count = limit_count - 1
154
+ if self.first == BracketEnd.OPEN:
155
+ bracket_count += 1
156
+
157
+ if self.last == BracketEnd.OPEN:
158
+ bracket_count += 1
159
+
160
+ return bracket_count
161
+
162
+
163
+ def require_increasing_limits(limits: list[int | float]) -> None:
164
+ """
165
+ Check that each limit is greater than the one before.
166
+
167
+ .. versionadded:: 0.1.0
168
+
169
+ Parameters
170
+ ----------
171
+ limits
172
+ The limits of brackets.
173
+
174
+ Raises
175
+ ------
176
+ InvalidLimitsError
177
+ When a limit is not greater than the one before, or is NaN.
178
+
179
+ Examples
180
+ --------
181
+ >>> import numdaplot as ndp
182
+ >>> from numdaplot.tables.columns.brackets import require_increasing_limits
183
+ >>> try:
184
+ ... require_increasing_limits([20, 10])
185
+ ... except ndp.InvalidLimitsError as error:
186
+ ... print(error)
187
+ Expected limits in strictly increasing order, got 10 after 20.
188
+ """
189
+ for earlier_limit, later_limit in zip(limits, limits[1:], strict=False):
190
+ is_greater = later_limit > earlier_limit
191
+ if not is_greater:
192
+ raise InvalidLimitsError(limits)
193
+
194
+
195
+ def require_bracket_labels(labels: list[str], bracket_count: int) -> None:
196
+ """
197
+ Check that the labels give one distinct name per bracket.
198
+
199
+ .. versionadded:: 0.1.0
200
+
201
+ Parameters
202
+ ----------
203
+ labels
204
+ The names of the brackets.
205
+ bracket_count
206
+ The number of brackets.
207
+
208
+ Raises
209
+ ------
210
+ InvalidLabelCountError
211
+ When there is not one label per bracket.
212
+ DuplicateLabelError
213
+ At the first label given twice.
214
+
215
+ Examples
216
+ --------
217
+ >>> import numdaplot as ndp
218
+ >>> from numdaplot.tables.columns.brackets import require_bracket_labels
219
+ >>> try:
220
+ ... require_bracket_labels(["child", "child"], 2)
221
+ ... except ndp.DuplicateLabelError as error:
222
+ ... print(error)
223
+ The label 'child' appears more than once.
224
+ """
225
+ label_count = len(labels)
226
+ if label_count != bracket_count:
227
+ raise InvalidLabelCountError(bracket_count, label_count)
228
+
229
+ seen_labels = set[str]()
230
+ for label in labels:
231
+ if label in seen_labels:
232
+ raise DuplicateLabelError(label)
233
+
234
+ seen_labels.add(label)
@@ -0,0 +1,55 @@
1
+ """
2
+ Choice of the columns of a Table.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ import pandas
8
+
9
+ from numdaplot.tables.columns.column_choice import ColumnChoice
10
+ from numdaplot.tables.columns.column_mode import ColumnMode
11
+ from numdaplot.tables.columns.column_names import require_known_columns
12
+
13
+
14
+ def choose_frame_columns(frame: pandas.DataFrame, choice: ColumnChoice) -> pandas.DataFrame:
15
+ """
16
+ Return the columns of a Table that a choice keeps.
17
+
18
+ .. versionadded:: 0.1.0
19
+
20
+ Parameters
21
+ ----------
22
+ frame
23
+ The columns of a Table.
24
+ choice
25
+ The columns, and whether to keep or drop them.
26
+
27
+ Returns
28
+ -------
29
+ pandas.DataFrame
30
+ With ``KEEP``, the named columns in the order of the list; with ``DROP``, the other columns in their order.
31
+
32
+ Raises
33
+ ------
34
+ ColumnNotFoundError
35
+ When a named column does not exist.
36
+
37
+ Examples
38
+ --------
39
+ >>> import pandas
40
+ >>> import numdaplot as ndp
41
+ >>> from numdaplot.tables.columns.chosen_columns import choose_frame_columns
42
+ >>> frame = pandas.DataFrame({"city": ["Pau"], "price": [1.5]})
43
+ >>> choose_frame_columns(frame, ndp.ColumnChoice(columns=["price", "city"]))
44
+ price city
45
+ 0 1.5 Pau
46
+ """
47
+ column_names = [str(column_name) for column_name in frame.columns]
48
+ require_known_columns(choice.columns, column_names)
49
+ if choice.mode == ColumnMode.DROP:
50
+ remaining_frame = frame.drop(columns=choice.columns)
51
+ return remaining_frame
52
+
53
+ kept_frame = frame.loc[:, choice.columns]
54
+
55
+ return kept_frame
@@ -0,0 +1,84 @@
1
+ """
2
+ Settings of the choice of the columns of a Table.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+
9
+ from numdaplot.errors.empty_list_error import EmptyListError
10
+ from numdaplot.settings.field_types import require_field_types
11
+ from numdaplot.tables.columns.column_mode import ColumnMode
12
+ from numdaplot.tables.columns.column_names import require_column_names
13
+
14
+ COLUMN_ITEM_NAME = "column"
15
+
16
+
17
+ @dataclass(frozen=True)
18
+ class ColumnChoice:
19
+ """
20
+ Columns to keep or to drop, used by ``Table.choose_columns``.
21
+
22
+ .. versionadded:: 0.1.0
23
+
24
+ Parameters
25
+ ----------
26
+ columns
27
+ The names of the columns. The choice keeps its own copy of the list.
28
+ mode
29
+ ``KEEP`` by default, keeping only these columns, in the order of the list, or ``DROP`` to remove them.
30
+
31
+ Raises
32
+ ------
33
+ InvalidTypeError
34
+ When a setting is not of the type its annotation names.
35
+ EmptyListError
36
+ When ``columns`` is empty with ``KEEP``, which would keep nothing.
37
+ InvalidColumnNameError
38
+ When a column name is an empty text.
39
+ DuplicateColumnError
40
+ When a column name appears twice.
41
+
42
+ Examples
43
+ --------
44
+ >>> import numdaplot as ndp
45
+ >>> cities = ndp.Array.from_list(["Paris", "Lyon", "Paris"])
46
+ >>> prices = ndp.Array.from_list([120.0, 80.0, 150.0])
47
+ >>> sales = ndp.Table.from_arrays({"city": cities, "price": prices})
48
+ >>> sales.choose_columns(ndp.ColumnChoice(columns=["price"]))
49
+ price
50
+ FLOAT64
51
+ 0 120.0
52
+ 1 80.0
53
+ 2 150.0
54
+ """
55
+
56
+ columns: list[str]
57
+ mode: ColumnMode = ColumnMode.KEEP
58
+
59
+ def __post_init__(self) -> None:
60
+ """
61
+ Check the columns and replace them with a copy that only the choice holds.
62
+
63
+ .. versionadded:: 0.1.0
64
+
65
+ Raises
66
+ ------
67
+ InvalidTypeError
68
+ When a setting is not of the type its annotation names.
69
+ EmptyListError
70
+ When ``columns`` is empty with ``KEEP``.
71
+ InvalidColumnNameError
72
+ When a column name is an empty text.
73
+ DuplicateColumnError
74
+ When a column name appears twice.
75
+ """
76
+ require_field_types(self)
77
+
78
+ keeps_nothing = self.columns == [] and self.mode == ColumnMode.KEEP
79
+ if keeps_nothing:
80
+ raise EmptyListError(COLUMN_ITEM_NAME)
81
+
82
+ require_column_names(self.columns)
83
+ columns_copy = list(self.columns)
84
+ object.__setattr__(self, "columns", columns_copy)
@@ -0,0 +1,64 @@
1
+ """
2
+ Whether a ColumnChoice keeps or drops its columns.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from enum import Enum, auto
8
+
9
+
10
+ class ColumnMode(Enum):
11
+ """
12
+ Whether a ``ColumnChoice`` keeps or drops the columns it names.
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.choose_columns(ndp.ColumnChoice(columns=["price"], mode=ndp.ColumnMode.DROP))
23
+ city
24
+ TEXT
25
+ 0 Paris
26
+ 1 Lyon
27
+ 2 Paris
28
+ """
29
+
30
+ KEEP = auto()
31
+ """
32
+ Only the named columns remain, in the order of the list. Default value.
33
+
34
+ Examples
35
+ --------
36
+ >>> import numdaplot as ndp
37
+ >>> cities = ndp.Array.from_list(["Paris", "Lyon", "Paris"])
38
+ >>> prices = ndp.Array.from_list([120.0, 80.0, 150.0])
39
+ >>> sales = ndp.Table.from_arrays({"city": cities, "price": prices})
40
+ >>> sales.choose_columns(ndp.ColumnChoice(columns=["price"], mode=ndp.ColumnMode.KEEP))
41
+ price
42
+ FLOAT64
43
+ 0 120.0
44
+ 1 80.0
45
+ 2 150.0
46
+ """
47
+
48
+ DROP = auto()
49
+ """
50
+ The named columns are removed, the others keep their order.
51
+
52
+ Examples
53
+ --------
54
+ >>> import numdaplot as ndp
55
+ >>> cities = ndp.Array.from_list(["Paris", "Lyon", "Paris"])
56
+ >>> prices = ndp.Array.from_list([120.0, 80.0, 150.0])
57
+ >>> sales = ndp.Table.from_arrays({"city": cities, "price": prices})
58
+ >>> sales.choose_columns(ndp.ColumnChoice(columns=["price"], mode=ndp.ColumnMode.DROP))
59
+ city
60
+ TEXT
61
+ 0 Paris
62
+ 1 Lyon
63
+ 2 Paris
64
+ """
@@ -0,0 +1,186 @@
1
+ """
2
+ Checks of the column names of a Table.
3
+
4
+ .. versionadded:: 0.1.0
5
+ """
6
+
7
+ from collections.abc import Sequence
8
+
9
+ from numdaplot.errors.column_not_found_error import ColumnNotFoundError
10
+ from numdaplot.errors.duplicate_column_error import DuplicateColumnError
11
+ from numdaplot.errors.invalid_column_name_error import InvalidColumnNameError
12
+
13
+
14
+ def require_column_name(column_name: object) -> None:
15
+ """
16
+ Check that a column name is a non-empty text.
17
+
18
+ .. versionadded:: 0.1.0
19
+
20
+ Parameters
21
+ ----------
22
+ column_name
23
+ The name to check.
24
+
25
+ Raises
26
+ ------
27
+ InvalidColumnNameError
28
+ When the name is not a text, or is empty.
29
+
30
+ Examples
31
+ --------
32
+ >>> import numdaplot as ndp
33
+ >>> from numdaplot.tables.columns.column_names import require_column_name
34
+ >>> try:
35
+ ... require_column_name(2024)
36
+ ... except ndp.InvalidColumnNameError as error:
37
+ ... print(error)
38
+ Expected a column name as a non-empty text, got 2024.
39
+ """
40
+ is_text = isinstance(column_name, str)
41
+ if not is_text:
42
+ raise InvalidColumnNameError(column_name)
43
+
44
+ if column_name == "":
45
+ raise InvalidColumnNameError(column_name)
46
+
47
+
48
+ def require_optional_column_name(column_name: object) -> None:
49
+ """
50
+ Check that a column name, when given, is a non-empty text.
51
+
52
+ .. versionadded:: 0.1.0
53
+
54
+ Parameters
55
+ ----------
56
+ column_name
57
+ The name to check, or None when the setting is omitted.
58
+
59
+ Raises
60
+ ------
61
+ InvalidColumnNameError
62
+ When the name is given and is not a non-empty text.
63
+
64
+ Examples
65
+ --------
66
+ >>> import numdaplot as ndp
67
+ >>> from numdaplot.tables.columns.column_names import require_optional_column_name
68
+ >>> require_optional_column_name(None)
69
+ >>> try:
70
+ ... require_optional_column_name("")
71
+ ... except ndp.InvalidColumnNameError as error:
72
+ ... print(error)
73
+ Expected a column name as a non-empty text, got ''.
74
+ """
75
+ if column_name is None:
76
+ return
77
+
78
+ require_column_name(column_name)
79
+
80
+
81
+ def require_unique_names(column_names: Sequence[str]) -> None:
82
+ """
83
+ Check that no column name appears twice.
84
+
85
+ .. versionadded:: 0.1.0
86
+
87
+ Parameters
88
+ ----------
89
+ column_names
90
+ The names to check.
91
+
92
+ Raises
93
+ ------
94
+ DuplicateColumnError
95
+ At the first name that appears a second time.
96
+
97
+ Examples
98
+ --------
99
+ >>> import numdaplot as ndp
100
+ >>> from numdaplot.tables.columns.column_names import require_unique_names
101
+ >>> try:
102
+ ... require_unique_names(["city", "price", "city"])
103
+ ... except ndp.DuplicateColumnError as error:
104
+ ... print(error)
105
+ The column name 'city' appears more than once.
106
+ """
107
+ seen_names = set[str]()
108
+
109
+ for column_name in column_names:
110
+ if column_name in seen_names:
111
+ raise DuplicateColumnError(column_name)
112
+
113
+ seen_names.add(column_name)
114
+
115
+
116
+ def require_column_names(column_names: Sequence[object]) -> None:
117
+ """
118
+ Check that every column name is a non-empty text and appears once.
119
+
120
+ .. versionadded:: 0.1.0
121
+
122
+ Parameters
123
+ ----------
124
+ column_names
125
+ The names to check, such as the header of a file.
126
+
127
+ Raises
128
+ ------
129
+ InvalidColumnNameError
130
+ At the first name that is not a non-empty text.
131
+ DuplicateColumnError
132
+ At the first name that appears a second time.
133
+
134
+ Examples
135
+ --------
136
+ >>> import numdaplot as ndp
137
+ >>> from numdaplot.tables.columns.column_names import require_column_names
138
+ >>> try:
139
+ ... require_column_names(["city", ""])
140
+ ... except ndp.InvalidColumnNameError as error:
141
+ ... print(error)
142
+ Expected a column name as a non-empty text, got ''.
143
+ """
144
+ text_names = list[str]()
145
+
146
+ for column_name in column_names:
147
+ require_column_name(column_name)
148
+ text_name = str(column_name)
149
+ text_names.append(text_name)
150
+
151
+ require_unique_names(text_names)
152
+
153
+
154
+ def require_known_columns(requested_names: Sequence[str], column_names: Sequence[str]) -> None:
155
+ """
156
+ Check that every requested column exists.
157
+
158
+ .. versionadded:: 0.1.0
159
+
160
+ Parameters
161
+ ----------
162
+ requested_names
163
+ The names given by the user.
164
+ column_names
165
+ The names of the columns of the Table.
166
+
167
+ Raises
168
+ ------
169
+ ColumnNotFoundError
170
+ At the first requested name that matches no column.
171
+
172
+ Examples
173
+ --------
174
+ >>> import numdaplot as ndp
175
+ >>> from numdaplot.tables.columns.column_names import require_known_columns
176
+ >>> try:
177
+ ... require_known_columns(["prise"], ["city", "price"])
178
+ ... except ndp.ColumnNotFoundError as error:
179
+ ... print(error)
180
+ No column is named 'prise'.
181
+ """
182
+ known_names = set(column_names)
183
+
184
+ for requested_name in requested_names:
185
+ if requested_name not in known_names:
186
+ raise ColumnNotFoundError(requested_name)