tabalyst 0.7.4__tar.gz → 0.7.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tabalyst-0.7.4/src/tabalyst.egg-info → tabalyst-0.7.6}/PKG-INFO +6 -4
- {tabalyst-0.7.4 → tabalyst-0.7.6}/README.md +5 -3
- {tabalyst-0.7.4 → tabalyst-0.7.6}/pyproject.toml +1 -1
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/cli/generate.py +1 -1
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/cli/report.py +4 -1
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/config.py +7 -3
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_computer.py +12 -1
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_definition.py +160 -7
- tabalyst-0.7.6/src/tabalyst/generate_draws.py +24 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/dataset.yaml +13 -0
- tabalyst-0.7.6/src/tabalyst/generate_examples/crm/dataset.yaml +152 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/crm/schemas/contacts.yaml +164 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/dataset.yaml +57 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_insurance.py +90 -19
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_package.py +1 -1
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_values.py +140 -4
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/models.py +3 -3
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_chain.py +1 -1
- tabalyst-0.7.6/src/tabalyst/report_charts.py +227 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_deep.py +17 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_insights.py +259 -34
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_labels.py +1 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_service.py +6 -1
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_views.py +16 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/reporting.py +52 -4
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzer.py +3 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/__init__.py +2 -1
- tabalyst-0.7.6/src/tabalyst/scanner/planner/analyzers/matrix.py +113 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/costmodel.py +10 -1
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/facts.py +20 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/planner.py +3 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/reasons.py +2 -1
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/secondpass.py +9 -2
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/executor.py +29 -2
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/matrix.py +149 -17
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/models.py +45 -1
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/schemas/tabalyst.report.schema.json +143 -4
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/schemas/tabalyst.scan.deep.schema.json +142 -3
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/service.py +84 -18
- tabalyst-0.7.6/src/tabalyst/static/charts.js +197 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/static/theme.css +15 -0
- tabalyst-0.7.6/src/tabalyst/templates/charts.html +89 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/templates/column.html +2 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/templates/insights.html +3 -2
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/templates/report.html +4 -3
- {tabalyst-0.7.4 → tabalyst-0.7.6/src/tabalyst.egg-info}/PKG-INFO +6 -4
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst.egg-info/SOURCES.txt +4 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_generate.py +238 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_generate_anomalies_regression.py +85 -38
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_generate_computer_output.py +7 -4
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_generate_computer_service.py +39 -0
- tabalyst-0.7.6/tests/test_generate_crm.py +126 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_generate_crm_package.py +4 -4
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_generate_insurance.py +71 -13
- tabalyst-0.7.4/src/tabalyst/generate_examples/crm/dataset.yaml +0 -76
- tabalyst-0.7.4/src/tabalyst/scanner/planner/analyzers/matrix.py +0 -59
- tabalyst-0.7.4/tests/test_generate_crm.py +0 -51
- {tabalyst-0.7.4 → tabalyst-0.7.6}/LICENSE +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/MANIFEST.in +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/examples/README.md +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/examples/config.json +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/examples/datasets/basic.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/examples/datasets/insurance-customers.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/examples/generate/README.md +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/examples/generate/cohorts-anomalies/catalog.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/examples/generate/cohorts-anomalies/dataset.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/examples/generate/cohorts-anomalies/schemas/accounts.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/examples/generate/cohorts-anomalies/schemas/contacts.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/examples/generate/common-references/catalog.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/examples/generate/common-references/dataset.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/examples/generate/common-references/schemas/contacts.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/examples/generate/generate_examples.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/setup.cfg +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/__init__.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/__main__.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/_version.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/batch.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/cache_service.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/cli/__init__.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/cli/app.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/cli/cache.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/cli/confirm.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/cli/dedup.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/cli/inspect.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/cli/sample.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/cli/scan.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/cli/terminal.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/csv_records.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/__init__.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/analysis.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/batch_report.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/cache.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/calculation.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/count_only.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/discovery.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/diskstore.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/failures.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/groups.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/identity.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/pipeline.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/publish.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/report.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/settings.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/store.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/tiered.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup/writer.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/dedup_service.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/deep_service.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/deep_store.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/errors.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/execution_log.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_anomalies.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_columns_package.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_computer_output.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_computer_parallel.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_csv.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/SOURCES.md +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/catalog.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/brand.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/color.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/computer_type.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/computer_type_form_factor.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/computer_type_product_segment.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/cpu.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/cpu_memory_weight.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/cpu_operating_system.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/display.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/extended_specs.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/form_factor.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/generation_color.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/generation_cpu.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/generation_display.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/generation_gpu.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/generation_memory.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/generation_operating_system.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/generation_profile.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/generation_profile_computer_type.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/generation_profile_segment.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/generation_storage.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/gpu.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/gpu_display.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/gpu_memory_weight.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/gpu_storage_weight.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/memory.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/model_form_factor.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/model_generation.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/operating_system.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/product_category.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/product_family.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/product_family_computer_type.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/product_family_product_segment.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/product_model.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/product_segment.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/product_segment_brand.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/product_segment_display_weight.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/product_segment_memory_weight.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/product_segment_storage_weight.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/product_subcategory.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/profile_exclusions.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/promotion_status.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/promotion_type.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/seller.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/seller_type.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/shipping_availability.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/standard_specs.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/storage.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/data/warehouse.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/computer_type.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/computer_type_form_factor.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/computer_type_product_segment.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/computers.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/cpu.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/cpu_memory_weight.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/cpu_operating_system.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/display.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/extended_specs.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/generation_color.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/generation_cpu.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/generation_display.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/generation_gpu.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/generation_memory.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/generation_operating_system.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/generation_profile.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/generation_profile_computer_type.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/generation_profile_segment.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/generation_storage.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/gpu.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/gpu_display.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/gpu_memory_weight.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/gpu_storage_weight.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/localized.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/memory.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/model_form_factor.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/model_generation.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/operating_system.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/product_family.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/product_family_computer_type.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/product_family_product_segment.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/product_model.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/product_segment.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/product_segment_brand.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/product_segment_display_weight.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/product_segment_memory_weight.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/product_segment_storage_weight.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/product_subcategory.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/profile_exclusions.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/seller.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/standard_specs.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/storage.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/computer/schemas/warehouse.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/crm/catalog.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/crm/schemas/accounts.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/SOURCES.md +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/catalog.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/data/agencies.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/data/branch_contract_weights.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/data/claim_statuses.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/data/contract_statuses.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/data/contract_types.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/data/payment_frequencies.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/data/payment_methods.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/schemas/agencies.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/schemas/branch_contract_weights.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/schemas/claim_statuses.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/schemas/contract_statuses.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/schemas/contract_types.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/schemas/customers.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/schemas/payment_frequencies.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_examples/insurance/schemas/payment_methods.yaml +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_references.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_resources/SOURCES.md +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_resources/addresses/street_directions_ca.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_resources/addresses/street_names_ca.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_resources/addresses/street_types_ca.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_resources/addresses/unit_types_ca.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_resources/contact/email_patterns.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_resources/contact/email_providers_ca.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_resources/contact/phone_area_codes_ca.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_resources/geography/cities_ca.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_resources/geography/postal_prefixes_ca.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_resources/geography/provinces_ca.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_resources/people/family_names_ca.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_resources/people/first_names_en_ca.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_resources/people/first_names_fr_qc.csv +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_selection.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/generate_service.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/identifier_uniqueness/__init__.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/identifier_uniqueness/facts.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/identifier_uniqueness/models.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/identifier_uniqueness/near_unique.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/identifier_uniqueness/proof.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/identifier_uniqueness/rule.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/inspect_service.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/inspector/__init__.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/inspector/choices.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/inspector/excel_inspect/__init__.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/inspector/excel_inspect/build.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/inspector/excel_inspect/detect.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/inspector/excel_inspect/parameters.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/inspector/json_inspect/__init__.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/inspector/json_inspect/build.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/inspector/json_inspect/detect.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/inspector/json_inspect/parameters.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/inspector/models.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/inspector/persistence.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/inspector/resolution.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/json_text.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/option_notices.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/plan_service.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/progress.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/project_open_service.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/project_scan_service.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/__init__.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/_bounded_values.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/_cache.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/_codec.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/_generation.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/_locks.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/_publication.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/_queries.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/_query_budget.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/_recovery.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/_retention.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/_schema.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/_session.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/_staging.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/_sync.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/_validation.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/catalog.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/freshness.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/identity.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/index.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/location.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/models.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/projects/store.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_classification.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_column_page.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_config.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_details.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_finding_details.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_findings.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_measures.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_overview.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_plan.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_preview.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_profile.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_relations.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_schema.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_sections.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_signals.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_summary.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_table.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/report_uniqueness.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/result_model.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/sample_page.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/sampling.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/sampling_service.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scan_document.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scan_page.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scan_reuse.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scan_service.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/__init__.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/api.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/bottomk.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/cases.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/charactermap.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/characters.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/classify/__init__.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/classify/candidates.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/classify/catalog.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/classify/identifiers.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/classify/models.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/classify/names.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/classify/rules.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/config.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/convention_rule.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/correlation_ratio.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/crosstab.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/__init__.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/amount.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/base.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/boolean.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/currency.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/email.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/enumeration.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/ip.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/keys.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/names.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/number.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/pattern.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/percentage.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/phone.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/postal.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/quantity.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/registry.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/shape.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/temporal.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/url.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/detectors/uuid.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/diagnostics.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/engine.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/exposure.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/features.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/field.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/identity.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/lengthsample.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/longtext.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/measures.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/memory.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/models.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/normalization.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/observations.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/paths.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/pattern_eligibility.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/patternfacets.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/patterninfer.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/patterntree.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/pearson.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/__init__.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/analytical.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/characters.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/common.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/copies.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/crosstab.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/date_order.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/distinct.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/drift.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/duplicates.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/forms.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/frequencies.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/histogram.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/lengths.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/measures.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/missing_copies.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/parts.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/patterns.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/pearson.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/residuals.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/shape.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/stats.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/structure.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/temporal.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/analyzers/texts.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/categorystats.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/crosstabs.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/identifiers.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/models.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/orders.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/registry.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/relations.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/render.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/samplerows.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/stratification.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/planner/stratmodels.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/process.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/quality.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/rankcorr.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/readers/__init__.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/readers/base.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/readers/csv_reader.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/readers/excel_common.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/readers/excel_reader.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/readers/excel_table.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/readers/factory.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/readers/json_common.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/readers/json_reader.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/readers/jsonl_reader.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/records.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/rowsample.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/schema.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/__init__.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/accumulators.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/analytical.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/bins.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/boundaries.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/characters.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/copies.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/crosstab.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/document.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/drift.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/duplicates.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/exactset.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/forms.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/frequencies.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/measures.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/missing_copies.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/orders.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/parallel.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/parts.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/patternreader.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/patterns.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/pearson.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/periods.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/ranks.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/replay.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/residuals.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/routing.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/schema.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/shape.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/stats.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/structure.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/secondpass/texts.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/smart/__init__.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/smart/bins.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/smart/estimate.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/smart/evaluate.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/smart/execute.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/smart/models.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/smart/near.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/smart/plan.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/smart/reasons.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/smart/render.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/smart/result.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/smart/select.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/smart/targets.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/smart/weights.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/stratify.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/structure.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/technical.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/validation.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/values.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/valuesample.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/scanner/workers.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/schemas/tabalyst.dedup.batch.schema.json +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/schemas/tabalyst.dedup.schema.json +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/schemas/tabalyst.sample.schema.json +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/schemas/tabalyst.scan.schema.json +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/shared_scan_service.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/smart_service.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/source_guard.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/static/report.js +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/summary_models.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/templates/characters.html +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/templates/patterns.html +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst/templates/sample.html +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst.egg-info/dependency_links.txt +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst.egg-info/entry_points.txt +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst.egg-info/requires.txt +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/src/tabalyst.egg-info/top_level.txt +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_all_collections.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_cli.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_csv_records.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_examples_index.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_examples_layout.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_generate_anomalies.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_generate_computer_catalog.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_generate_computer_components.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_generate_computer_derivations.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_generate_computer_hierarchy.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_generate_computer_parallel.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_generate_insurance_stress.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_generate_lot4.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_generate_package.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_generate_references.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_generate_selection.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_json_text.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_license_headers.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_make_datasets.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_option_notices.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_project_cache.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_project_database.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_project_generations.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_project_identity.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_project_index.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_project_location.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_project_open_service.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_project_queries.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_project_rescan.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_project_scan.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_project_scan_model.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_project_sessions.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_project_store.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_public_api.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_report_contrast.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_reporting.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_sampling.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_sampling_stratified_balanced.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_scan_command.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_scanner_amounts.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_scanner_batches.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_scanner_config.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_scanner_csv.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_scanner_email_url.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_scanner_exposure.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_scanner_paths.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_scanner_phone.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_scanner_postal.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_scanner_uuid_ip.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_shared_scan_cli.py +0 -0
- {tabalyst-0.7.4 → tabalyst-0.7.6}/tests/test_source_freshness.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tabalyst
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.6
|
|
4
4
|
Summary: Open-source toolkit for understanding and working with unfamiliar data.
|
|
5
5
|
Author: Gregory Borelli
|
|
6
6
|
License-Expression: MPL-2.0
|
|
@@ -114,8 +114,9 @@ customers.json
|
|
|
114
114
|
executions.json
|
|
115
115
|
```
|
|
116
116
|
|
|
117
|
-
Add `--details` to
|
|
118
|
-
|
|
117
|
+
Add `--details` to write one HTML page per column and the chart pages, such as
|
|
118
|
+
the combinations of missing values (it also runs the second pass), and `-o` to
|
|
119
|
+
choose another HTML filename for one source:
|
|
119
120
|
|
|
120
121
|
```console
|
|
121
122
|
tabalyst report customers.csv --details
|
|
@@ -164,7 +165,8 @@ Details: [Tabalyst Report](https://docs.tabalyst.com/report/),
|
|
|
164
165
|
The report is built on Tabalyst Scan; values of sensitive columns can be masked
|
|
165
166
|
or hidden. Ambiguous dates stay
|
|
166
167
|
ambiguous; the report shows the evidence of the column without applying it. The
|
|
167
|
-
HTML report is self-contained and works without a CDN or network connection
|
|
168
|
+
HTML report is self-contained and works without a CDN or network connection;
|
|
169
|
+
only the chart pages of `--details` load Apache ECharts from a CDN to draw.
|
|
168
170
|
The JSON profile contains the same canonical analysis result for scripts and
|
|
169
171
|
future Tabalyst tools. See
|
|
170
172
|
[how to read the report](https://docs.tabalyst.com/report/read-report/).
|
|
@@ -74,8 +74,9 @@ customers.json
|
|
|
74
74
|
executions.json
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
Add `--details` to
|
|
78
|
-
|
|
77
|
+
Add `--details` to write one HTML page per column and the chart pages, such as
|
|
78
|
+
the combinations of missing values (it also runs the second pass), and `-o` to
|
|
79
|
+
choose another HTML filename for one source:
|
|
79
80
|
|
|
80
81
|
```console
|
|
81
82
|
tabalyst report customers.csv --details
|
|
@@ -124,7 +125,8 @@ Details: [Tabalyst Report](https://docs.tabalyst.com/report/),
|
|
|
124
125
|
The report is built on Tabalyst Scan; values of sensitive columns can be masked
|
|
125
126
|
or hidden. Ambiguous dates stay
|
|
126
127
|
ambiguous; the report shows the evidence of the column without applying it. The
|
|
127
|
-
HTML report is self-contained and works without a CDN or network connection
|
|
128
|
+
HTML report is self-contained and works without a CDN or network connection;
|
|
129
|
+
only the chart pages of `--details` load Apache ECharts from a CDN to draw.
|
|
128
130
|
The JSON profile contains the same canonical analysis result for scripts and
|
|
129
131
|
future Tabalyst tools. See
|
|
130
132
|
[how to read the report](https://docs.tabalyst.com/report/read-report/).
|
|
@@ -114,7 +114,7 @@ def generate_command(
|
|
|
114
114
|
] = None,
|
|
115
115
|
anomaly_profile: Annotated[
|
|
116
116
|
str | None,
|
|
117
|
-
typer.Option("--anomaly-profile", help="Inject errors. Computer: dirty_realistic, dirty_stress, unit_variants, unit_variants_extended; several, comma separated, with -d."),
|
|
117
|
+
typer.Option("--anomaly-profile", help="Inject errors. Computer: dirty_realistic, dirty_stress, unit_variants, unit_variants_extended, rule_breaks; every example has rule_breaks; several, comma separated, with -d."),
|
|
118
118
|
] = None,
|
|
119
119
|
request: Annotated[
|
|
120
120
|
Path | None,
|
|
@@ -210,7 +210,10 @@ def report_command(
|
|
|
210
210
|
bool,
|
|
211
211
|
typer.Option(
|
|
212
212
|
"--details/--no-details",
|
|
213
|
-
help=
|
|
213
|
+
help=(
|
|
214
|
+
"Also write a page for every column and the chart pages, which "
|
|
215
|
+
"load Apache ECharts from a CDN. Forces the second pass, as --deep."
|
|
216
|
+
),
|
|
214
217
|
),
|
|
215
218
|
] = False,
|
|
216
219
|
quiet: Annotated[
|
|
@@ -431,18 +431,22 @@ class DriftSettings(BaseModel):
|
|
|
431
431
|
|
|
432
432
|
|
|
433
433
|
class MissingSettings(BaseModel):
|
|
434
|
-
"""How the values missing together are counted (design 20.31).
|
|
434
|
+
"""How the values missing together are counted (design 20.31 and 20.44).
|
|
435
435
|
|
|
436
436
|
A dataset of more than ``max_columns`` columns is left out (the pairs grow with
|
|
437
437
|
the square of the columns); ``max_listed`` partners at most are listed for a
|
|
438
|
-
column, the ones missing most often with it.
|
|
439
|
-
|
|
438
|
+
column, the ones missing most often with it. The combinations of a dataset
|
|
439
|
+
(``missing_patterns``) are tracked up to ``max_patterns``, each counted exactly
|
|
440
|
+
from its first record, and ``max_patterns_listed`` are listed, the most frequent
|
|
441
|
+
first. Each is part of the key of a result.
|
|
440
442
|
"""
|
|
441
443
|
|
|
442
444
|
model_config = ConfigDict(extra="forbid", frozen=True)
|
|
443
445
|
|
|
444
446
|
max_columns: int = Field(default=100, ge=2, le=1_000)
|
|
445
447
|
max_listed: int = Field(default=10, ge=1, le=1_000)
|
|
448
|
+
max_patterns: int = Field(default=1_000, ge=1, le=100_000)
|
|
449
|
+
max_patterns_listed: int = Field(default=200, ge=1, le=10_000)
|
|
446
450
|
|
|
447
451
|
|
|
448
452
|
class ArraySettings(BaseModel):
|
|
@@ -33,6 +33,12 @@ def _digest(parts: tuple[str, ...]) -> str:
|
|
|
33
33
|
)).hexdigest()[:40]
|
|
34
34
|
|
|
35
35
|
|
|
36
|
+
NEW_PRODUCT_DAYS = 365
|
|
37
|
+
NEW_PRODUCT_UNRATED = 0.3
|
|
38
|
+
DAYS_PER_REVIEW = 2
|
|
39
|
+
MAX_REVIEWS = 500
|
|
40
|
+
|
|
41
|
+
|
|
36
42
|
def _stream(seed: int, dataset_id: str, row_index: int, decision: str,
|
|
37
43
|
context: tuple[str, ...]) -> random.Random:
|
|
38
44
|
return random.Random(int(_digest((str(seed), dataset_id, str(row_index), decision, *context)), 16))
|
|
@@ -265,7 +271,12 @@ def derive_computer_row(package: DatasetPackage, selected: dict[str, Cell],
|
|
|
265
271
|
release += timedelta(days=_stream(seed, dataset_id, row_index, "release", context).randrange(
|
|
266
272
|
min(365, (as_of_date - release).days + 1)
|
|
267
273
|
))
|
|
268
|
-
|
|
274
|
+
# Reviews come with time: a product under NEW_PRODUCT_DAYS old often has none
|
|
275
|
+
# yet, so its rating is missing, and the count grows with the age.
|
|
276
|
+
review_rng = _stream(seed, dataset_id, row_index, "reviews", context)
|
|
277
|
+
age_days = (as_of_date - release).days
|
|
278
|
+
review_count = (0 if age_days < NEW_PRODUCT_DAYS and review_rng.random() < NEW_PRODUCT_UNRATED
|
|
279
|
+
else review_rng.randrange(0, min(MAX_REVIEWS, age_days // DAYS_PER_REVIEW) + 1))
|
|
269
280
|
rating: Decimal | None = None
|
|
270
281
|
if review_count:
|
|
271
282
|
rating = Decimal(_stream(seed, dataset_id, row_index, "rating", context).randrange(30, 51)) / 10
|
|
@@ -38,15 +38,31 @@ KINDS = {
|
|
|
38
38
|
}
|
|
39
39
|
TYPES = {"string", "integer", "decimal", "boolean", "date", "datetime"}
|
|
40
40
|
MAX_NUMBER = 1_000_000_000_000
|
|
41
|
+
# English month names, January first: the keys of `decimal.by_month.factors`.
|
|
42
|
+
MONTHS = ("january", "february", "march", "april", "may", "june", "july",
|
|
43
|
+
"august", "september", "october", "november", "december")
|
|
44
|
+
MAX_MONTH_FACTOR = 10
|
|
45
|
+
DISTRIBUTIONS = {"uniform", "lognormal"}
|
|
46
|
+
MAX_SIGMA = 5
|
|
47
|
+
MAX_GROWTH = 10
|
|
48
|
+
MAX_CASES = 256
|
|
49
|
+
# What a `by_case` entry may replace, by generator kind.
|
|
50
|
+
CASE_KEYS = {
|
|
51
|
+
"choice": {"weights"}, "integer": {"min", "max"}, "decimal": {"min", "max"},
|
|
52
|
+
"date": {"min", "max"}, "datetime": {"min", "max"},
|
|
53
|
+
}
|
|
54
|
+
# The options that read another column: a `by_case` entry is checked without them.
|
|
55
|
+
ROW_OPTIONS = {"by_case", "by_month", "by_value", "after"}
|
|
41
56
|
GENERATOR_KEYS = {
|
|
42
57
|
"constant": {"value"},
|
|
43
58
|
"sequence": {"prefix", "width", "start"},
|
|
44
|
-
"choice": {"weights"},
|
|
45
|
-
"integer": {"min", "max"},
|
|
46
|
-
"decimal": {"min", "max", "scale"
|
|
47
|
-
|
|
48
|
-
"
|
|
49
|
-
"
|
|
59
|
+
"choice": {"weights", "by_case"},
|
|
60
|
+
"integer": {"min", "max", "by_case"},
|
|
61
|
+
"decimal": {"min", "max", "scale", "by_month", "by_value", "distribution", "median", "sigma",
|
|
62
|
+
"round_to", "by_case"},
|
|
63
|
+
"boolean": {"true_share"},
|
|
64
|
+
"date": {"min", "max", "format", "by_case", "after", "growth", "weekdays"},
|
|
65
|
+
"datetime": {"min", "max", "format", "by_case", "after", "growth", "weekdays"},
|
|
50
66
|
"text": {"length"},
|
|
51
67
|
"reference": {"entity", "field"},
|
|
52
68
|
"relative_date": {"from", "offset", "format"},
|
|
@@ -175,12 +191,112 @@ def _date(source: Path, value: Any, where: str) -> str:
|
|
|
175
191
|
return value
|
|
176
192
|
|
|
177
193
|
|
|
194
|
+
def _distribution(source: Path, generator: dict, lower: float, upper: float) -> None:
|
|
195
|
+
"""Check the draw of a decimal: `median` and `sigma` belong to `lognormal` only."""
|
|
196
|
+
distribution = generator.get("distribution", "uniform")
|
|
197
|
+
if distribution not in DISTRIBUTIONS:
|
|
198
|
+
_fail(source, generator, "decimal.distribution must be uniform or lognormal")
|
|
199
|
+
if distribution == "uniform":
|
|
200
|
+
if "median" in generator or "sigma" in generator:
|
|
201
|
+
_fail(source, generator, "decimal.median and decimal.sigma require distribution lognormal")
|
|
202
|
+
return
|
|
203
|
+
median, sigma = generator.get("median"), generator.get("sigma")
|
|
204
|
+
if lower <= 0:
|
|
205
|
+
_fail(source, generator, "decimal lognormal requires min above 0")
|
|
206
|
+
if not _bounded_number(median) or not lower <= median <= upper:
|
|
207
|
+
_fail(source, generator, "decimal lognormal requires a median from min to max")
|
|
208
|
+
if not _bounded_number(sigma) or not 0 < sigma <= MAX_SIGMA:
|
|
209
|
+
_fail(source, generator, f"decimal lognormal requires a sigma above 0 and at most {MAX_SIGMA}")
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def _probability(value: object) -> bool:
|
|
213
|
+
return _bounded_number(value) and 0 <= value <= 1
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def _missing_by(source: Path, item: dict, dependencies: list) -> None:
|
|
217
|
+
"""Check `missing_by`: a missing rate by the value of another column, or when it is empty."""
|
|
218
|
+
rule = _mapping(source, item["missing_by"], "missing_by", {"from", "cases", "empty"})
|
|
219
|
+
cases = rule.get("cases", {})
|
|
220
|
+
if (not isinstance(rule.get("from"), str) or not isinstance(cases, dict)
|
|
221
|
+
or not cases and "empty" not in rule or len(cases) > MAX_CASES
|
|
222
|
+
or any(not isinstance(key, str) or not key or not _probability(rate)
|
|
223
|
+
for key, rate in cases.items())
|
|
224
|
+
or "empty" in rule and not _probability(rule["empty"])):
|
|
225
|
+
_fail(source, rule, "missing_by requires from and rates from 0 to 1 by value or when empty")
|
|
226
|
+
if rule["from"] not in dependencies:
|
|
227
|
+
_fail(source, rule, "missing_by.from must be declared in depends_on")
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def _by_case(source: Path, item: dict, dependencies: list, where: str) -> None:
|
|
231
|
+
"""Check `by_case`: each case replaces some parameters, and the result must be valid alone.
|
|
232
|
+
|
|
233
|
+
A case is validated as a column of its own, so the rules of every kind exist once;
|
|
234
|
+
the options that read another column are checked on the declared generator only.
|
|
235
|
+
"""
|
|
236
|
+
generator = item["generate"]
|
|
237
|
+
kind = generator["kind"]
|
|
238
|
+
by_case = _mapping(source, generator["by_case"], f"{kind}.by_case", {"from", "cases"})
|
|
239
|
+
cases = by_case.get("cases")
|
|
240
|
+
if (not isinstance(by_case.get("from"), str) or not isinstance(cases, dict) or not cases
|
|
241
|
+
or len(cases) > MAX_CASES or any(not isinstance(key, str) or not key for key in cases)):
|
|
242
|
+
_fail(source, by_case, f"{kind}.by_case requires from and 1 to {MAX_CASES} named cases")
|
|
243
|
+
if by_case["from"] not in dependencies:
|
|
244
|
+
_fail(source, by_case, f"{kind}.by_case.from must be declared in depends_on")
|
|
245
|
+
base = {key: value for key, value in generator.items() if key not in ROW_OPTIONS}
|
|
246
|
+
for case, override in cases.items():
|
|
247
|
+
override = _mapping(source, override, f"{kind}.by_case.cases.{case}", CASE_KEYS[kind])
|
|
248
|
+
if not override:
|
|
249
|
+
_fail(source, by_case, f"{kind}.by_case.cases.{case} changes nothing")
|
|
250
|
+
alone = {"name": item["name"], "type": item["type"], "generate": base | override}
|
|
251
|
+
_columns(source, [alone], f"{where}.by_case.{case}")
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def _by_value(source: Path, generator: dict, lower: float, upper: float) -> None:
|
|
255
|
+
"""Check the factors of a decimal by the value of another column."""
|
|
256
|
+
by_value = _mapping(source, generator["by_value"], "decimal.by_value", {"from", "factors"})
|
|
257
|
+
factors = by_value.get("factors")
|
|
258
|
+
if (not isinstance(by_value.get("from"), str) or not isinstance(factors, dict) or not factors
|
|
259
|
+
or len(factors) > MAX_CASES or any(not isinstance(key, str) or not key for key in factors)
|
|
260
|
+
or any(not _bounded_number(factor) or not 0 < factor <= MAX_MONTH_FACTOR
|
|
261
|
+
for factor in factors.values())):
|
|
262
|
+
_fail(source, by_value, "decimal.by_value requires from and factors keyed by value, "
|
|
263
|
+
f"each above 0 and at most {MAX_MONTH_FACTOR}")
|
|
264
|
+
largest = max(factors.values()) * max(generator.get("by_month", {}).get("factors", {"": 1}).values())
|
|
265
|
+
if max(abs(lower), abs(upper)) * largest > MAX_NUMBER:
|
|
266
|
+
_fail(source, by_value, "decimal.by_value scales an amount beyond one trillion")
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def _round_to(source: Path, generator: dict, scale: int) -> None:
|
|
270
|
+
"""Check the mixed rounding of a decimal: a step at the scale and a share of the rows."""
|
|
271
|
+
round_to = _mapping(source, generator["round_to"], "decimal.round_to", {"step", "share"})
|
|
272
|
+
step, share = round_to.get("step"), round_to.get("share")
|
|
273
|
+
if (not _bounded_number(step) or step <= 0
|
|
274
|
+
or (Decimal(str(step)) * 10 ** scale) % 1 != 0):
|
|
275
|
+
_fail(source, round_to, "decimal.round_to.step must be above 0 and a multiple of the scale")
|
|
276
|
+
if not _bounded_number(share) or not 0 < share <= 1:
|
|
277
|
+
_fail(source, round_to, "decimal.round_to.share must be above 0 and at most 1")
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def _by_month(source: Path, generator: dict, lower: float, upper: float) -> None:
|
|
281
|
+
"""Check the monthly factors of a decimal; a scaled amount must stay within MAX_NUMBER."""
|
|
282
|
+
by_month = _mapping(source, generator["by_month"], "decimal.by_month", {"from", "factors"})
|
|
283
|
+
factors = by_month.get("factors")
|
|
284
|
+
if (not isinstance(by_month.get("from"), str) or not isinstance(factors, dict) or not factors
|
|
285
|
+
or not set(factors) <= set(MONTHS)
|
|
286
|
+
or any(not _bounded_number(factor) or not 0 < factor <= MAX_MONTH_FACTOR
|
|
287
|
+
for factor in factors.values())):
|
|
288
|
+
_fail(source, by_month, "decimal.by_month requires from and factors keyed by English month "
|
|
289
|
+
f"name, each above 0 and at most {MAX_MONTH_FACTOR}")
|
|
290
|
+
if max(abs(lower), abs(upper)) * max(factors.values()) > MAX_NUMBER:
|
|
291
|
+
_fail(source, by_month, "decimal.by_month scales an amount beyond one trillion")
|
|
292
|
+
|
|
293
|
+
|
|
178
294
|
def _columns(source: Path, value: Any, where: str) -> None:
|
|
179
295
|
columns = _list(source, value, where, MAX_COLUMNS, nonempty=True)
|
|
180
296
|
names: set[str] = set()
|
|
181
297
|
for column in columns:
|
|
182
298
|
item = _mapping(source, column, f"{where} column", {
|
|
183
|
-
"name", "type", "generate", "depends_on", "missing", "cohort",
|
|
299
|
+
"name", "type", "generate", "depends_on", "missing", "cohort", "missing_by",
|
|
184
300
|
})
|
|
185
301
|
name = item.get("name")
|
|
186
302
|
if not isinstance(name, str) or not COLUMN_NAME.fullmatch(name):
|
|
@@ -195,6 +311,8 @@ def _columns(source: Path, value: Any, where: str) -> None:
|
|
|
195
311
|
"scale", "entity", "field", "from", "offset", "format", "length",
|
|
196
312
|
"cases", "default", "provider", "group", "profile", "province",
|
|
197
313
|
"first", "last", "language", "unit_probability", "direction_probability",
|
|
314
|
+
"by_month", "distribution", "median", "sigma", "round_to",
|
|
315
|
+
"by_case", "by_value", "after", "growth", "weekdays", "true_share",
|
|
198
316
|
})
|
|
199
317
|
kind = generator.get("kind")
|
|
200
318
|
if not isinstance(kind, str) or kind not in KINDS:
|
|
@@ -270,6 +388,13 @@ def _columns(source: Path, value: Any, where: str) -> None:
|
|
|
270
388
|
right = (Decimal(str(upper)) * factor).to_integral_value(rounding="ROUND_FLOOR")
|
|
271
389
|
if left > right:
|
|
272
390
|
_fail(source, generator, "decimal bounds contain no value at the selected scale")
|
|
391
|
+
_distribution(source, generator, lower, upper)
|
|
392
|
+
if "by_month" in generator:
|
|
393
|
+
_by_month(source, generator, lower, upper)
|
|
394
|
+
if "by_value" in generator:
|
|
395
|
+
_by_value(source, generator, lower, upper)
|
|
396
|
+
if "round_to" in generator:
|
|
397
|
+
_round_to(source, generator, scale)
|
|
273
398
|
if kind in {"date", "datetime"}:
|
|
274
399
|
parser = date.fromisoformat if kind == "date" else datetime.fromisoformat
|
|
275
400
|
for bound in ("min", "max"):
|
|
@@ -287,6 +412,16 @@ def _columns(source: Path, value: Any, where: str) -> None:
|
|
|
287
412
|
if (not isinstance(fmt, str) or not 1 <= len(fmt) <= 80
|
|
288
413
|
or re.search(r"%(?![%YymdHMS])", fmt)):
|
|
289
414
|
_fail(source, generator, f"{kind}.format has an unsupported directive")
|
|
415
|
+
if "growth" in generator and (not _bounded_number(generator["growth"])
|
|
416
|
+
or not 0 < generator["growth"] <= MAX_GROWTH):
|
|
417
|
+
_fail(source, generator, f"{kind}.growth must be above 0 and at most {MAX_GROWTH}")
|
|
418
|
+
if "weekdays" in generator and generator["weekdays"] is not True:
|
|
419
|
+
_fail(source, generator, f"{kind}.weekdays must be true when present")
|
|
420
|
+
if "after" in generator and not isinstance(generator["after"], str):
|
|
421
|
+
_fail(source, generator, f"{kind}.after must name a column")
|
|
422
|
+
if kind == "boolean" and "true_share" in generator and (
|
|
423
|
+
not _bounded_number(generator["true_share"]) or not 0 <= generator["true_share"] <= 1):
|
|
424
|
+
_fail(source, generator, "boolean.true_share must be from 0 to 1")
|
|
290
425
|
if kind == "sequence" and item["type"] != "string":
|
|
291
426
|
_fail(source, generator, "sequence requires string type")
|
|
292
427
|
if kind == "text" and item["type"] != "string":
|
|
@@ -336,12 +471,22 @@ def _columns(source: Path, value: Any, where: str) -> None:
|
|
|
336
471
|
_fail(source, generator, "common contact inputs must be declared in depends_on")
|
|
337
472
|
if kind in {"relative_date", "conditional"} and generator["from"] not in dependencies:
|
|
338
473
|
_fail(source, generator, f"{kind}.from must be declared in depends_on")
|
|
474
|
+
if kind == "decimal" and "by_month" in generator and generator["by_month"]["from"] not in dependencies:
|
|
475
|
+
_fail(source, generator, "decimal.by_month.from must be declared in depends_on")
|
|
476
|
+
if kind == "decimal" and "by_value" in generator and generator["by_value"]["from"] not in dependencies:
|
|
477
|
+
_fail(source, generator, "decimal.by_value.from must be declared in depends_on")
|
|
478
|
+
if "after" in generator and generator["after"] not in dependencies:
|
|
479
|
+
_fail(source, generator, f"{kind}.after must be declared in depends_on")
|
|
480
|
+
if "by_case" in generator:
|
|
481
|
+
_by_case(source, item, dependencies, f"{where}.{name}")
|
|
339
482
|
missing = item.get("missing")
|
|
340
483
|
if missing is not None and (type(missing) not in (float, int)
|
|
341
484
|
or not math.isfinite(missing) or not 0 <= missing <= 1):
|
|
342
485
|
_fail(source, item, "missing must be a probability from 0 to 1")
|
|
343
486
|
if "cohort" in item:
|
|
344
487
|
_id(source, item["cohort"], "column cohort")
|
|
488
|
+
if "missing_by" in item:
|
|
489
|
+
_missing_by(source, item, dependencies)
|
|
345
490
|
graph = {item["name"]: item.get("depends_on", []) for item in columns}
|
|
346
491
|
done: set[str] = set()
|
|
347
492
|
active: set[str] = set()
|
|
@@ -387,6 +532,14 @@ def _columns(source: Path, value: Any, where: str) -> None:
|
|
|
387
532
|
_fail(source, generator, "relative_date source must match date or datetime type")
|
|
388
533
|
if "format" in parent["generate"]:
|
|
389
534
|
_fail(source, generator, "relative_date source must use ISO format")
|
|
535
|
+
if "after" in generator:
|
|
536
|
+
parent = by_name[generator["after"]]
|
|
537
|
+
if parent["type"] != item["type"] or "format" in parent["generate"]:
|
|
538
|
+
_fail(source, generator, f"{generator['kind']}.after must name an ISO column of the same type")
|
|
539
|
+
if generator["kind"] == "decimal" and "by_month" in generator:
|
|
540
|
+
parent = by_name[generator["by_month"]["from"]]
|
|
541
|
+
if parent["type"] not in {"date", "datetime"} or "format" in parent["generate"]:
|
|
542
|
+
_fail(source, generator, "decimal.by_month.from must be an ISO date or datetime column")
|
|
390
543
|
|
|
391
544
|
|
|
392
545
|
def validate_generate_mapping(root: Any, source: Path) -> GenerateDefinition:
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
|
|
5
|
+
"""Random draws shared by the Generate providers, so a distribution is computed once."""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import math
|
|
10
|
+
import random
|
|
11
|
+
from statistics import NormalDist
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def truncated_lognormal(rng: random.Random, median: float, sigma: float,
|
|
15
|
+
low: float, high: float) -> float:
|
|
16
|
+
"""Draw a log-normal value truncated to [low, high]; both bounds must be above 0.
|
|
17
|
+
|
|
18
|
+
The inverse of the normal CDF on a uniform share of [CDF(low), CDF(high)] keeps
|
|
19
|
+
one random number per value, without rejection, so the stream stays aligned.
|
|
20
|
+
"""
|
|
21
|
+
normal = NormalDist(math.log(median), sigma)
|
|
22
|
+
lower, upper = normal.cdf(math.log(low)), normal.cdf(math.log(high))
|
|
23
|
+
share = min(max(lower + rng.random() * (upper - lower), 1e-15), 1 - 1e-15)
|
|
24
|
+
return math.exp(normal.inv_cdf(share))
|
|
@@ -45,6 +45,19 @@ anomaly_profiles:
|
|
|
45
45
|
- {kind: format, column: memory_gb, value: unit_gb, rate: 0.15}
|
|
46
46
|
- {kind: format, column: storage_gb, value: unit_gb, rate: 0.1}
|
|
47
47
|
- {kind: format, column: gpu_vram_gb, value: unit_gb, rate: 0.06}
|
|
48
|
+
rule_breaks:
|
|
49
|
+
targets: [computers]
|
|
50
|
+
operations:
|
|
51
|
+
- {kind: swap, column: current_price, value: list_price, rate: 0.004, class: current_above_list}
|
|
52
|
+
- {kind: swap, column: cpu_cores, value: cpu_threads, rate: 0.004, class: threads_below_cores}
|
|
53
|
+
- {kind: replace, column: gpu_vram_gb, value: "8", rate: 0.004,
|
|
54
|
+
when: {gpu_type: integrated}, class: vram_vs_gpu_type}
|
|
55
|
+
- {kind: replace, column: stock_status, value: out_of_stock, rate: 0.004,
|
|
56
|
+
when: {stock_status: in_stock}, class: stock_status_vs_quantity}
|
|
57
|
+
- {kind: replace, column: release_date, value: "2027-06-15", rate: 0.003, class: release_after_as_of}
|
|
58
|
+
- {kind: replace, column: review_count, value: "0", rate: 0.004, class: rating_without_reviews}
|
|
59
|
+
- {kind: replace, column: display_type, value: ips, rate: 0.004,
|
|
60
|
+
when: {display_type: none}, class: display_without_size}
|
|
48
61
|
unit_variants:
|
|
49
62
|
targets: [computers]
|
|
50
63
|
operations:
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
format: tabalyst.generate.package
|
|
2
|
+
format_version: 0.1.0
|
|
3
|
+
id: crm
|
|
4
|
+
package_version: 0.1.0
|
|
5
|
+
catalog: catalog.yaml
|
|
6
|
+
defaults:
|
|
7
|
+
rows: 20000
|
|
8
|
+
seed: 42
|
|
9
|
+
as_of_date: '2026-09-30'
|
|
10
|
+
entities:
|
|
11
|
+
- id: accounts
|
|
12
|
+
count: 400
|
|
13
|
+
generator: company
|
|
14
|
+
schema: schemas/accounts.yaml
|
|
15
|
+
cohorts:
|
|
16
|
+
- id: contact_only
|
|
17
|
+
weight: 64
|
|
18
|
+
values:
|
|
19
|
+
opportunity_stage: None
|
|
20
|
+
- id: pipeline
|
|
21
|
+
weight: 36
|
|
22
|
+
datasets:
|
|
23
|
+
- id: crm-contacts
|
|
24
|
+
mode: generated
|
|
25
|
+
row_source: columns
|
|
26
|
+
rows: 20000
|
|
27
|
+
schema: schemas/contacts.yaml
|
|
28
|
+
anomaly_profiles:
|
|
29
|
+
dirty_realistic:
|
|
30
|
+
targets:
|
|
31
|
+
- crm-contacts
|
|
32
|
+
operations:
|
|
33
|
+
- kind: set_missing
|
|
34
|
+
column: email
|
|
35
|
+
rate: 0.06
|
|
36
|
+
- kind: duplicate
|
|
37
|
+
column: email
|
|
38
|
+
rate: 0.02
|
|
39
|
+
- kind: replace
|
|
40
|
+
column: email
|
|
41
|
+
value: invalid-address
|
|
42
|
+
rate: 0.01
|
|
43
|
+
- kind: set_missing
|
|
44
|
+
column: phone
|
|
45
|
+
rate: 0.05
|
|
46
|
+
- kind: format
|
|
47
|
+
column: phone
|
|
48
|
+
value: phone_spaces
|
|
49
|
+
rate: 0.12
|
|
50
|
+
- kind: format
|
|
51
|
+
column: company_name
|
|
52
|
+
value: upper
|
|
53
|
+
rate: 0.03
|
|
54
|
+
- kind: replace
|
|
55
|
+
column: country
|
|
56
|
+
value: CA
|
|
57
|
+
rate: 0.06
|
|
58
|
+
- kind: format
|
|
59
|
+
column: industry
|
|
60
|
+
value: lower
|
|
61
|
+
rate: 0.04
|
|
62
|
+
- kind: format
|
|
63
|
+
column: lead_source
|
|
64
|
+
value: lower
|
|
65
|
+
rate: 0.04
|
|
66
|
+
- kind: set_missing
|
|
67
|
+
column: opportunity_amount
|
|
68
|
+
rate: 0.04
|
|
69
|
+
when:
|
|
70
|
+
opportunity_stage: Proposal
|
|
71
|
+
- kind: replace
|
|
72
|
+
column: opportunity_probability
|
|
73
|
+
value: '120'
|
|
74
|
+
rate: 0.01
|
|
75
|
+
when:
|
|
76
|
+
opportunity_stage: Closed Won
|
|
77
|
+
- kind: format
|
|
78
|
+
column: opportunity_amount
|
|
79
|
+
value: currency_fr
|
|
80
|
+
rate: 0.02
|
|
81
|
+
- kind: format
|
|
82
|
+
column: opportunity_amount
|
|
83
|
+
value: currency_code
|
|
84
|
+
rate: 0.01
|
|
85
|
+
- kind: format
|
|
86
|
+
column: created_at
|
|
87
|
+
value: date_dmy
|
|
88
|
+
rate: 0.02
|
|
89
|
+
- kind: format
|
|
90
|
+
column: owner
|
|
91
|
+
value: trailing_space
|
|
92
|
+
rate: 0.03
|
|
93
|
+
- kind: format
|
|
94
|
+
column: job_title
|
|
95
|
+
value: lower
|
|
96
|
+
rate: 0.03
|
|
97
|
+
rule_breaks:
|
|
98
|
+
targets:
|
|
99
|
+
- crm-contacts
|
|
100
|
+
operations:
|
|
101
|
+
- kind: replace
|
|
102
|
+
column: opportunity_probability
|
|
103
|
+
value: '90'
|
|
104
|
+
rate: 0.1
|
|
105
|
+
when:
|
|
106
|
+
opportunity_stage: Closed Lost
|
|
107
|
+
class: probability_vs_stage
|
|
108
|
+
- kind: replace
|
|
109
|
+
column: opportunity_probability
|
|
110
|
+
value: '5'
|
|
111
|
+
rate: 0.03
|
|
112
|
+
when:
|
|
113
|
+
opportunity_stage: Negotiation
|
|
114
|
+
class: probability_vs_stage
|
|
115
|
+
- kind: replace
|
|
116
|
+
column: lifecycle_stage
|
|
117
|
+
value: Customer
|
|
118
|
+
rate: 0.1
|
|
119
|
+
when:
|
|
120
|
+
opportunity_stage: Closed Lost
|
|
121
|
+
class: lifecycle_vs_stage
|
|
122
|
+
- kind: replace
|
|
123
|
+
column: lead_status
|
|
124
|
+
value: Converted
|
|
125
|
+
rate: 0.01
|
|
126
|
+
when:
|
|
127
|
+
lifecycle_stage: Lead
|
|
128
|
+
class: status_vs_lifecycle
|
|
129
|
+
- kind: replace
|
|
130
|
+
column: opportunity_close_date
|
|
131
|
+
value: '2027-03-15'
|
|
132
|
+
rate: 0.03
|
|
133
|
+
when:
|
|
134
|
+
opportunity_stage: Closed Won
|
|
135
|
+
class: closed_in_future
|
|
136
|
+
- kind: replace
|
|
137
|
+
column: last_activity_at
|
|
138
|
+
value: '2018-06-01'
|
|
139
|
+
rate: 0.005
|
|
140
|
+
class: activity_before_creation
|
|
141
|
+
- kind: replace
|
|
142
|
+
column: owner
|
|
143
|
+
value: Sam Patel
|
|
144
|
+
rate: 0.005
|
|
145
|
+
when:
|
|
146
|
+
province_code: QC
|
|
147
|
+
class: owner_vs_territory
|
|
148
|
+
- kind: format
|
|
149
|
+
column: company_name
|
|
150
|
+
value: drop_char
|
|
151
|
+
rate: 0.002
|
|
152
|
+
class: company_name_variant
|