ts-shape 0.0.0__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.
- ts_shape-0.0.0/.github/workflows/ci.yml +55 -0
- ts_shape-0.0.0/.github/workflows/release.yml +161 -0
- ts_shape-0.0.0/.gitignore +180 -0
- ts_shape-0.0.0/.vscode/settings.json +3 -0
- ts_shape-0.0.0/CHANGES.txt +60 -0
- ts_shape-0.0.0/CYCLE_EXTRACTOR_CHANGES_SUMMARY.md +198 -0
- ts_shape-0.0.0/DAILY_PRODUCTION_MODULES.md +440 -0
- ts_shape-0.0.0/DOCUMENTATION_DEPLOYMENT.md +330 -0
- ts_shape-0.0.0/DOWNTIME_QUALITY_MODULES.md +549 -0
- ts_shape-0.0.0/ENHANCEMENTS_AT_A_GLANCE.txt +164 -0
- ts_shape-0.0.0/ENHANCEMENTS_INDEX.md +156 -0
- ts_shape-0.0.0/ENHANCEMENTS_VISUAL_GUIDE.txt +226 -0
- ts_shape-0.0.0/ENHANCEMENT_SUMMARY.md +349 -0
- ts_shape-0.0.0/ENHANCEMENT_SUMMARY.txt +196 -0
- ts_shape-0.0.0/EXAMPLES_SPC_ENHANCEMENTS.py +490 -0
- ts_shape-0.0.0/FINAL_SUMMARY.txt +293 -0
- ts_shape-0.0.0/FUTURE_PRODUCTION_FEATURES.md +367 -0
- ts_shape-0.0.0/IMPLEMENTATION_COMPLETE.md +564 -0
- ts_shape-0.0.0/IMPLEMENTATION_SUMMARY.txt +419 -0
- ts_shape-0.0.0/LICENSE.txt +21 -0
- ts_shape-0.0.0/MANIFEST.in +0 -0
- ts_shape-0.0.0/MANUFACTURING_IMPROVEMENTS_ANALYSIS.md +621 -0
- ts_shape-0.0.0/OUTLIER_DETECTION_ENHANCEMENTS.md +319 -0
- ts_shape-0.0.0/PKG-INFO +400 -0
- ts_shape-0.0.0/PRODUCTION_MODULES_SUMMARY.md +486 -0
- ts_shape-0.0.0/PRODUCTION_MODULE_STRUCTURE.md +212 -0
- ts_shape-0.0.0/QUICK_REFERENCE.md +251 -0
- ts_shape-0.0.0/README.md +355 -0
- ts_shape-0.0.0/README_ENHANCEMENTS.md +143 -0
- ts_shape-0.0.0/SETPOINT_EVENTS_ENHANCEMENTS.md +358 -0
- ts_shape-0.0.0/SPC_ENHANCEMENTS_SUMMARY.md +439 -0
- ts_shape-0.0.0/SPC_QUICK_REFERENCE.md +242 -0
- ts_shape-0.0.0/STARTUP_ENHANCEMENTS.md +441 -0
- ts_shape-0.0.0/TOLERANCE_DEVIATION_ENHANCEMENTS.md +225 -0
- ts_shape-0.0.0/docs/assets/favicon-16x16.icon +0 -0
- ts_shape-0.0.0/docs/assets/favicon-16x16.jpg +0 -0
- ts_shape-0.0.0/docs/assets/favicon-16x16.png +0 -0
- ts_shape-0.0.0/docs/assets/favicon-32x32.icon +0 -0
- ts_shape-0.0.0/docs/assets/favicon-32x32.jpg +0 -0
- ts_shape-0.0.0/docs/assets/favicon-32x32.png +0 -0
- ts_shape-0.0.0/docs/assets/favicon-48x48.icon +0 -0
- ts_shape-0.0.0/docs/assets/favicon-48x48.jpg +0 -0
- ts_shape-0.0.0/docs/assets/favicon-48x48.png +0 -0
- ts_shape-0.0.0/docs/assets/ts-shape.png +0 -0
- ts_shape-0.0.0/docs/changelog.md +1 -0
- ts_shape-0.0.0/docs/concept.md +276 -0
- ts_shape-0.0.0/docs/contributing.md +0 -0
- ts_shape-0.0.0/docs/index.md +220 -0
- ts_shape-0.0.0/docs/insiders/development.md +114 -0
- ts_shape-0.0.0/docs/license.md +1 -0
- ts_shape-0.0.0/docs/usage/index.md +908 -0
- ts_shape-0.0.0/docs/user_guide/installation.md +94 -0
- ts_shape-0.0.0/docs/user_guide/quick_start.md +87 -0
- ts_shape-0.0.0/examples/context_enricher_demo.py +135 -0
- ts_shape-0.0.0/examples/correlation_events_demo.py +183 -0
- ts_shape-0.0.0/examples/cycle_extractor_enhancements_demo.py +318 -0
- ts_shape-0.0.0/examples/energy_events_demo.py +141 -0
- ts_shape-0.0.0/examples/features_statistics_demo.py +545 -0
- ts_shape-0.0.0/examples/loader_usage_demo.py +305 -0
- ts_shape-0.0.0/examples/maintenance_events_demo.py +493 -0
- ts_shape-0.0.0/examples/production_events_demo.py +883 -0
- ts_shape-0.0.0/examples/production_tracking_demo.py +367 -0
- ts_shape-0.0.0/examples/quality_events_demo.py +370 -0
- ts_shape-0.0.0/examples/setpoint_events_advanced_usage.py +316 -0
- ts_shape-0.0.0/examples/statistics_demo.py +277 -0
- ts_shape-0.0.0/examples/supplychain_events_demo.py +545 -0
- ts_shape-0.0.0/examples/transform_operations_demo.py +461 -0
- ts_shape-0.0.0/mkdocs.yml +130 -0
- ts_shape-0.0.0/pyproject.toml +78 -0
- ts_shape-0.0.0/requirements-docs.txt +7 -0
- ts_shape-0.0.0/requirements.in +10 -0
- ts_shape-0.0.0/requirements.txt +9 -0
- ts_shape-0.0.0/scripts/gen_ref_pages.py +33 -0
- ts_shape-0.0.0/scripts/generate_docs.sh +17 -0
- ts_shape-0.0.0/scripts/path_extract_md.py +30 -0
- ts_shape-0.0.0/scripts/requirements.py +100 -0
- ts_shape-0.0.0/setup.cfg +4 -0
- ts_shape-0.0.0/setup.py +4 -0
- ts_shape-0.0.0/src/ts_shape/__init__.py +0 -0
- ts_shape-0.0.0/src/ts_shape/context/__init__.py +9 -0
- ts_shape-0.0.0/src/ts_shape/context/value_mapping.py +89 -0
- ts_shape-0.0.0/src/ts_shape/events/__init__.py +14 -0
- ts_shape-0.0.0/src/ts_shape/events/correlation/__init__.py +24 -0
- ts_shape-0.0.0/src/ts_shape/events/correlation/anomaly_correlation.py +248 -0
- ts_shape-0.0.0/src/ts_shape/events/correlation/signal_correlation.py +213 -0
- ts_shape-0.0.0/src/ts_shape/events/energy/__init__.py +27 -0
- ts_shape-0.0.0/src/ts_shape/events/energy/consumption_analysis.py +238 -0
- ts_shape-0.0.0/src/ts_shape/events/energy/efficiency_tracking.py +390 -0
- ts_shape-0.0.0/src/ts_shape/events/engineering/__init__.py +24 -0
- ts_shape-0.0.0/src/ts_shape/events/engineering/setpoint_events.py +1025 -0
- ts_shape-0.0.0/src/ts_shape/events/engineering/startup_events.py +720 -0
- ts_shape-0.0.0/src/ts_shape/events/maintenance/__init__.py +35 -0
- ts_shape-0.0.0/src/ts_shape/events/maintenance/degradation_detection.py +368 -0
- ts_shape-0.0.0/src/ts_shape/events/maintenance/failure_prediction.py +255 -0
- ts_shape-0.0.0/src/ts_shape/events/maintenance/vibration_analysis.py +217 -0
- ts_shape-0.0.0/src/ts_shape/events/production/__init__.py +106 -0
- ts_shape-0.0.0/src/ts_shape/events/production/alarm_management.py +289 -0
- ts_shape-0.0.0/src/ts_shape/events/production/batch_tracking.py +242 -0
- ts_shape-0.0.0/src/ts_shape/events/production/changeover.py +282 -0
- ts_shape-0.0.0/src/ts_shape/events/production/cycle_time_tracking.py +404 -0
- ts_shape-0.0.0/src/ts_shape/events/production/downtime.py +0 -0
- ts_shape-0.0.0/src/ts_shape/events/production/downtime_tracking.py +418 -0
- ts_shape-0.0.0/src/ts_shape/events/production/flow_constraints.py +356 -0
- ts_shape-0.0.0/src/ts_shape/events/production/line_throughput.py +322 -0
- ts_shape-0.0.0/src/ts_shape/events/production/machine_state.py +210 -0
- ts_shape-0.0.0/src/ts_shape/events/production/oee_calculator.py +369 -0
- ts_shape-0.0.0/src/ts_shape/events/production/part_tracking.py +276 -0
- ts_shape-0.0.0/src/ts_shape/events/production/quality_tracking.py +507 -0
- ts_shape-0.0.0/src/ts_shape/events/production/shift_reporting.py +366 -0
- ts_shape-0.0.0/src/ts_shape/events/quality/__init__.py +27 -0
- ts_shape-0.0.0/src/ts_shape/events/quality/outlier_detection.py +254 -0
- ts_shape-0.0.0/src/ts_shape/events/quality/statistical_process_control.py +641 -0
- ts_shape-0.0.0/src/ts_shape/events/quality/tolerance_deviation.py +456 -0
- ts_shape-0.0.0/src/ts_shape/events/supplychain/__init__.py +19 -0
- ts_shape-0.0.0/src/ts_shape/events/supplychain/demand_pattern.py +209 -0
- ts_shape-0.0.0/src/ts_shape/events/supplychain/inventory_monitoring.py +316 -0
- ts_shape-0.0.0/src/ts_shape/events/supplychain/lead_time_analysis.py +192 -0
- ts_shape-0.0.0/src/ts_shape/features/__init__.py +95 -0
- ts_shape-0.0.0/src/ts_shape/features/cycles/__init__.py +19 -0
- ts_shape-0.0.0/src/ts_shape/features/cycles/cycle_processor.py +328 -0
- ts_shape-0.0.0/src/ts_shape/features/cycles/cycles_extractor.py +464 -0
- ts_shape-0.0.0/src/ts_shape/features/stats/__init__.py +76 -0
- ts_shape-0.0.0/src/ts_shape/features/stats/boolean_stats.py +71 -0
- ts_shape-0.0.0/src/ts_shape/features/stats/feature_table.py +118 -0
- ts_shape-0.0.0/src/ts_shape/features/stats/numeric_stats.py +122 -0
- ts_shape-0.0.0/src/ts_shape/features/stats/string_stats.py +124 -0
- ts_shape-0.0.0/src/ts_shape/features/stats/timestamp_stats.py +103 -0
- ts_shape-0.0.0/src/ts_shape/features/time_stats/__init__.py +10 -0
- ts_shape-0.0.0/src/ts_shape/features/time_stats/time_stats_numeric.py +89 -0
- ts_shape-0.0.0/src/ts_shape/loader/__init__.py +51 -0
- ts_shape-0.0.0/src/ts_shape/loader/combine/__init__.py +8 -0
- ts_shape-0.0.0/src/ts_shape/loader/combine/integrator.py +139 -0
- ts_shape-0.0.0/src/ts_shape/loader/context/__init__.py +17 -0
- ts_shape-0.0.0/src/ts_shape/loader/context/context_enricher.py +162 -0
- ts_shape-0.0.0/src/ts_shape/loader/metadata/__init__.py +28 -0
- ts_shape-0.0.0/src/ts_shape/loader/metadata/metadata_api_loader.py +109 -0
- ts_shape-0.0.0/src/ts_shape/loader/metadata/metadata_db_loader.py +107 -0
- ts_shape-0.0.0/src/ts_shape/loader/metadata/metadata_json_loader.py +315 -0
- ts_shape-0.0.0/src/ts_shape/loader/timeseries/__init__.py +37 -0
- ts_shape-0.0.0/src/ts_shape/loader/timeseries/azure_blob_loader.py +830 -0
- ts_shape-0.0.0/src/ts_shape/loader/timeseries/energy_api_loader.py +202 -0
- ts_shape-0.0.0/src/ts_shape/loader/timeseries/parquet_loader.py +169 -0
- ts_shape-0.0.0/src/ts_shape/loader/timeseries/s3proxy_parquet_loader.py +83 -0
- ts_shape-0.0.0/src/ts_shape/loader/timeseries/timescale_loader.py +55 -0
- ts_shape-0.0.0/src/ts_shape/transform/__init__.py +63 -0
- ts_shape-0.0.0/src/ts_shape/transform/calculator/__init__.py +14 -0
- ts_shape-0.0.0/src/ts_shape/transform/calculator/numeric_calc.py +120 -0
- ts_shape-0.0.0/src/ts_shape/transform/filter/__init__.py +41 -0
- ts_shape-0.0.0/src/ts_shape/transform/filter/boolean_filter.py +37 -0
- ts_shape-0.0.0/src/ts_shape/transform/filter/custom_filter.py +32 -0
- ts_shape-0.0.0/src/ts_shape/transform/filter/datetime_filter.py +123 -0
- ts_shape-0.0.0/src/ts_shape/transform/filter/numeric_filter.py +39 -0
- ts_shape-0.0.0/src/ts_shape/transform/filter/string_filter.py +44 -0
- ts_shape-0.0.0/src/ts_shape/transform/functions/__init__.py +8 -0
- ts_shape-0.0.0/src/ts_shape/transform/functions/lambda_func.py +28 -0
- ts_shape-0.0.0/src/ts_shape/transform/time_functions/__init__.py +15 -0
- ts_shape-0.0.0/src/ts_shape/transform/time_functions/timestamp_converter.py +41 -0
- ts_shape-0.0.0/src/ts_shape/transform/time_functions/timezone_shift.py +150 -0
- ts_shape-0.0.0/src/ts_shape/utils/__init__.py +8 -0
- ts_shape-0.0.0/src/ts_shape/utils/base.py +36 -0
- ts_shape-0.0.0/src/ts_shape.egg-info/PKG-INFO +400 -0
- ts_shape-0.0.0/src/ts_shape.egg-info/SOURCES.txt +206 -0
- ts_shape-0.0.0/src/ts_shape.egg-info/dependency_links.txt +1 -0
- ts_shape-0.0.0/src/ts_shape.egg-info/requires.txt +27 -0
- ts_shape-0.0.0/src/ts_shape.egg-info/top_level.txt +1 -0
- ts_shape-0.0.0/test_outlier_enhancements.py +159 -0
- ts_shape-0.0.0/test_spc_enhancements.py +133 -0
- ts_shape-0.0.0/test_startup_enhancements.py +343 -0
- ts_shape-0.0.0/tests/conftest.py +9 -0
- ts_shape-0.0.0/tests/test_azure_blob_loader.py +138 -0
- ts_shape-0.0.0/tests/test_base.py +25 -0
- ts_shape-0.0.0/tests/test_boolean_filter.py +56 -0
- ts_shape-0.0.0/tests/test_context_enricher.py +152 -0
- ts_shape-0.0.0/tests/test_correlation_events.py +188 -0
- ts_shape-0.0.0/tests/test_custom_filter.py +15 -0
- ts_shape-0.0.0/tests/test_cycles.py +73 -0
- ts_shape-0.0.0/tests/test_downtime_quality.py +564 -0
- ts_shape-0.0.0/tests/test_energy_api_loader.py +116 -0
- ts_shape-0.0.0/tests/test_energy_events.py +206 -0
- ts_shape-0.0.0/tests/test_engineering_setpoint.py +103 -0
- ts_shape-0.0.0/tests/test_engineering_startup.py +44 -0
- ts_shape-0.0.0/tests/test_feature_table.py +176 -0
- ts_shape-0.0.0/tests/test_lambda_func.py +19 -0
- ts_shape-0.0.0/tests/test_loader_integrator.py +38 -0
- ts_shape-0.0.0/tests/test_maintenance_events.py +316 -0
- ts_shape-0.0.0/tests/test_metadata_api_loader.py +48 -0
- ts_shape-0.0.0/tests/test_metadata_db_loader.py +51 -0
- ts_shape-0.0.0/tests/test_metadata_json_loader.py +55 -0
- ts_shape-0.0.0/tests/test_numeric_calc.py +34 -0
- ts_shape-0.0.0/tests/test_numeric_filter.py +58 -0
- ts_shape-0.0.0/tests/test_outlier_detection.py +18 -0
- ts_shape-0.0.0/tests/test_parquet_loader.py +49 -0
- ts_shape-0.0.0/tests/test_production_events.py +99 -0
- ts_shape-0.0.0/tests/test_production_oee_alarm_batch.py +459 -0
- ts_shape-0.0.0/tests/test_production_tracking.py +598 -0
- ts_shape-0.0.0/tests/test_s3proxy_parquet_loader.py +50 -0
- ts_shape-0.0.0/tests/test_spc.py +25 -0
- ts_shape-0.0.0/tests/test_stats_boolean.py +17 -0
- ts_shape-0.0.0/tests/test_stats_numeric.py +35 -0
- ts_shape-0.0.0/tests/test_stats_string.py +25 -0
- ts_shape-0.0.0/tests/test_string_and_datetime_filter.py +65 -0
- ts_shape-0.0.0/tests/test_supplychain_events.py +417 -0
- ts_shape-0.0.0/tests/test_time_functions.py +54 -0
- ts_shape-0.0.0/tests/test_time_stats_numeric.py +39 -0
- ts_shape-0.0.0/tests/test_timescale_loader.py +28 -0
- ts_shape-0.0.0/tests/test_timestamp_stats.py +27 -0
- ts_shape-0.0.0/tests/test_tolerance_deviation.py +39 -0
- ts_shape-0.0.0/tests/test_value_mapping.py +39 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- '**'
|
|
7
|
+
pull_request:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
|
|
11
|
+
concurrency:
|
|
12
|
+
group: "ci-${{ github.ref }}"
|
|
13
|
+
cancel-in-progress: true
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
test:
|
|
17
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
strategy:
|
|
20
|
+
fail-fast: false
|
|
21
|
+
matrix:
|
|
22
|
+
python-version: ['3.10', '3.11', '3.12']
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- name: Checkout repository
|
|
26
|
+
uses: actions/checkout@v4
|
|
27
|
+
with:
|
|
28
|
+
fetch-depth: 0
|
|
29
|
+
|
|
30
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
31
|
+
uses: actions/setup-python@v5
|
|
32
|
+
with:
|
|
33
|
+
python-version: ${{ matrix.python-version }}
|
|
34
|
+
cache: 'pip'
|
|
35
|
+
|
|
36
|
+
- name: Install dependencies
|
|
37
|
+
run: |
|
|
38
|
+
python -m pip install --upgrade pip
|
|
39
|
+
pip install -r requirements.txt
|
|
40
|
+
pip install pytest pytest-cov
|
|
41
|
+
|
|
42
|
+
- name: Install package
|
|
43
|
+
run: pip install -e .
|
|
44
|
+
|
|
45
|
+
- name: Run tests with coverage
|
|
46
|
+
run: |
|
|
47
|
+
pytest --cov=ts_shape --cov-report=xml --cov-report=term -v
|
|
48
|
+
|
|
49
|
+
- name: Upload coverage report
|
|
50
|
+
if: always()
|
|
51
|
+
uses: actions/upload-artifact@v4
|
|
52
|
+
with:
|
|
53
|
+
name: coverage-report-py${{ matrix.python-version }}
|
|
54
|
+
path: coverage.xml
|
|
55
|
+
retention-days: 14
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
name: Release Pipeline
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
pages: write
|
|
12
|
+
id-token: write
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: "release-${{ github.ref }}"
|
|
16
|
+
cancel-in-progress: false
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
# =============================================================================
|
|
20
|
+
# Job 0: Run Tests
|
|
21
|
+
# =============================================================================
|
|
22
|
+
test:
|
|
23
|
+
name: Test
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
|
|
26
|
+
steps:
|
|
27
|
+
- name: Checkout repository
|
|
28
|
+
uses: actions/checkout@v4
|
|
29
|
+
with:
|
|
30
|
+
fetch-depth: 0
|
|
31
|
+
|
|
32
|
+
- name: Set up Python
|
|
33
|
+
uses: actions/setup-python@v5
|
|
34
|
+
with:
|
|
35
|
+
python-version: '3.11'
|
|
36
|
+
cache: 'pip'
|
|
37
|
+
|
|
38
|
+
- name: Install dependencies
|
|
39
|
+
run: |
|
|
40
|
+
python -m pip install --upgrade pip
|
|
41
|
+
pip install -r requirements.txt
|
|
42
|
+
pip install pytest pytest-cov
|
|
43
|
+
|
|
44
|
+
- name: Install package
|
|
45
|
+
run: pip install -e .
|
|
46
|
+
|
|
47
|
+
- name: Run tests
|
|
48
|
+
run: pytest --cov=ts_shape --cov-report=term -v
|
|
49
|
+
|
|
50
|
+
# =============================================================================
|
|
51
|
+
# Job 1: Build Documentation (MkDocs Material)
|
|
52
|
+
# =============================================================================
|
|
53
|
+
build-docs:
|
|
54
|
+
name: Build Documentation
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
needs: test
|
|
57
|
+
|
|
58
|
+
steps:
|
|
59
|
+
- name: Checkout repository
|
|
60
|
+
uses: actions/checkout@v4
|
|
61
|
+
with:
|
|
62
|
+
fetch-depth: 0
|
|
63
|
+
|
|
64
|
+
- name: Set up Python
|
|
65
|
+
uses: actions/setup-python@v5
|
|
66
|
+
with:
|
|
67
|
+
python-version: '3.11'
|
|
68
|
+
cache: 'pip'
|
|
69
|
+
|
|
70
|
+
- name: Install package dependencies
|
|
71
|
+
run: |
|
|
72
|
+
python -m pip install --upgrade pip
|
|
73
|
+
pip install -r requirements.txt
|
|
74
|
+
|
|
75
|
+
- name: Install documentation dependencies
|
|
76
|
+
run: pip install -r requirements-docs.txt
|
|
77
|
+
|
|
78
|
+
- name: Install package
|
|
79
|
+
run: pip install .
|
|
80
|
+
|
|
81
|
+
- name: Build MkDocs documentation
|
|
82
|
+
run: mkdocs build
|
|
83
|
+
|
|
84
|
+
- name: Upload Pages artifact
|
|
85
|
+
uses: actions/upload-pages-artifact@v3
|
|
86
|
+
with:
|
|
87
|
+
path: 'site'
|
|
88
|
+
|
|
89
|
+
# =============================================================================
|
|
90
|
+
# Job 2: Deploy Documentation to GitHub Pages
|
|
91
|
+
# =============================================================================
|
|
92
|
+
deploy-docs:
|
|
93
|
+
name: Deploy Documentation
|
|
94
|
+
runs-on: ubuntu-latest
|
|
95
|
+
needs: build-docs
|
|
96
|
+
environment:
|
|
97
|
+
name: github-pages
|
|
98
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
99
|
+
|
|
100
|
+
steps:
|
|
101
|
+
- name: Deploy to GitHub Pages
|
|
102
|
+
id: deployment
|
|
103
|
+
uses: actions/deploy-pages@v4
|
|
104
|
+
|
|
105
|
+
# =============================================================================
|
|
106
|
+
# Job 3: Build Python Package
|
|
107
|
+
# =============================================================================
|
|
108
|
+
build-package:
|
|
109
|
+
name: Build Package
|
|
110
|
+
runs-on: ubuntu-latest
|
|
111
|
+
needs: test
|
|
112
|
+
|
|
113
|
+
steps:
|
|
114
|
+
- name: Checkout
|
|
115
|
+
uses: actions/checkout@v4
|
|
116
|
+
with:
|
|
117
|
+
fetch-depth: 0
|
|
118
|
+
|
|
119
|
+
- name: Set up Python
|
|
120
|
+
uses: actions/setup-python@v5
|
|
121
|
+
with:
|
|
122
|
+
python-version: '3.11'
|
|
123
|
+
|
|
124
|
+
- name: Install build tools
|
|
125
|
+
run: |
|
|
126
|
+
python -m pip install --upgrade pip
|
|
127
|
+
pip install build wheel setuptools setuptools-scm
|
|
128
|
+
|
|
129
|
+
- name: Build sdist and wheel
|
|
130
|
+
run: python -m build
|
|
131
|
+
|
|
132
|
+
- name: Verify package
|
|
133
|
+
run: |
|
|
134
|
+
pip install twine
|
|
135
|
+
twine check dist/*
|
|
136
|
+
|
|
137
|
+
- name: Upload dist artifacts
|
|
138
|
+
uses: actions/upload-artifact@v4
|
|
139
|
+
with:
|
|
140
|
+
name: dist
|
|
141
|
+
path: dist/*
|
|
142
|
+
|
|
143
|
+
# =============================================================================
|
|
144
|
+
# Job 4: Publish to PyPI
|
|
145
|
+
# =============================================================================
|
|
146
|
+
publish-pypi:
|
|
147
|
+
name: Publish to PyPI
|
|
148
|
+
runs-on: ubuntu-latest
|
|
149
|
+
needs: build-package
|
|
150
|
+
|
|
151
|
+
steps:
|
|
152
|
+
- name: Download dist artifacts
|
|
153
|
+
uses: actions/download-artifact@v4
|
|
154
|
+
with:
|
|
155
|
+
name: dist
|
|
156
|
+
path: dist
|
|
157
|
+
|
|
158
|
+
- name: Publish to PyPI
|
|
159
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
160
|
+
with:
|
|
161
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Created by https://www.toptal.com/developers/gitignore/api/python
|
|
2
|
+
# Edit at https://www.toptal.com/developers/gitignore?templates=python
|
|
3
|
+
|
|
4
|
+
# Inputs #
|
|
5
|
+
inputs/
|
|
6
|
+
real-world-testing/
|
|
7
|
+
|
|
8
|
+
### Python ###
|
|
9
|
+
# Byte-compiled / optimized / DLL files
|
|
10
|
+
__pycache__/
|
|
11
|
+
*.py[cod]
|
|
12
|
+
*$py.class
|
|
13
|
+
|
|
14
|
+
# C extensions
|
|
15
|
+
*.so
|
|
16
|
+
|
|
17
|
+
# Distribution / packaging
|
|
18
|
+
.Python
|
|
19
|
+
build/
|
|
20
|
+
develop-eggs/
|
|
21
|
+
dist/
|
|
22
|
+
downloads/
|
|
23
|
+
eggs/
|
|
24
|
+
.eggs/
|
|
25
|
+
lib/
|
|
26
|
+
lib64/
|
|
27
|
+
parts/
|
|
28
|
+
sdist/
|
|
29
|
+
var/
|
|
30
|
+
wheels/
|
|
31
|
+
share/python-wheels/
|
|
32
|
+
*.egg-info/
|
|
33
|
+
.installed.cfg
|
|
34
|
+
*.egg
|
|
35
|
+
MANIFEST
|
|
36
|
+
|
|
37
|
+
# PyInstaller
|
|
38
|
+
# Usually these files are written by a python script from a template
|
|
39
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
40
|
+
*.manifest
|
|
41
|
+
*.spec
|
|
42
|
+
|
|
43
|
+
# Installer logs
|
|
44
|
+
pip-log.txt
|
|
45
|
+
pip-delete-this-directory.txt
|
|
46
|
+
|
|
47
|
+
# Unit test / coverage reports
|
|
48
|
+
htmlcov/
|
|
49
|
+
.tox/
|
|
50
|
+
.nox/
|
|
51
|
+
.coverage
|
|
52
|
+
.coverage.*
|
|
53
|
+
.cache
|
|
54
|
+
nosetests.xml
|
|
55
|
+
coverage.xml
|
|
56
|
+
*.cover
|
|
57
|
+
*.py,cover
|
|
58
|
+
.hypothesis/
|
|
59
|
+
.pytest_cache/
|
|
60
|
+
cover/
|
|
61
|
+
|
|
62
|
+
# Translations
|
|
63
|
+
*.mo
|
|
64
|
+
*.pot
|
|
65
|
+
|
|
66
|
+
# Django stuff:
|
|
67
|
+
*.log
|
|
68
|
+
local_settings.py
|
|
69
|
+
db.sqlite3
|
|
70
|
+
db.sqlite3-journal
|
|
71
|
+
|
|
72
|
+
# Flask stuff:
|
|
73
|
+
instance/
|
|
74
|
+
.webassets-cache
|
|
75
|
+
|
|
76
|
+
# Scrapy stuff:
|
|
77
|
+
.scrapy
|
|
78
|
+
|
|
79
|
+
# Sphinx documentation
|
|
80
|
+
docs/_build/
|
|
81
|
+
|
|
82
|
+
# PyBuilder
|
|
83
|
+
.pybuilder/
|
|
84
|
+
target/
|
|
85
|
+
|
|
86
|
+
# Jupyter Notebook
|
|
87
|
+
.ipynb_checkpoints
|
|
88
|
+
|
|
89
|
+
# IPython
|
|
90
|
+
profile_default/
|
|
91
|
+
ipython_config.py
|
|
92
|
+
|
|
93
|
+
# pyenv
|
|
94
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
95
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
96
|
+
# .python-version
|
|
97
|
+
|
|
98
|
+
# pipenv
|
|
99
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
100
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
101
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
102
|
+
# install all needed dependencies.
|
|
103
|
+
#Pipfile.lock
|
|
104
|
+
|
|
105
|
+
# poetry
|
|
106
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
107
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
108
|
+
# commonly ignored for libraries.
|
|
109
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
110
|
+
#poetry.lock
|
|
111
|
+
|
|
112
|
+
# pdm
|
|
113
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
114
|
+
#pdm.lock
|
|
115
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
116
|
+
# in version control.
|
|
117
|
+
# https://pdm.fming.dev/#use-with-ide
|
|
118
|
+
.pdm.toml
|
|
119
|
+
|
|
120
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
121
|
+
__pypackages__/
|
|
122
|
+
|
|
123
|
+
# Celery stuff
|
|
124
|
+
celerybeat-schedule
|
|
125
|
+
celerybeat.pid
|
|
126
|
+
|
|
127
|
+
# SageMath parsed files
|
|
128
|
+
*.sage.py
|
|
129
|
+
|
|
130
|
+
# Environments
|
|
131
|
+
.env
|
|
132
|
+
.venv
|
|
133
|
+
env/
|
|
134
|
+
venv/
|
|
135
|
+
ENV/
|
|
136
|
+
env.bak/
|
|
137
|
+
venv.bak/
|
|
138
|
+
|
|
139
|
+
# Spyder project settings
|
|
140
|
+
.spyderproject
|
|
141
|
+
.spyproject
|
|
142
|
+
|
|
143
|
+
# Rope project settings
|
|
144
|
+
.ropeproject
|
|
145
|
+
|
|
146
|
+
# mkdocs documentation
|
|
147
|
+
/site
|
|
148
|
+
|
|
149
|
+
# mypy
|
|
150
|
+
.mypy_cache/
|
|
151
|
+
.dmypy.json
|
|
152
|
+
dmypy.json
|
|
153
|
+
|
|
154
|
+
# Pyre type checker
|
|
155
|
+
.pyre/
|
|
156
|
+
|
|
157
|
+
# pytype static type analyzer
|
|
158
|
+
.pytype/
|
|
159
|
+
|
|
160
|
+
# Cython debug symbols
|
|
161
|
+
cython_debug/
|
|
162
|
+
|
|
163
|
+
# PyCharm
|
|
164
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
165
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
166
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
167
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
168
|
+
#.idea/
|
|
169
|
+
|
|
170
|
+
### Python Patch ###
|
|
171
|
+
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
|
|
172
|
+
poetry.toml
|
|
173
|
+
|
|
174
|
+
# ruff
|
|
175
|
+
.ruff_cache/
|
|
176
|
+
|
|
177
|
+
# LSP config files
|
|
178
|
+
pyrightconfig.json
|
|
179
|
+
|
|
180
|
+
# End of https://www.toptal.com/developers/gitignore/api/python
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Sep 09, 2025
|
|
2
|
+
add: Azure blob storage container loader
|
|
3
|
+
add: Metadata JSON loader added
|
|
4
|
+
changed: development guide
|
|
5
|
+
|
|
6
|
+
# Apr 06, 2025
|
|
7
|
+
add: quickstart guide added to docs
|
|
8
|
+
|
|
9
|
+
# Dec 26, 2024
|
|
10
|
+
add: mkdocs material deployment with gh actions
|
|
11
|
+
|
|
12
|
+
# Dec 25, 2024
|
|
13
|
+
add: pdoc docs exchanged with mkdocs material autodoc
|
|
14
|
+
|
|
15
|
+
# Dec 23, 2024
|
|
16
|
+
add: library rename
|
|
17
|
+
add: library structure change. loader, transform, feature, context, events
|
|
18
|
+
|
|
19
|
+
# Dec 20, 2024
|
|
20
|
+
fix: closes #7
|
|
21
|
+
|
|
22
|
+
# Nov 16, 2024
|
|
23
|
+
add: dev state docs for combine/integrator.py
|
|
24
|
+
add: dev state for combine/integrator.py
|
|
25
|
+
add: metadata loader improved
|
|
26
|
+
|
|
27
|
+
# Nov 4, 2024
|
|
28
|
+
add: stats classes improved + feature table class added
|
|
29
|
+
|
|
30
|
+
# Oct 29, 2024
|
|
31
|
+
add: timescaledb loader adjusted
|
|
32
|
+
|
|
33
|
+
# Oct 28, 2024
|
|
34
|
+
add: loader classes adjusted
|
|
35
|
+
add: classes for timestamp_converter added
|
|
36
|
+
add: classes for s3, timescaledb, timezone_shift added
|
|
37
|
+
|
|
38
|
+
# Oct 27, 2024
|
|
39
|
+
add: docs for time_stats added
|
|
40
|
+
add: time_stats for numeric value columns added
|
|
41
|
+
|
|
42
|
+
# Sep 11, 2024
|
|
43
|
+
add: methods refactored to execute without an instance
|
|
44
|
+
|
|
45
|
+
# Sep 9, 2024
|
|
46
|
+
add: cycle methods refined and splitted to cycle processor and extractor
|
|
47
|
+
|
|
48
|
+
# Sep 8, 2024
|
|
49
|
+
add: cycle method and metadata loader including tests for numeric filters
|
|
50
|
+
add: additional methods added
|
|
51
|
+
|
|
52
|
+
# Aug 25, 2024
|
|
53
|
+
fix: docs re-created
|
|
54
|
+
fix: docs
|
|
55
|
+
add: parquet loader, timestamp, string, numeric and boolean stats methods
|
|
56
|
+
|
|
57
|
+
# May 4, 2024
|
|
58
|
+
change: typings added, first test added
|
|
59
|
+
change: package folder moved
|
|
60
|
+
init: pypi package structure for timeseries-shaper / internal project for my master thesis
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# CycleExtractor Enhancement Summary
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Enhanced `/home/user/ts-shape/src/ts_shape/features/cycles/cycles_extractor.py` with 7 major improvements while maintaining 100% backward compatibility.
|
|
5
|
+
|
|
6
|
+
## Changes Made
|
|
7
|
+
|
|
8
|
+
### 1. ✅ Cycle Validation
|
|
9
|
+
- **New method**: `validate_cycles(min_duration='1s', max_duration='1h', warn=True)`
|
|
10
|
+
- Validates cycles based on duration constraints
|
|
11
|
+
- Adds columns: `cycle_duration`, `is_valid`, `validation_issue`
|
|
12
|
+
- Identifies: incomplete cycles, too short/long cycles
|
|
13
|
+
- Duration format: '1s', '5m', '1h', '2d'
|
|
14
|
+
|
|
15
|
+
### 2. ✅ Overlapping Cycle Detection
|
|
16
|
+
- **New method**: `detect_overlapping_cycles(cycle_df, resolve='flag')`
|
|
17
|
+
- Detects cycles with overlapping time ranges
|
|
18
|
+
- Resolution strategies: 'flag', 'keep_first', 'keep_last', 'keep_longest'
|
|
19
|
+
- Adds column: `has_overlap`
|
|
20
|
+
|
|
21
|
+
### 3. ✅ Incomplete Cycle Handling
|
|
22
|
+
- **Modified**: `_generate_cycle_dataframe()` now tracks incomplete cycles
|
|
23
|
+
- No more silent data loss when cycle ends run out
|
|
24
|
+
- All cycles now have `is_complete` flag (True/False)
|
|
25
|
+
- Incomplete cycles have `cycle_end = pd.NaT`
|
|
26
|
+
- Logs warnings for each incomplete cycle
|
|
27
|
+
|
|
28
|
+
### 4. ✅ Method Selection Helper
|
|
29
|
+
- **New method**: `suggest_method()`
|
|
30
|
+
- Analyzes data characteristics
|
|
31
|
+
- Recommends best extraction method(s)
|
|
32
|
+
- Returns: recommended methods, reasoning, data characteristics
|
|
33
|
+
- Considers: data types, patterns, transitions, UUID configuration
|
|
34
|
+
|
|
35
|
+
### 5. ✅ Cycle Extraction Statistics
|
|
36
|
+
- **New method**: `get_extraction_stats()`
|
|
37
|
+
- **New method**: `reset_stats()`
|
|
38
|
+
- Tracks: total cycles, complete/incomplete counts, unmatched starts/ends, overlaps
|
|
39
|
+
- Calculates: success rate
|
|
40
|
+
- Stores: warnings, configuration
|
|
41
|
+
- Auto-updated during extraction
|
|
42
|
+
|
|
43
|
+
### 6. ✅ Improved Iterator Handling
|
|
44
|
+
- **Modified**: `_generate_cycle_dataframe()`
|
|
45
|
+
- Continues processing all starts even when ends run out
|
|
46
|
+
- Marks remaining cycles as incomplete instead of dropping
|
|
47
|
+
- Better error handling and logging
|
|
48
|
+
- Statistics tracking integrated
|
|
49
|
+
|
|
50
|
+
### 7. ✅ Value Change Significance Threshold
|
|
51
|
+
- **New parameter**: `value_change_threshold` in `__init__()` (default: 0.0)
|
|
52
|
+
- **Modified**: `process_value_change_cycle()` uses threshold
|
|
53
|
+
- Filters out noise in numeric data
|
|
54
|
+
- Applied to `value_double` and `value_integer` columns
|
|
55
|
+
- Boolean/string changes always considered significant
|
|
56
|
+
|
|
57
|
+
## New API Methods
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
# Constructor enhancement
|
|
61
|
+
CycleExtractor(dataframe, start_uuid, end_uuid=None, value_change_threshold=0.0)
|
|
62
|
+
|
|
63
|
+
# New validation method
|
|
64
|
+
validate_cycles(cycle_df, min_duration='1s', max_duration='1h', warn=True) -> pd.DataFrame
|
|
65
|
+
|
|
66
|
+
# New overlap detection method
|
|
67
|
+
detect_overlapping_cycles(cycle_df, resolve='flag') -> pd.DataFrame
|
|
68
|
+
|
|
69
|
+
# New suggestion method
|
|
70
|
+
suggest_method() -> Dict[str, Any]
|
|
71
|
+
|
|
72
|
+
# New statistics methods
|
|
73
|
+
get_extraction_stats() -> Dict[str, Any]
|
|
74
|
+
reset_stats() -> None
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## New DataFrame Columns
|
|
78
|
+
|
|
79
|
+
### All extraction methods now return:
|
|
80
|
+
- `cycle_start` (existing)
|
|
81
|
+
- `cycle_end` (existing)
|
|
82
|
+
- `cycle_uuid` (existing)
|
|
83
|
+
- `is_complete` (**NEW**) - Boolean flag
|
|
84
|
+
|
|
85
|
+
### After validation:
|
|
86
|
+
- `cycle_duration` - Timedelta
|
|
87
|
+
- `is_valid` - Boolean
|
|
88
|
+
- `validation_issue` - String (empty if valid)
|
|
89
|
+
|
|
90
|
+
### After overlap detection:
|
|
91
|
+
- `has_overlap` - Boolean
|
|
92
|
+
|
|
93
|
+
## Files Created/Modified
|
|
94
|
+
|
|
95
|
+
### Modified:
|
|
96
|
+
- `/home/user/ts-shape/src/ts_shape/features/cycles/cycles_extractor.py` - Main enhancement
|
|
97
|
+
|
|
98
|
+
### Created:
|
|
99
|
+
- `/home/user/ts-shape/examples/cycle_extractor_enhancements_demo.py` - Comprehensive demo
|
|
100
|
+
- `/home/user/ts-shape/docs/CYCLE_EXTRACTOR_ENHANCEMENTS.md` - Full documentation
|
|
101
|
+
- `/home/user/ts-shape/CYCLE_EXTRACTOR_CHANGES_SUMMARY.md` - This summary
|
|
102
|
+
|
|
103
|
+
## Testing
|
|
104
|
+
|
|
105
|
+
Demo script runs successfully:
|
|
106
|
+
```bash
|
|
107
|
+
python examples/cycle_extractor_enhancements_demo.py
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
All features tested and working:
|
|
111
|
+
- ✅ Basic extraction with incomplete tracking
|
|
112
|
+
- ✅ Cycle validation
|
|
113
|
+
- ✅ Overlap detection and resolution
|
|
114
|
+
- ✅ Method suggestions
|
|
115
|
+
- ✅ Statistics collection
|
|
116
|
+
- ✅ Value change thresholds
|
|
117
|
+
- ✅ Complete workflow integration
|
|
118
|
+
|
|
119
|
+
## Backward Compatibility
|
|
120
|
+
|
|
121
|
+
**100% backward compatible** - all existing code continues to work:
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
# Old code (still works perfectly)
|
|
125
|
+
extractor = CycleExtractor(df, 'uuid')
|
|
126
|
+
cycles = extractor.process_persistent_cycle()
|
|
127
|
+
# Returns: cycle_start, cycle_end, cycle_uuid, is_complete
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
New features are opt-in:
|
|
131
|
+
- New parameter `value_change_threshold` defaults to 0.0 (original behavior)
|
|
132
|
+
- New column `is_complete` can be ignored if not needed
|
|
133
|
+
- New methods are additions only
|
|
134
|
+
|
|
135
|
+
## Statistics Example
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
stats = extractor.get_extraction_stats()
|
|
139
|
+
# Returns:
|
|
140
|
+
{
|
|
141
|
+
'total_cycles': 60,
|
|
142
|
+
'complete_cycles': 60,
|
|
143
|
+
'incomplete_cycles': 0,
|
|
144
|
+
'unmatched_starts': 0,
|
|
145
|
+
'unmatched_ends': 0,
|
|
146
|
+
'overlapping_cycles': 0,
|
|
147
|
+
'success_rate': 1.0,
|
|
148
|
+
'warnings': [],
|
|
149
|
+
'configuration': {
|
|
150
|
+
'start_uuid': 'test-uuid-001',
|
|
151
|
+
'end_uuid': 'test-uuid-001',
|
|
152
|
+
'value_change_threshold': 0.0
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Performance Impact
|
|
158
|
+
|
|
159
|
+
- Minimal overhead for statistics tracking (O(1) per cycle)
|
|
160
|
+
- Validation: O(n) where n = number of cycles
|
|
161
|
+
- Overlap detection: O(n²) worst case, optimized with early breaks
|
|
162
|
+
- Method suggestion: O(m) where m = number of data rows
|
|
163
|
+
|
|
164
|
+
## Key Benefits
|
|
165
|
+
|
|
166
|
+
1. **No data loss**: Incomplete cycles are now tracked and flagged
|
|
167
|
+
2. **Better quality control**: Validation catches problematic cycles
|
|
168
|
+
3. **Easier debugging**: Statistics and warnings provide insights
|
|
169
|
+
4. **Smarter extraction**: Method suggestions help choose the right approach
|
|
170
|
+
5. **Flexible filtering**: Value change threshold reduces noise
|
|
171
|
+
6. **Production ready**: Overlap detection ensures clean data
|
|
172
|
+
7. **Fully compatible**: Drop-in replacement for existing code
|
|
173
|
+
|
|
174
|
+
## Code Quality
|
|
175
|
+
|
|
176
|
+
- ✅ Type hints added for all new methods
|
|
177
|
+
- ✅ Comprehensive docstrings
|
|
178
|
+
- ✅ Proper error handling
|
|
179
|
+
- ✅ Logging throughout
|
|
180
|
+
- ✅ No breaking changes
|
|
181
|
+
- ✅ Clean, maintainable code
|
|
182
|
+
- ✅ Follows existing code style
|
|
183
|
+
|
|
184
|
+
## Next Steps
|
|
185
|
+
|
|
186
|
+
To use the enhancements:
|
|
187
|
+
|
|
188
|
+
1. **Review documentation**: Read `/home/user/ts-shape/docs/CYCLE_EXTRACTOR_ENHANCEMENTS.md`
|
|
189
|
+
2. **Run demo**: Execute `python examples/cycle_extractor_enhancements_demo.py`
|
|
190
|
+
3. **Update code**: Add validation, statistics, or other features as needed
|
|
191
|
+
4. **Test thoroughly**: Use your actual data to verify behavior
|
|
192
|
+
|
|
193
|
+
## Support
|
|
194
|
+
|
|
195
|
+
For questions or issues:
|
|
196
|
+
- Check the full documentation in `/home/user/ts-shape/docs/CYCLE_EXTRACTOR_ENHANCEMENTS.md`
|
|
197
|
+
- Review examples in `/home/user/ts-shape/examples/cycle_extractor_enhancements_demo.py`
|
|
198
|
+
- Examine source code in `/home/user/ts-shape/src/ts_shape/features/cycles/cycles_extractor.py`
|