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.
- numdaplot/__init__.py +506 -0
- numdaplot/arrays/__init__.py +5 -0
- numdaplot/arrays/array.py +92 -0
- numdaplot/arrays/array_arithmetic.py +404 -0
- numdaplot/arrays/array_calculation.py +143 -0
- numdaplot/arrays/array_conversion.py +150 -0
- numdaplot/arrays/array_creation.py +371 -0
- numdaplot/arrays/array_data.py +281 -0
- numdaplot/arrays/array_layout.py +179 -0
- numdaplot/arrays/array_logic.py +227 -0
- numdaplot/arrays/array_reflected_arithmetic.py +334 -0
- numdaplot/arrays/array_refusals.py +339 -0
- numdaplot/arrays/array_selection.py +195 -0
- numdaplot/arrays/array_sorting.py +59 -0
- numdaplot/arrays/axis_number.py +58 -0
- numdaplot/arrays/calculation/__init__.py +5 -0
- numdaplot/arrays/calculation/counting_statistics.py +325 -0
- numdaplot/arrays/calculation/location_statistics.py +268 -0
- numdaplot/arrays/calculation/math_function_values.py +183 -0
- numdaplot/arrays/calculation/statistic_values.py +209 -0
- numdaplot/arrays/calculation/time_function_values.py +419 -0
- numdaplot/arrays/conversion/__init__.py +5 -0
- numdaplot/arrays/conversion/array_text.py +62 -0
- numdaplot/arrays/conversion/equality_check.py +72 -0
- numdaplot/arrays/conversion/python_values.py +70 -0
- numdaplot/arrays/conversion/time_text.py +290 -0
- numdaplot/arrays/creation/__init__.py +5 -0
- numdaplot/arrays/creation/date_parts.py +89 -0
- numdaplot/arrays/creation/date_parts_values.py +437 -0
- numdaplot/arrays/creation/distribution.py +54 -0
- numdaplot/arrays/creation/filled_values.py +58 -0
- numdaplot/arrays/creation/list_conversion.py +311 -0
- numdaplot/arrays/creation/list_shape.py +97 -0
- numdaplot/arrays/creation/normal.py +65 -0
- numdaplot/arrays/creation/numpy_conversion.py +149 -0
- numdaplot/arrays/creation/random_integers.py +104 -0
- numdaplot/arrays/creation/random_values.py +97 -0
- numdaplot/arrays/creation/range_values.py +73 -0
- numdaplot/arrays/creation/spacing.py +84 -0
- numdaplot/arrays/creation/spacing_values.py +63 -0
- numdaplot/arrays/creation/uniform.py +63 -0
- numdaplot/arrays/equality.py +68 -0
- numdaplot/arrays/layout/__init__.py +5 -0
- numdaplot/arrays/layout/sorting_values.py +113 -0
- numdaplot/arrays/layout/unique_values.py +49 -0
- numdaplot/arrays/mapping/__init__.py +5 -0
- numdaplot/arrays/mapping/mapped_values.py +286 -0
- numdaplot/arrays/mapping/unmatched.py +50 -0
- numdaplot/arrays/mapping/value_change.py +55 -0
- numdaplot/arrays/mapping/value_mapping.py +161 -0
- numdaplot/arrays/math_functions/__init__.py +5 -0
- numdaplot/arrays/math_functions/absolute.py +27 -0
- numdaplot/arrays/math_functions/cosine.py +28 -0
- numdaplot/arrays/math_functions/exponential.py +27 -0
- numdaplot/arrays/math_functions/logarithm.py +72 -0
- numdaplot/arrays/math_functions/math_function.py +58 -0
- numdaplot/arrays/math_functions/round.py +58 -0
- numdaplot/arrays/math_functions/sine.py +28 -0
- numdaplot/arrays/math_functions/square_root.py +27 -0
- numdaplot/arrays/operations/__init__.py +5 -0
- numdaplot/arrays/operations/boolean_operands.py +48 -0
- numdaplot/arrays/operations/combination.py +157 -0
- numdaplot/arrays/operations/float_errors.py +170 -0
- numdaplot/arrays/operations/integer_bounds.py +175 -0
- numdaplot/arrays/operations/integer_rules.py +397 -0
- numdaplot/arrays/operations/operand.py +139 -0
- numdaplot/arrays/operations/time_arithmetic.py +479 -0
- numdaplot/arrays/operations/time_bounds.py +286 -0
- numdaplot/arrays/operations/time_result_bounds.py +397 -0
- numdaplot/arrays/operations/transformation.py +54 -0
- numdaplot/arrays/operations/type_requirements.py +94 -0
- numdaplot/arrays/replacement.py +66 -0
- numdaplot/arrays/selection/__init__.py +5 -0
- numdaplot/arrays/selection/comparison_masks.py +131 -0
- numdaplot/arrays/selection/membership_masks.py +118 -0
- numdaplot/arrays/selection/missing_mask.py +50 -0
- numdaplot/arrays/selection/region_index.py +178 -0
- numdaplot/arrays/selection/replaced_values.py +120 -0
- numdaplot/arrays/selection/rule_mask.py +83 -0
- numdaplot/arrays/selection/time_reference.py +172 -0
- numdaplot/arrays/shape.py +74 -0
- numdaplot/arrays/type_match.py +51 -0
- numdaplot/data_types/__init__.py +5 -0
- numdaplot/data_types/library.py +57 -0
- numdaplot/data_types/numpy_mapping.py +207 -0
- numdaplot/data_types/pandas_mapping.py +114 -0
- numdaplot/data_types/time_of_day.py +292 -0
- numdaplot/data_types/type.py +224 -0
- numdaplot/data_types/value_family.py +149 -0
- numdaplot/data_types/value_type.py +147 -0
- numdaplot/dates/__init__.py +5 -0
- numdaplot/dates/custom_date_format.py +83 -0
- numdaplot/dates/date_format.py +120 -0
- numdaplot/dates/date_part.py +59 -0
- numdaplot/dates/date_part_unit.py +153 -0
- numdaplot/dates/date_period.py +57 -0
- numdaplot/dates/duration_in.py +58 -0
- numdaplot/dates/duration_unit.py +90 -0
- numdaplot/dates/period_unit.py +101 -0
- numdaplot/dates/time_function.py +56 -0
- numdaplot/dates/time_zone.py +68 -0
- numdaplot/dates/time_zone_change.py +71 -0
- numdaplot/dates/time_zone_mode.py +81 -0
- numdaplot/dates/to_duration.py +58 -0
- numdaplot/errors/__init__.py +7 -0
- numdaplot/errors/broadcast_warning.py +36 -0
- numdaplot/errors/calculation_warning.py +35 -0
- numdaplot/errors/cell_out_of_range_error.py +77 -0
- numdaplot/errors/column_not_found_error.py +64 -0
- numdaplot/errors/conflicting_settings_error.py +60 -0
- numdaplot/errors/dimension_error.py +62 -0
- numdaplot/errors/display_warning.py +32 -0
- numdaplot/errors/duplicate_column_error.py +82 -0
- numdaplot/errors/duplicate_label_error.py +55 -0
- numdaplot/errors/duplicate_statistic_error.py +55 -0
- numdaplot/errors/duplicate_value_error.py +54 -0
- numdaplot/errors/empty_array_error.py +55 -0
- numdaplot/errors/empty_list_error.py +52 -0
- numdaplot/errors/empty_region_error.py +34 -0
- numdaplot/errors/empty_text_error.py +34 -0
- numdaplot/errors/empty_total_error.py +62 -0
- numdaplot/errors/empty_values_error.py +34 -0
- numdaplot/errors/file_access_error.py +70 -0
- numdaplot/errors/file_exists_error.py +62 -0
- numdaplot/errors/file_not_found_error.py +56 -0
- numdaplot/errors/incompatible_charts_error.py +80 -0
- numdaplot/errors/incompatible_types_error.py +104 -0
- numdaplot/errors/integer_overflow_error.py +61 -0
- numdaplot/errors/invalid_base_error.py +52 -0
- numdaplot/errors/invalid_bin_width_error.py +66 -0
- numdaplot/errors/invalid_bounds_error.py +58 -0
- numdaplot/errors/invalid_chart_data_error.py +81 -0
- numdaplot/errors/invalid_color_count_error.py +63 -0
- numdaplot/errors/invalid_color_error.py +51 -0
- numdaplot/errors/invalid_column_name_error.py +52 -0
- numdaplot/errors/invalid_conversion_error.py +119 -0
- numdaplot/errors/invalid_count_error.py +61 -0
- numdaplot/errors/invalid_date_format_error.py +51 -0
- numdaplot/errors/invalid_deviation_error.py +52 -0
- numdaplot/errors/invalid_fraction_error.py +51 -0
- numdaplot/errors/invalid_label_count_error.py +61 -0
- numdaplot/errors/invalid_limits_error.py +111 -0
- numdaplot/errors/invalid_opacity_error.py +52 -0
- numdaplot/errors/invalid_point_size_error.py +52 -0
- numdaplot/errors/invalid_position_error.py +106 -0
- numdaplot/errors/invalid_resolution_error.py +51 -0
- numdaplot/errors/invalid_rotation_error.py +53 -0
- numdaplot/errors/invalid_seed_error.py +53 -0
- numdaplot/errors/invalid_separator_error.py +52 -0
- numdaplot/errors/invalid_shape_error.py +52 -0
- numdaplot/errors/invalid_sheet_name_error.py +54 -0
- numdaplot/errors/invalid_size_error.py +58 -0
- numdaplot/errors/invalid_step_error.py +77 -0
- numdaplot/errors/invalid_suffixes_error.py +61 -0
- numdaplot/errors/invalid_time_zone_change_error.py +63 -0
- numdaplot/errors/invalid_type_error.py +79 -0
- numdaplot/errors/irregular_list_error.py +36 -0
- numdaplot/errors/join_relation_error.py +183 -0
- numdaplot/errors/missing_dependency_error.py +58 -0
- numdaplot/errors/missing_type_error.py +36 -0
- numdaplot/errors/missing_value_error.py +62 -0
- numdaplot/errors/not_single_value_error.py +53 -0
- numdaplot/errors/numdaplot_error.py +25 -0
- numdaplot/errors/numdaplot_warning.py +34 -0
- numdaplot/errors/occupied_cell_error.py +63 -0
- numdaplot/errors/out_of_domain_error.py +70 -0
- numdaplot/errors/readability_warning.py +35 -0
- numdaplot/errors/refused_operation_error.py +64 -0
- numdaplot/errors/refused_setting_error.py +60 -0
- numdaplot/errors/rejected_dates.py +60 -0
- numdaplot/errors/repeated_key.py +36 -0
- numdaplot/errors/shape_mismatch_error.py +67 -0
- numdaplot/errors/time_overflow_error.py +131 -0
- numdaplot/errors/time_zone_mismatch_error.py +83 -0
- numdaplot/errors/unknown_time_zone_error.py +51 -0
- numdaplot/errors/unmatched_value_error.py +81 -0
- numdaplot/errors/unsupported_image_format_error.py +56 -0
- numdaplot/errors/unsupported_index_error.py +38 -0
- numdaplot/errors/unsupported_missing_error.py +129 -0
- numdaplot/errors/unsupported_type_error.py +62 -0
- numdaplot/errors/value_conversion_error.py +215 -0
- numdaplot/ordering/__init__.py +5 -0
- numdaplot/ordering/missing_position.py +46 -0
- numdaplot/ordering/order.py +46 -0
- numdaplot/package_version.py +36 -0
- numdaplot/plots/__init__.py +5 -0
- numdaplot/plots/chart_layer.py +47 -0
- numdaplot/plots/charts/__init__.py +5 -0
- numdaplot/plots/charts/bar_chart.py +98 -0
- numdaplot/plots/charts/bar_layout.py +58 -0
- numdaplot/plots/charts/bin_count.py +61 -0
- numdaplot/plots/charts/bin_width.py +78 -0
- numdaplot/plots/charts/box_chart.py +97 -0
- numdaplot/plots/charts/cell_values.py +61 -0
- numdaplot/plots/charts/chart.py +59 -0
- numdaplot/plots/charts/chart_settings.py +105 -0
- numdaplot/plots/charts/color_scale.py +147 -0
- numdaplot/plots/charts/heatmap_chart.py +92 -0
- numdaplot/plots/charts/histogram_chart.py +93 -0
- numdaplot/plots/charts/line_chart.py +100 -0
- numdaplot/plots/charts/line_type.py +75 -0
- numdaplot/plots/charts/marker_shape.py +113 -0
- numdaplot/plots/charts/missing_chart.py +60 -0
- numdaplot/plots/charts/missing_map_chart.py +27 -0
- numdaplot/plots/charts/orientation.py +58 -0
- numdaplot/plots/charts/outliers.py +49 -0
- numdaplot/plots/charts/percentages.py +55 -0
- numdaplot/plots/charts/pie_chart.py +87 -0
- numdaplot/plots/charts/scatter_chart.py +159 -0
- numdaplot/plots/charts/value_axis.py +66 -0
- numdaplot/plots/data/__init__.py +5 -0
- numdaplot/plots/data/array_values.py +128 -0
- numdaplot/plots/data/chart_data.py +143 -0
- numdaplot/plots/data/chart_values.py +109 -0
- numdaplot/plots/data/column_reading.py +468 -0
- numdaplot/plots/data/heatmap_values.py +63 -0
- numdaplot/plots/data/missing_cells.py +165 -0
- numdaplot/plots/data/pie_values.py +215 -0
- numdaplot/plots/data/point_values.py +249 -0
- numdaplot/plots/data/position_kind.py +83 -0
- numdaplot/plots/data/renamed_layers.py +340 -0
- numdaplot/plots/data/sample_values.py +160 -0
- numdaplot/plots/data/shown_columns.py +248 -0
- numdaplot/plots/data/table_values.py +256 -0
- numdaplot/plots/data/unique_labels.py +45 -0
- numdaplot/plots/drawing/__init__.py +5 -0
- numdaplot/plots/drawing/bar_drawing.py +316 -0
- numdaplot/plots/drawing/box_drawing.py +344 -0
- numdaplot/plots/drawing/cell_merging.py +237 -0
- numdaplot/plots/drawing/chart_texts.py +124 -0
- numdaplot/plots/drawing/color_bar.py +57 -0
- numdaplot/plots/drawing/color_scale_values.py +120 -0
- numdaplot/plots/drawing/default_labels.py +41 -0
- numdaplot/plots/drawing/drawn_chart.py +50 -0
- numdaplot/plots/drawing/grid_axes.py +75 -0
- numdaplot/plots/drawing/heatmap_drawing.py +313 -0
- numdaplot/plots/drawing/histogram_drawing.py +350 -0
- numdaplot/plots/drawing/label_room.py +344 -0
- numdaplot/plots/drawing/label_thinning.py +216 -0
- numdaplot/plots/drawing/layer_alignment.py +319 -0
- numdaplot/plots/drawing/layer_colors.py +123 -0
- numdaplot/plots/drawing/line_drawing.py +85 -0
- numdaplot/plots/drawing/marker_codes.py +20 -0
- numdaplot/plots/drawing/missing_drawing.py +360 -0
- numdaplot/plots/drawing/moment_period_formatter.py +253 -0
- numdaplot/plots/drawing/pie_drawing.py +185 -0
- numdaplot/plots/drawing/plot_axes.py +38 -0
- numdaplot/plots/drawing/plot_drawing.py +288 -0
- numdaplot/plots/drawing/plot_theme.py +45 -0
- numdaplot/plots/drawing/position_axis.py +278 -0
- numdaplot/plots/drawing/scatter_drawing.py +364 -0
- numdaplot/plots/drawing/series_colors.py +177 -0
- numdaplot/plots/drawing/size_inches.py +45 -0
- numdaplot/plots/drawing/style_drawing.py +410 -0
- numdaplot/plots/drawing/text_contrast.py +44 -0
- numdaplot/plots/drawing/tick_rotation.py +354 -0
- numdaplot/plots/drawing/time_axis.py +212 -0
- numdaplot/plots/drawing/whole_numbers.py +72 -0
- numdaplot/plots/figure/__init__.py +5 -0
- numdaplot/plots/figure/cell.py +95 -0
- numdaplot/plots/figure/figure.py +256 -0
- numdaplot/plots/figure/figure_drawing.py +99 -0
- numdaplot/plots/figure/figure_style.py +60 -0
- numdaplot/plots/figure/layout.py +71 -0
- numdaplot/plots/figure/placement.py +150 -0
- numdaplot/plots/layer_reading.py +166 -0
- numdaplot/plots/output/__init__.py +5 -0
- numdaplot/plots/output/image_saving.py +187 -0
- numdaplot/plots/output/plot_display.py +181 -0
- numdaplot/plots/output/shown_object.py +45 -0
- numdaplot/plots/overlay_checks.py +245 -0
- numdaplot/plots/plot.py +31 -0
- numdaplot/plots/plot_data.py +140 -0
- numdaplot/plots/plot_distribution_creation.py +237 -0
- numdaplot/plots/plot_output.py +124 -0
- numdaplot/plots/plot_overlays.py +273 -0
- numdaplot/plots/plot_overview_creation.py +195 -0
- numdaplot/plots/plot_series_creation.py +213 -0
- numdaplot/plots/style/__init__.py +5 -0
- numdaplot/plots/style/axis_settings.py +60 -0
- numdaplot/plots/style/color.py +168 -0
- numdaplot/plots/style/custom_color.py +65 -0
- numdaplot/plots/style/grid_lines.py +49 -0
- numdaplot/plots/style/image_options.py +71 -0
- numdaplot/plots/style/legend_position.py +149 -0
- numdaplot/plots/style/plot_style.py +136 -0
- numdaplot/plots/style/size.py +70 -0
- numdaplot/plots/style/size_unit.py +62 -0
- numdaplot/positions/__init__.py +5 -0
- numdaplot/positions/axis.py +54 -0
- numdaplot/positions/index.py +51 -0
- numdaplot/positions/range.py +90 -0
- numdaplot/positions/region.py +92 -0
- numdaplot/py.typed +0 -0
- numdaplot/ratios/__init__.py +5 -0
- numdaplot/ratios/fraction.py +40 -0
- numdaplot/ratios/measure.py +48 -0
- numdaplot/rules/__init__.py +5 -0
- numdaplot/rules/between.py +78 -0
- numdaplot/rules/bounds.py +83 -0
- numdaplot/rules/case.py +48 -0
- numdaplot/rules/contains.py +63 -0
- numdaplot/rules/equal.py +43 -0
- numdaplot/rules/greater.py +39 -0
- numdaplot/rules/greater_or_equal.py +38 -0
- numdaplot/rules/is_in.py +67 -0
- numdaplot/rules/is_missing.py +25 -0
- numdaplot/rules/is_present.py +25 -0
- numdaplot/rules/less.py +39 -0
- numdaplot/rules/less_or_equal.py +38 -0
- numdaplot/rules/not_equal.py +45 -0
- numdaplot/rules/rule.py +62 -0
- numdaplot/rules/rule_values.py +44 -0
- numdaplot/rules/value_rule.py +110 -0
- numdaplot/settings/__init__.py +5 -0
- numdaplot/settings/argument_types.py +327 -0
- numdaplot/settings/field_types.py +593 -0
- numdaplot/statistics/__init__.py +5 -0
- numdaplot/statistics/count.py +71 -0
- numdaplot/statistics/count_distinct.py +27 -0
- numdaplot/statistics/counted_missing.py +46 -0
- numdaplot/statistics/maximum.py +27 -0
- numdaplot/statistics/mean.py +27 -0
- numdaplot/statistics/median.py +27 -0
- numdaplot/statistics/minimum.py +27 -0
- numdaplot/statistics/most_frequent.py +27 -0
- numdaplot/statistics/most_frequent_count.py +27 -0
- numdaplot/statistics/quantile.py +61 -0
- numdaplot/statistics/standard_deviation.py +29 -0
- numdaplot/statistics/statistic.py +63 -0
- numdaplot/statistics/sum.py +27 -0
- numdaplot/tables/__init__.py +5 -0
- numdaplot/tables/aggregation/__init__.py +5 -0
- numdaplot/tables/aggregation/aggregated_frame.py +189 -0
- numdaplot/tables/aggregation/aggregation.py +97 -0
- numdaplot/tables/aggregation/calculation.py +123 -0
- numdaplot/tables/aggregation/result_column.py +108 -0
- numdaplot/tables/aggregation/row_groups.py +96 -0
- numdaplot/tables/aggregation/statistic_name.py +122 -0
- numdaplot/tables/columns/__init__.py +5 -0
- numdaplot/tables/columns/added_column.py +89 -0
- numdaplot/tables/columns/boolean_conversion.py +144 -0
- numdaplot/tables/columns/boolean_rule.py +59 -0
- numdaplot/tables/columns/bracket_end.py +50 -0
- numdaplot/tables/columns/bracket_names.py +346 -0
- numdaplot/tables/columns/bracketed_column.py +179 -0
- numdaplot/tables/columns/brackets.py +234 -0
- numdaplot/tables/columns/chosen_columns.py +55 -0
- numdaplot/tables/columns/column_choice.py +84 -0
- numdaplot/tables/columns/column_mode.py +64 -0
- numdaplot/tables/columns/column_names.py +186 -0
- numdaplot/tables/columns/conversion.py +103 -0
- numdaplot/tables/columns/converted_column.py +669 -0
- numdaplot/tables/columns/date_conversion.py +526 -0
- numdaplot/tables/columns/date_range.py +135 -0
- numdaplot/tables/columns/name_change.py +67 -0
- numdaplot/tables/columns/new_column.py +79 -0
- numdaplot/tables/columns/number_conversion.py +281 -0
- numdaplot/tables/columns/renamed_columns.py +60 -0
- numdaplot/tables/columns/renaming.py +81 -0
- numdaplot/tables/columns/text_conversion.py +70 -0
- numdaplot/tables/columns/time_conversion.py +313 -0
- numdaplot/tables/columns/time_zone_conversion.py +128 -0
- numdaplot/tables/conflict.py +68 -0
- numdaplot/tables/description/__init__.py +5 -0
- numdaplot/tables/description/described_frame.py +335 -0
- numdaplot/tables/description/description.py +155 -0
- numdaplot/tables/duplicates/__init__.py +5 -0
- numdaplot/tables/duplicates/deduplicated_frame.py +66 -0
- numdaplot/tables/duplicates/deduplication.py +88 -0
- numdaplot/tables/duplicates/keep.py +81 -0
- numdaplot/tables/files/__init__.py +5 -0
- numdaplot/tables/files/column_names.py +60 -0
- numdaplot/tables/files/csv_file.py +265 -0
- numdaplot/tables/files/csv_read_options.py +89 -0
- numdaplot/tables/files/csv_separator.py +41 -0
- numdaplot/tables/files/csv_write_options.py +79 -0
- numdaplot/tables/files/decimal_count.py +42 -0
- numdaplot/tables/files/encoding.py +82 -0
- numdaplot/tables/files/excel_file.py +171 -0
- numdaplot/tables/files/excel_read_options.py +79 -0
- numdaplot/tables/files/excel_sheet.py +50 -0
- numdaplot/tables/files/excel_time_cells.py +146 -0
- numdaplot/tables/files/excel_write_options.py +63 -0
- numdaplot/tables/files/file_access.py +152 -0
- numdaplot/tables/files/file_paths.py +106 -0
- numdaplot/tables/files/json_decimals.py +387 -0
- numdaplot/tables/files/json_file.py +203 -0
- numdaplot/tables/files/json_layout.py +63 -0
- numdaplot/tables/files/json_read_options.py +64 -0
- numdaplot/tables/files/json_write_options.py +71 -0
- numdaplot/tables/files/missing_texts.py +63 -0
- numdaplot/tables/files/optional_package.py +42 -0
- numdaplot/tables/files/pandas_backend.py +11 -0
- numdaplot/tables/files/parquet_file.py +91 -0
- numdaplot/tables/files/parquet_read_options.py +56 -0
- numdaplot/tables/files/sas_file.py +94 -0
- numdaplot/tables/files/sas_read_options.py +67 -0
- numdaplot/tables/files/stata_file.py +83 -0
- numdaplot/tables/files/stata_read_options.py +56 -0
- numdaplot/tables/files/xpt_read_options.py +65 -0
- numdaplot/tables/filtering/__init__.py +5 -0
- numdaplot/tables/filtering/checked_frame.py +60 -0
- numdaplot/tables/filtering/column_mask.py +71 -0
- numdaplot/tables/filtering/column_match.py +62 -0
- numdaplot/tables/filtering/condition.py +94 -0
- numdaplot/tables/filtering/filter.py +74 -0
- numdaplot/tables/filtering/filter_mode.py +67 -0
- numdaplot/tables/filtering/row_mask.py +152 -0
- numdaplot/tables/filtering/rule_moments.py +164 -0
- numdaplot/tables/frames/__init__.py +5 -0
- numdaplot/tables/frames/array_frame.py +95 -0
- numdaplot/tables/frames/cleaned_names.py +132 -0
- numdaplot/tables/frames/column.py +15 -0
- numdaplot/tables/frames/column_values.py +273 -0
- numdaplot/tables/frames/frame_equality.py +130 -0
- numdaplot/tables/frames/frame_normalization.py +459 -0
- numdaplot/tables/frames/named_column_errors.py +85 -0
- numdaplot/tables/frames/pandas_decimals.py +113 -0
- numdaplot/tables/frames/region_positions.py +113 -0
- numdaplot/tables/frames/table_text.py +222 -0
- numdaplot/tables/frames/time_columns.py +345 -0
- numdaplot/tables/frames/time_range_errors.py +117 -0
- numdaplot/tables/frames/time_zones.py +271 -0
- numdaplot/tables/joining/__init__.py +5 -0
- numdaplot/tables/joining/join.py +110 -0
- numdaplot/tables/joining/join_keys.py +367 -0
- numdaplot/tables/joining/join_mode.py +93 -0
- numdaplot/tables/joining/join_relation.py +149 -0
- numdaplot/tables/joining/join_suffixes.py +71 -0
- numdaplot/tables/joining/joined_frame.py +166 -0
- numdaplot/tables/joining/joined_names.py +107 -0
- numdaplot/tables/joining/joined_rows.py +235 -0
- numdaplot/tables/joining/key_types.py +57 -0
- numdaplot/tables/joining/relation.py +78 -0
- numdaplot/tables/missing/__init__.py +5 -0
- numdaplot/tables/missing/missing_count.py +59 -0
- numdaplot/tables/missing/missing_counts.py +214 -0
- numdaplot/tables/missing/missing_drop.py +98 -0
- numdaplot/tables/missing/missing_mode.py +63 -0
- numdaplot/tables/missing/missing_ratio.py +71 -0
- numdaplot/tables/missing/missing_removal.py +257 -0
- numdaplot/tables/missing/missing_summary.py +174 -0
- numdaplot/tables/missing/ratio_comparison.py +70 -0
- numdaplot/tables/pivot/__init__.py +5 -0
- numdaplot/tables/pivot/pivot_table.py +104 -0
- numdaplot/tables/pivot/pivoted_frame.py +244 -0
- numdaplot/tables/preview/__init__.py +5 -0
- numdaplot/tables/preview/notebook_display.py +238 -0
- numdaplot/tables/preview/preview.py +100 -0
- numdaplot/tables/preview/preview_rows.py +55 -0
- numdaplot/tables/preview/shown_columns.py +62 -0
- numdaplot/tables/preview/side.py +82 -0
- numdaplot/tables/sorting/__init__.py +5 -0
- numdaplot/tables/sorting/sort_key.py +71 -0
- numdaplot/tables/sorting/sorted_frame.py +81 -0
- numdaplot/tables/sorting/sorting.py +82 -0
- numdaplot/tables/table.py +71 -0
- numdaplot/tables/table_calculation.py +172 -0
- numdaplot/tables/table_columns.py +214 -0
- numdaplot/tables/table_conversion.py +351 -0
- numdaplot/tables/table_data.py +321 -0
- numdaplot/tables/table_display.py +56 -0
- numdaplot/tables/table_joining.py +80 -0
- numdaplot/tables/table_layout.py +105 -0
- numdaplot/tables/table_missing.py +146 -0
- numdaplot/tables/table_reading.py +451 -0
- numdaplot/tables/table_refusals.py +295 -0
- numdaplot/tables/table_selection.py +163 -0
- numdaplot/tables/table_writing.py +269 -0
- numdaplot-0.1.0.dist-info/METADATA +176 -0
- numdaplot-0.1.0.dist-info/RECORD +474 -0
- numdaplot-0.1.0.dist-info/WHEEL +4 -0
- numdaplot-0.1.0.dist-info/licenses/LICENSE +28 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Rule keeping the values that are not missing.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from numdaplot.rules.rule import Rule
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class IsPresent(Rule):
|
|
14
|
+
"""
|
|
15
|
+
Keep the values that are not missing. It is the opposite of ``IsMissing``.
|
|
16
|
+
|
|
17
|
+
.. versionadded:: 0.1.0
|
|
18
|
+
|
|
19
|
+
Examples
|
|
20
|
+
--------
|
|
21
|
+
>>> import numdaplot as ndp
|
|
22
|
+
>>> temperatures = ndp.Array.from_list([12.5, None, 18.0])
|
|
23
|
+
>>> temperatures.select(ndp.IsPresent())
|
|
24
|
+
Array([12.5, 18. ], dtype=FLOAT64)
|
|
25
|
+
"""
|
numdaplot/rules/less.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Rule keeping the values strictly less than a reference value.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from numdaplot.rules.rule_values import OrderedValue
|
|
10
|
+
from numdaplot.rules.value_rule import ValueRule
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class Less(ValueRule[OrderedValue]):
|
|
15
|
+
"""
|
|
16
|
+
Keep the values strictly less than a reference value.
|
|
17
|
+
|
|
18
|
+
.. versionadded:: 0.1.0
|
|
19
|
+
|
|
20
|
+
Parameters
|
|
21
|
+
----------
|
|
22
|
+
value
|
|
23
|
+
The reference value, an ``OrderedValue`` such as ``10``, ``"M"`` or ``date(2026, 1, 31)``, which is not
|
|
24
|
+
kept itself.
|
|
25
|
+
|
|
26
|
+
Raises
|
|
27
|
+
------
|
|
28
|
+
InvalidTypeError
|
|
29
|
+
When ``value`` is not a single value, such as an Array or a list.
|
|
30
|
+
|
|
31
|
+
Examples
|
|
32
|
+
--------
|
|
33
|
+
>>> import numdaplot as ndp
|
|
34
|
+
>>> prices = ndp.Array.from_list([80, 100, 120])
|
|
35
|
+
>>> prices.select(ndp.Less(100))
|
|
36
|
+
Array([80], dtype=INT64)
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
value: OrderedValue
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Rule keeping the values less than or equal to a reference value.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from numdaplot.rules.rule_values import OrderedValue
|
|
10
|
+
from numdaplot.rules.value_rule import ValueRule
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class LessOrEqual(ValueRule[OrderedValue]):
|
|
15
|
+
"""
|
|
16
|
+
Keep the values less than or equal to a reference value.
|
|
17
|
+
|
|
18
|
+
.. versionadded:: 0.1.0
|
|
19
|
+
|
|
20
|
+
Parameters
|
|
21
|
+
----------
|
|
22
|
+
value
|
|
23
|
+
The reference value, an ``OrderedValue`` such as ``10``, ``"M"`` or ``date(2026, 1, 31)``, which is kept itself.
|
|
24
|
+
|
|
25
|
+
Raises
|
|
26
|
+
------
|
|
27
|
+
InvalidTypeError
|
|
28
|
+
When ``value`` is not a single value, such as an Array or a list.
|
|
29
|
+
|
|
30
|
+
Examples
|
|
31
|
+
--------
|
|
32
|
+
>>> import numdaplot as ndp
|
|
33
|
+
>>> prices = ndp.Array.from_list([80, 100, 120])
|
|
34
|
+
>>> prices.select(ndp.LessOrEqual(100))
|
|
35
|
+
Array([ 80, 100], dtype=INT64)
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
value: OrderedValue
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Rule keeping the values different from a reference value.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from typing import ClassVar
|
|
9
|
+
|
|
10
|
+
from numdaplot.rules.rule_values import ScalarValue
|
|
11
|
+
from numdaplot.rules.value_rule import ValueRule
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class NotEqual(ValueRule[ScalarValue]):
|
|
16
|
+
"""
|
|
17
|
+
Keep the values different from a reference value.
|
|
18
|
+
|
|
19
|
+
Missing values are not kept: use ``IsMissing`` to test them.
|
|
20
|
+
|
|
21
|
+
.. versionadded:: 0.1.0
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
value
|
|
26
|
+
The reference value, a ``ScalarValue`` such as ``"Paris"``, ``10`` or ``True``.
|
|
27
|
+
|
|
28
|
+
Raises
|
|
29
|
+
------
|
|
30
|
+
RefusedOperationError
|
|
31
|
+
When ``value`` is None: ``IsPresent`` tests the missing values.
|
|
32
|
+
InvalidTypeError
|
|
33
|
+
When ``value`` is not a single value, such as an Array or a list.
|
|
34
|
+
|
|
35
|
+
Examples
|
|
36
|
+
--------
|
|
37
|
+
>>> import numdaplot as ndp
|
|
38
|
+
>>> countries = ndp.Array.from_list(["FR", "DE", "FR"])
|
|
39
|
+
>>> countries.select(ndp.NotEqual("FR"))
|
|
40
|
+
Array(['DE'], dtype=TEXT)
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
MISSING_VALUE_RULE: ClassVar[str | None] = "IsPresent"
|
|
44
|
+
|
|
45
|
+
value: ScalarValue
|
numdaplot/rules/rule.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base class of every rule.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from numdaplot.errors.refused_operation_error import RefusedOperationError
|
|
8
|
+
|
|
9
|
+
CONSTRUCTOR_OPERATION = "Creating a Rule with ndp.Rule()"
|
|
10
|
+
CONSTRUCTOR_ALTERNATIVE = "a rule such as ndp.Greater"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Rule:
|
|
14
|
+
"""
|
|
15
|
+
Base class of every rule, a test applied to each value of an Array or of Table columns.
|
|
16
|
+
|
|
17
|
+
A rule is immutable and checks its settings when it is created.
|
|
18
|
+
|
|
19
|
+
Only its subclasses are created: calling ``ndp.Rule()`` raises ``RefusedOperationError``.
|
|
20
|
+
|
|
21
|
+
Every rule, passed to ``Array.select``, ``Array.check``, ``Table.check`` and ``Condition``:
|
|
22
|
+
|
|
23
|
+
|Rule|What it keeps|Example|
|
|
24
|
+
|---|---|---|
|
|
25
|
+
|``Equal``|The values equal to a reference value|``ndp.Equal("Paris")``|
|
|
26
|
+
|``NotEqual``|The values different from a reference value|``ndp.NotEqual("Paris")``|
|
|
27
|
+
|``Greater``|The values strictly greater than a reference value|``ndp.Greater(10)``|
|
|
28
|
+
|``GreaterOrEqual``|The values greater than or equal to a reference value|``ndp.GreaterOrEqual(10)``|
|
|
29
|
+
|``Less``|The values strictly less than a reference value|``ndp.Less(10)``|
|
|
30
|
+
|``LessOrEqual``|The values less than or equal to a reference value|``ndp.LessOrEqual(10)``|
|
|
31
|
+
|``Between``|The values inside an interval|``ndp.Between(10, 20)``|
|
|
32
|
+
|``IsIn``|The values that belong to a list of accepted values|``ndp.IsIn(["Paris", "Lyon"])``|
|
|
33
|
+
|``Contains``|The texts that contain a given text|``ndp.Contains("Pa")``|
|
|
34
|
+
|``IsMissing``|The missing values|``ndp.IsMissing()``|
|
|
35
|
+
|``IsPresent``|The values that are not missing|``ndp.IsPresent()``|
|
|
36
|
+
|
|
37
|
+
.. versionadded:: 0.1.0
|
|
38
|
+
|
|
39
|
+
Examples
|
|
40
|
+
--------
|
|
41
|
+
>>> import numdaplot as ndp
|
|
42
|
+
>>> prices = ndp.Array.from_list([80, 120])
|
|
43
|
+
>>> for rule in [ndp.Greater(100), ndp.Less(100)]:
|
|
44
|
+
... print(prices.select(rule))
|
|
45
|
+
Array([120], dtype=INT64)
|
|
46
|
+
Array([80], dtype=INT64)
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def __init__(self) -> None:
|
|
50
|
+
"""
|
|
51
|
+
Refuse the creation of the base class itself, and let a subclass be created.
|
|
52
|
+
|
|
53
|
+
.. versionadded:: 0.1.0
|
|
54
|
+
|
|
55
|
+
Raises
|
|
56
|
+
------
|
|
57
|
+
RefusedOperationError
|
|
58
|
+
When the created object is a Rule and not one of its subclasses.
|
|
59
|
+
"""
|
|
60
|
+
created_class = type(self)
|
|
61
|
+
if created_class is Rule:
|
|
62
|
+
raise RefusedOperationError(CONSTRUCTOR_OPERATION, CONSTRUCTOR_ALTERNATIVE)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Kinds of values that a rule compares against.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from datetime import date, datetime, time, timedelta
|
|
8
|
+
|
|
9
|
+
type ScalarValue = bool | int | float | str | date | datetime | timedelta | time
|
|
10
|
+
"""
|
|
11
|
+
A single value: a boolean, a number, a text, a date, a datetime, a duration or a time of day.
|
|
12
|
+
|
|
13
|
+
It is a name used by the documentation and the annotations, not an object to create: pass the value itself,
|
|
14
|
+
such as ``True``, ``10``, ``2.5``, ``"Paris"``, ``date(2026, 1, 31)``, ``datetime(2026, 1, 31, 14, 30)`` or
|
|
15
|
+
``timedelta(days=1)`` or ``time(15, 35)``.
|
|
16
|
+
|
|
17
|
+
.. versionadded:: 0.1.0
|
|
18
|
+
|
|
19
|
+
Examples
|
|
20
|
+
--------
|
|
21
|
+
>>> import numdaplot as ndp
|
|
22
|
+
>>> countries = ndp.Array.from_list(["FR", "DE", "FR"])
|
|
23
|
+
>>> countries.check(ndp.Equal("FR"))
|
|
24
|
+
Array([ True, False, True], dtype=BOOL)
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
type OrderedValue = int | float | str | date | datetime | timedelta | time
|
|
28
|
+
"""
|
|
29
|
+
A single value that can be ordered: a number, a text in alphabetical order, a date, a datetime, a duration or a
|
|
30
|
+
time of day.
|
|
31
|
+
|
|
32
|
+
It is a name used by the documentation and the annotations, not an object to create: pass the value itself,
|
|
33
|
+
such as ``10``, ``2.5``, ``"Paris"``, ``date(2026, 1, 31)``, ``datetime(2026, 1, 31, 14, 30)`` or
|
|
34
|
+
``timedelta(days=1)`` or ``time(15, 35)``.
|
|
35
|
+
|
|
36
|
+
.. versionadded:: 0.1.0
|
|
37
|
+
|
|
38
|
+
Examples
|
|
39
|
+
--------
|
|
40
|
+
>>> import numdaplot as ndp
|
|
41
|
+
>>> prices = ndp.Array.from_list([80, 120])
|
|
42
|
+
>>> prices.select(ndp.Greater(100))
|
|
43
|
+
Array([120], dtype=INT64)
|
|
44
|
+
"""
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base class of the rules that compare each value to a single reference value.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from typing import ClassVar, cast
|
|
9
|
+
|
|
10
|
+
from numdaplot.errors.refused_operation_error import RefusedOperationError
|
|
11
|
+
from numdaplot.rules.rule import Rule
|
|
12
|
+
from numdaplot.settings.field_types import require_field_types
|
|
13
|
+
|
|
14
|
+
MISSING_VALUE_OPERATION = "{rule_name}(None)"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass(frozen=True)
|
|
18
|
+
class ValueRule[ReferenceValue](Rule):
|
|
19
|
+
"""
|
|
20
|
+
Base class of the rules that compare each value to a single reference value.
|
|
21
|
+
|
|
22
|
+
Two rules are equal only when they have the same class and the same reference value,
|
|
23
|
+
so ``Greater(1)`` and ``Less(1)`` are different.
|
|
24
|
+
|
|
25
|
+
.. versionadded:: 0.1.0
|
|
26
|
+
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
value
|
|
30
|
+
The reference value each tested value is compared to.
|
|
31
|
+
|
|
32
|
+
Raises
|
|
33
|
+
------
|
|
34
|
+
InvalidTypeError
|
|
35
|
+
When a setting is not of the type its annotation names.
|
|
36
|
+
RefusedOperationError
|
|
37
|
+
When ``value`` is None for a rule with a rule of its own for missing values, such as ``Equal(None)``.
|
|
38
|
+
|
|
39
|
+
Examples
|
|
40
|
+
--------
|
|
41
|
+
>>> import numdaplot as ndp
|
|
42
|
+
>>> limit = ndp.Greater(100)
|
|
43
|
+
>>> limit.value
|
|
44
|
+
100
|
|
45
|
+
>>> ndp.Array.from_list([80, 120]).select(limit)
|
|
46
|
+
Array([120], dtype=INT64)
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
# The rule testing missing values in place of this rule given None, such as IsMissing for Equal.
|
|
50
|
+
MISSING_VALUE_RULE: ClassVar[str | None] = None
|
|
51
|
+
|
|
52
|
+
value: ReferenceValue
|
|
53
|
+
|
|
54
|
+
def __post_init__(self) -> None:
|
|
55
|
+
"""
|
|
56
|
+
Check the reference value.
|
|
57
|
+
|
|
58
|
+
.. versionadded:: 0.1.0
|
|
59
|
+
|
|
60
|
+
Raises
|
|
61
|
+
------
|
|
62
|
+
InvalidTypeError
|
|
63
|
+
When a setting is not of the type its annotation names.
|
|
64
|
+
RefusedOperationError
|
|
65
|
+
When ``value`` is None for a rule with a rule of its own for missing values, such as ``Equal(None)``.
|
|
66
|
+
"""
|
|
67
|
+
rule_class = type(self)
|
|
68
|
+
value = cast(object, self.value)
|
|
69
|
+
refuse_missing_value(rule_class.__name__, self.MISSING_VALUE_RULE, value)
|
|
70
|
+
require_field_types(self)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def refuse_missing_value(rule_name: str, missing_value_rule: str | None, value: object) -> None:
|
|
74
|
+
"""
|
|
75
|
+
Refuse None as the reference value of a rule that has a rule of its own for missing values.
|
|
76
|
+
|
|
77
|
+
.. versionadded:: 0.1.0
|
|
78
|
+
|
|
79
|
+
Parameters
|
|
80
|
+
----------
|
|
81
|
+
rule_name
|
|
82
|
+
The name of the rule, such as ``"Equal"``.
|
|
83
|
+
missing_value_rule
|
|
84
|
+
The rule testing missing values in its place, such as ``"IsMissing"``, or None when there is none.
|
|
85
|
+
value
|
|
86
|
+
The reference value.
|
|
87
|
+
|
|
88
|
+
Raises
|
|
89
|
+
------
|
|
90
|
+
RefusedOperationError
|
|
91
|
+
When the value is None and the rule has a rule of its own for missing values.
|
|
92
|
+
|
|
93
|
+
Examples
|
|
94
|
+
--------
|
|
95
|
+
>>> import numdaplot as ndp
|
|
96
|
+
>>> from numdaplot.rules.value_rule import refuse_missing_value
|
|
97
|
+
>>> try:
|
|
98
|
+
... refuse_missing_value("Equal", "IsMissing", None)
|
|
99
|
+
... except ndp.RefusedOperationError as error:
|
|
100
|
+
... print(error)
|
|
101
|
+
Equal(None) is not available, use IsMissing instead.
|
|
102
|
+
"""
|
|
103
|
+
if value is not None:
|
|
104
|
+
return
|
|
105
|
+
|
|
106
|
+
if missing_value_rule is None:
|
|
107
|
+
return
|
|
108
|
+
|
|
109
|
+
operation = MISSING_VALUE_OPERATION.format(rule_name=rule_name)
|
|
110
|
+
raise RefusedOperationError(operation, missing_value_rule)
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Check of the arguments of the public methods and functions against their annotations.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 0.1.0
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# typing.Self is a special form the type checker only knows inside annotations.
|
|
8
|
+
# pyright: reportUnknownMemberType=false
|
|
9
|
+
|
|
10
|
+
import functools
|
|
11
|
+
import inspect
|
|
12
|
+
import typing
|
|
13
|
+
from collections.abc import Callable
|
|
14
|
+
from typing import cast
|
|
15
|
+
|
|
16
|
+
from numdaplot.errors.invalid_type_error import InvalidTypeError
|
|
17
|
+
from numdaplot.settings.field_types import (
|
|
18
|
+
AcceptedKinds,
|
|
19
|
+
accepts_value,
|
|
20
|
+
describe_kinds,
|
|
21
|
+
find_rejected_value,
|
|
22
|
+
read_accepted_kinds,
|
|
23
|
+
read_annotations,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
INSTANCE_PARAMETER = "self"
|
|
27
|
+
CLASS_PARAMETER = "cls"
|
|
28
|
+
CONSTRUCTOR_NAME = "__init__"
|
|
29
|
+
TARGET_FORMAT = "{callable_name} {parameter_name}"
|
|
30
|
+
METHOD_NAME_FORMAT = "{owner_name}.{method_name}"
|
|
31
|
+
OPERATOR_NAME_FORMAT = "{owner_name} {symbol}"
|
|
32
|
+
OPERATOR_SYMBOLS = {
|
|
33
|
+
"__add__": "+",
|
|
34
|
+
"__radd__": "+",
|
|
35
|
+
"__sub__": "-",
|
|
36
|
+
"__rsub__": "-",
|
|
37
|
+
"__mul__": "*",
|
|
38
|
+
"__rmul__": "*",
|
|
39
|
+
"__truediv__": "/",
|
|
40
|
+
"__rtruediv__": "/",
|
|
41
|
+
"__floordiv__": "//",
|
|
42
|
+
"__rfloordiv__": "//",
|
|
43
|
+
"__mod__": "%",
|
|
44
|
+
"__rmod__": "%",
|
|
45
|
+
"__pow__": "**",
|
|
46
|
+
"__rpow__": "**",
|
|
47
|
+
"__and__": "&",
|
|
48
|
+
"__rand__": "&",
|
|
49
|
+
"__or__": "|",
|
|
50
|
+
"__ror__": "|",
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def checked_arguments[**Parameters, Result](function: Callable[Parameters, Result]) -> Callable[Parameters, Result]:
|
|
55
|
+
"""
|
|
56
|
+
Make a method or a function check its arguments against its annotations at each call.
|
|
57
|
+
|
|
58
|
+
The annotations are read once, at the first call. An argument left to its default is not checked.
|
|
59
|
+
|
|
60
|
+
.. versionadded:: 0.1.0
|
|
61
|
+
|
|
62
|
+
Parameters
|
|
63
|
+
----------
|
|
64
|
+
function
|
|
65
|
+
The method or the function.
|
|
66
|
+
|
|
67
|
+
Returns
|
|
68
|
+
-------
|
|
69
|
+
Callable
|
|
70
|
+
The same function, with the same signature, refusing an argument of the wrong type.
|
|
71
|
+
|
|
72
|
+
Examples
|
|
73
|
+
--------
|
|
74
|
+
>>> import numdaplot as ndp
|
|
75
|
+
>>> try:
|
|
76
|
+
... ndp.Array.from_list([1, 2]).sort(5)
|
|
77
|
+
... except ndp.InvalidTypeError as error:
|
|
78
|
+
... print(error)
|
|
79
|
+
Array.sort sorting expects an ArraySorting or None, got 5.
|
|
80
|
+
"""
|
|
81
|
+
parameter_names = tuple(inspect.signature(function).parameters)
|
|
82
|
+
|
|
83
|
+
@functools.wraps(function)
|
|
84
|
+
def call_after_check(*args: Parameters.args, **kwargs: Parameters.kwargs) -> Result:
|
|
85
|
+
"""
|
|
86
|
+
Check the given arguments, then call the function.
|
|
87
|
+
|
|
88
|
+
.. versionadded:: 0.1.0
|
|
89
|
+
|
|
90
|
+
Parameters
|
|
91
|
+
----------
|
|
92
|
+
args
|
|
93
|
+
The positional arguments.
|
|
94
|
+
kwargs
|
|
95
|
+
The named arguments.
|
|
96
|
+
|
|
97
|
+
Returns
|
|
98
|
+
-------
|
|
99
|
+
Result
|
|
100
|
+
What the function returns.
|
|
101
|
+
|
|
102
|
+
Raises
|
|
103
|
+
------
|
|
104
|
+
InvalidTypeError
|
|
105
|
+
When an argument is not of the type its annotation names.
|
|
106
|
+
"""
|
|
107
|
+
owner = find_owner(parameter_names, args)
|
|
108
|
+
argument_kinds = find_argument_kinds(function, owner)
|
|
109
|
+
named_arguments = zip(parameter_names, args, strict=False)
|
|
110
|
+
|
|
111
|
+
for parameter_name, value in named_arguments:
|
|
112
|
+
require_argument_type(function, owner, argument_kinds.get(parameter_name), (parameter_name, value))
|
|
113
|
+
|
|
114
|
+
for parameter_name, value in kwargs.items():
|
|
115
|
+
require_argument_type(function, owner, argument_kinds.get(parameter_name), (parameter_name, value))
|
|
116
|
+
|
|
117
|
+
return function(*args, **kwargs)
|
|
118
|
+
|
|
119
|
+
return call_after_check
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def find_owner(parameter_names: tuple[str, ...], args: tuple[object, ...]) -> type | None:
|
|
123
|
+
"""
|
|
124
|
+
Return the class a method is called on, or None for a function.
|
|
125
|
+
|
|
126
|
+
.. versionadded:: 0.1.0
|
|
127
|
+
|
|
128
|
+
Parameters
|
|
129
|
+
----------
|
|
130
|
+
parameter_names
|
|
131
|
+
The names of the parameters of the method or the function.
|
|
132
|
+
args
|
|
133
|
+
The positional arguments of the call.
|
|
134
|
+
|
|
135
|
+
Returns
|
|
136
|
+
-------
|
|
137
|
+
type or None
|
|
138
|
+
The class of ``self``, the ``cls`` itself, or None.
|
|
139
|
+
|
|
140
|
+
Examples
|
|
141
|
+
--------
|
|
142
|
+
>>> from numdaplot.settings.argument_types import find_owner
|
|
143
|
+
>>> find_owner(("self", "other"), (1, 2))
|
|
144
|
+
<class 'int'>
|
|
145
|
+
>>> find_owner(("data",), (1,)) is None
|
|
146
|
+
True
|
|
147
|
+
"""
|
|
148
|
+
if not parameter_names:
|
|
149
|
+
return None
|
|
150
|
+
|
|
151
|
+
first_name = parameter_names[0]
|
|
152
|
+
if first_name == INSTANCE_PARAMETER:
|
|
153
|
+
return type(args[0])
|
|
154
|
+
|
|
155
|
+
if first_name == CLASS_PARAMETER:
|
|
156
|
+
return cast(type, args[0])
|
|
157
|
+
|
|
158
|
+
return None
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
@functools.cache
|
|
162
|
+
def find_argument_kinds(function: Callable[..., object], owner: type | None) -> dict[str, AcceptedKinds]:
|
|
163
|
+
"""
|
|
164
|
+
Return what each parameter of a method or a function accepts, read once for each class.
|
|
165
|
+
|
|
166
|
+
.. versionadded:: 0.1.0
|
|
167
|
+
|
|
168
|
+
Parameters
|
|
169
|
+
----------
|
|
170
|
+
function
|
|
171
|
+
The method or the function.
|
|
172
|
+
owner
|
|
173
|
+
The class it is called on, which ``Self`` names in its annotations, or None for a function.
|
|
174
|
+
|
|
175
|
+
Returns
|
|
176
|
+
-------
|
|
177
|
+
dict[str, AcceptedKinds]
|
|
178
|
+
What each annotated parameter accepts.
|
|
179
|
+
|
|
180
|
+
Examples
|
|
181
|
+
--------
|
|
182
|
+
>>> import numdaplot as ndp
|
|
183
|
+
>>> from numdaplot.settings.argument_types import find_argument_kinds
|
|
184
|
+
>>> find_argument_kinds(ndp.Plot.missing_map, None)["table"].names
|
|
185
|
+
('Table',)
|
|
186
|
+
"""
|
|
187
|
+
annotations = read_annotations(function)
|
|
188
|
+
annotations.pop("return", None)
|
|
189
|
+
argument_kinds = dict[str, AcceptedKinds]()
|
|
190
|
+
|
|
191
|
+
for parameter_name, annotation in annotations.items():
|
|
192
|
+
owned_annotation = replace_self(annotation, owner)
|
|
193
|
+
argument_kinds[parameter_name] = read_accepted_kinds(owned_annotation)
|
|
194
|
+
|
|
195
|
+
return argument_kinds
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def replace_self(annotation: object, owner: type | None) -> object:
|
|
199
|
+
"""
|
|
200
|
+
Return an annotation with ``Self`` replaced by the class a method is called on.
|
|
201
|
+
|
|
202
|
+
.. versionadded:: 0.1.0
|
|
203
|
+
|
|
204
|
+
Parameters
|
|
205
|
+
----------
|
|
206
|
+
annotation
|
|
207
|
+
The annotation.
|
|
208
|
+
owner
|
|
209
|
+
The class, or None for a function.
|
|
210
|
+
|
|
211
|
+
Returns
|
|
212
|
+
-------
|
|
213
|
+
object
|
|
214
|
+
The annotation naming the class.
|
|
215
|
+
|
|
216
|
+
Examples
|
|
217
|
+
--------
|
|
218
|
+
>>> from typing import Self
|
|
219
|
+
>>> from numdaplot.settings.argument_types import replace_self
|
|
220
|
+
>>> replace_self(Self | None, int) == int | None
|
|
221
|
+
True
|
|
222
|
+
"""
|
|
223
|
+
if annotation is typing.Self:
|
|
224
|
+
return owner
|
|
225
|
+
|
|
226
|
+
members = typing.get_args(annotation)
|
|
227
|
+
has_self = typing.Self in members
|
|
228
|
+
if not has_self:
|
|
229
|
+
return annotation
|
|
230
|
+
|
|
231
|
+
owned_members = tuple(owner if member is typing.Self else member for member in members)
|
|
232
|
+
owned_union = cast(object, typing.Union[owned_members]) # noqa: UP007
|
|
233
|
+
|
|
234
|
+
return owned_union
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def require_argument_type(
|
|
238
|
+
function: Callable[..., object],
|
|
239
|
+
owner: type | None,
|
|
240
|
+
kinds: AcceptedKinds | None,
|
|
241
|
+
argument: tuple[str, object],
|
|
242
|
+
) -> None:
|
|
243
|
+
"""
|
|
244
|
+
Check one argument of a call.
|
|
245
|
+
|
|
246
|
+
.. versionadded:: 0.1.0
|
|
247
|
+
|
|
248
|
+
Parameters
|
|
249
|
+
----------
|
|
250
|
+
function
|
|
251
|
+
The method or the function called.
|
|
252
|
+
owner
|
|
253
|
+
The class it is called on, or None.
|
|
254
|
+
kinds
|
|
255
|
+
What the parameter accepts, or None when it has no annotation, such as ``self``.
|
|
256
|
+
argument
|
|
257
|
+
The name of the parameter and the given value.
|
|
258
|
+
|
|
259
|
+
Raises
|
|
260
|
+
------
|
|
261
|
+
InvalidTypeError
|
|
262
|
+
When the value is not of an accepted kind.
|
|
263
|
+
|
|
264
|
+
Examples
|
|
265
|
+
--------
|
|
266
|
+
>>> import numdaplot as ndp
|
|
267
|
+
>>> from numdaplot.settings.argument_types import require_argument_type
|
|
268
|
+
>>> from numdaplot.settings.field_types import read_accepted_kinds
|
|
269
|
+
>>> try:
|
|
270
|
+
... require_argument_type(ndp.Plot.line, ndp.Plot, read_accepted_kinds(str), ("chart", 5))
|
|
271
|
+
... except ndp.InvalidTypeError as error:
|
|
272
|
+
... print(error)
|
|
273
|
+
Plot.line chart expects a str, got 5.
|
|
274
|
+
"""
|
|
275
|
+
if kinds is None:
|
|
276
|
+
return
|
|
277
|
+
|
|
278
|
+
parameter_name, value = argument
|
|
279
|
+
is_accepted = accepts_value(kinds, value)
|
|
280
|
+
if is_accepted:
|
|
281
|
+
return
|
|
282
|
+
|
|
283
|
+
callable_name = name_callable(function, owner)
|
|
284
|
+
target_name = TARGET_FORMAT.format(callable_name=callable_name, parameter_name=parameter_name)
|
|
285
|
+
expected = describe_kinds(kinds, value)
|
|
286
|
+
rejected_value = find_rejected_value(kinds, value)
|
|
287
|
+
raise InvalidTypeError(target_name, expected, rejected_value)
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def name_callable(function: Callable[..., object], owner: type | None) -> str:
|
|
291
|
+
"""
|
|
292
|
+
Return the name of a method or a function, as the user writes it.
|
|
293
|
+
|
|
294
|
+
.. versionadded:: 0.1.0
|
|
295
|
+
|
|
296
|
+
Parameters
|
|
297
|
+
----------
|
|
298
|
+
function
|
|
299
|
+
The method or the function.
|
|
300
|
+
owner
|
|
301
|
+
The class it is called on, or None.
|
|
302
|
+
|
|
303
|
+
Returns
|
|
304
|
+
-------
|
|
305
|
+
str
|
|
306
|
+
``Plot.line``, ``Table.filter``, ``Array +``, or ``Figure`` for a constructor.
|
|
307
|
+
|
|
308
|
+
Examples
|
|
309
|
+
--------
|
|
310
|
+
>>> import numdaplot as ndp
|
|
311
|
+
>>> from numdaplot.settings.argument_types import name_callable
|
|
312
|
+
>>> name_callable(ndp.Array.__add__, ndp.Array)
|
|
313
|
+
'Array +'
|
|
314
|
+
"""
|
|
315
|
+
function_name = function.__name__
|
|
316
|
+
if owner is None:
|
|
317
|
+
return function_name
|
|
318
|
+
|
|
319
|
+
owner_name = owner.__name__
|
|
320
|
+
if function_name == CONSTRUCTOR_NAME:
|
|
321
|
+
return owner_name
|
|
322
|
+
|
|
323
|
+
symbol = OPERATOR_SYMBOLS.get(function_name)
|
|
324
|
+
if symbol is not None:
|
|
325
|
+
return OPERATOR_NAME_FORMAT.format(owner_name=owner_name, symbol=symbol)
|
|
326
|
+
|
|
327
|
+
return METHOD_NAME_FORMAT.format(owner_name=owner_name, method_name=function_name)
|