TimeFeatures 2.2.0__tar.gz → 2.3.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.
- {timefeatures-2.2.0/TimeFeatures.egg-info → timefeatures-2.3.0}/PKG-INFO +15 -7
- {timefeatures-2.2.0 → timefeatures-2.3.0}/README.md +6 -4
- {timefeatures-2.2.0 → timefeatures-2.3.0/TimeFeatures.egg-info}/PKG-INFO +15 -7
- {timefeatures-2.2.0 → timefeatures-2.3.0}/TimeFeatures.egg-info/SOURCES.txt +3 -1
- {timefeatures-2.2.0 → timefeatures-2.3.0}/TimeFeatures.egg-info/requires.txt +1 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/docs/changes.rst +31 -1
- {timefeatures-2.2.0 → timefeatures-2.3.0}/docs/index.rst +1 -2
- {timefeatures-2.2.0 → timefeatures-2.3.0}/docs/installation.rst +27 -4
- {timefeatures-2.2.0 → timefeatures-2.3.0}/docs/widgets/load-from-db.rst +16 -10
- {timefeatures-2.2.0 → timefeatures-2.3.0}/docs/widgets/save-to-db.rst +38 -31
- {timefeatures-2.2.0 → timefeatures-2.3.0}/docs/widgets/time-feature-constructor.rst +16 -4
- {timefeatures-2.2.0 → timefeatures-2.3.0}/docs/widgets/variable-dependency-graph.rst +20 -11
- timefeatures-2.3.0/setup.cfg +4 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/setup.py +17 -4
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/__version__.py +1 -1
- timefeatures-2.2.0/timefeatures/help_html/.buildinfo.bak → timefeatures-2.3.0/timefeatures/help_html/.buildinfo +1 -1
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_sources/changes.rst.txt +31 -1
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_sources/index.rst.txt +1 -2
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_sources/installation.rst.txt +27 -4
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_sources/widgets/load-from-db.rst.txt +16 -10
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_sources/widgets/save-to-db.rst.txt +38 -31
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_sources/widgets/time-feature-constructor.rst.txt +16 -4
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_sources/widgets/variable-dependency-graph.rst.txt +20 -11
- timefeatures-2.3.0/timefeatures/help_html/_static/base-stemmer.js +476 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_static/basic.css +0 -8
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_static/doctools.js +6 -5
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_static/documentation_options.js +1 -1
- timefeatures-2.3.0/timefeatures/help_html/_static/english-stemmer.js +1066 -0
- timefeatures-2.3.0/timefeatures/help_html/_static/language_data.js +13 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_static/searchtools.js +121 -60
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_static/sphinx_highlight.js +36 -31
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/changes.html +37 -7
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/genindex.html +4 -4
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/index.html +6 -7
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/installation.html +33 -11
- timefeatures-2.3.0/timefeatures/help_html/objects.inv +11 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/search.html +4 -4
- timefeatures-2.3.0/timefeatures/help_html/searchindex.js +1 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/widgets/load-from-db.html +20 -14
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/widgets/save-to-db.html +41 -36
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/widgets/time-feature-constructor.html +19 -8
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/widgets/variable-dependency-graph.html +24 -15
- timefeatures-2.3.0/timefeatures/widgets/_threads.py +88 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/widgets/owloadfromdb.py +43 -46
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/widgets/owsavetodb.py +131 -47
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/widgets/owtimefeaturesconstructor.py +65 -110
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/widgets/owvardependencygraph.py +108 -49
- timefeatures-2.2.0/setup.cfg +0 -7
- timefeatures-2.2.0/timefeatures/help_html/_static/language_data.js +0 -192
- timefeatures-2.2.0/timefeatures/help_html/objects.inv +0 -0
- timefeatures-2.2.0/timefeatures/help_html/searchindex.js +0 -1
- {timefeatures-2.2.0 → timefeatures-2.3.0}/LICENSE +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/MANIFEST.in +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/TimeFeatures.egg-info/dependency_links.txt +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/TimeFeatures.egg-info/entry_points.txt +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/TimeFeatures.egg-info/top_level.txt +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/docs/Makefile +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/docs/conf.py +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/docs/requirements.txt +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/imgs/installation.png +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/imgs/widgets/owloadfromdb.png +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/imgs/widgets/owsavetodb.png +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/imgs/widgets/owtimefeaturesconstructor.png +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/imgs/widgets/owvariabledependencygraph.png +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/imgs/workflow.png +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/__init__.py +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help.py +0 -0
- /timefeatures-2.2.0/timefeatures/help_html/.buildinfo → /timefeatures-2.3.0/timefeatures/help_html/.buildinfo.bak +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_images/owloadfromdb.png +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_images/owsavetodb.png +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_images/owtimefeaturesconstructor.png +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_images/owvariabledependencygraph.png +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_static/alabaster.css +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_static/custom.css +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_static/file.png +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_static/github-banner.svg +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_static/minus.png +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_static/plus.png +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/help_html/_static/pygments.css +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/widgets/__init__.py +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/widgets/icons/graphgenerator.svg +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/widgets/icons/loaddatadb.svg +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/widgets/icons/savedatadb.svg +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/widgets/icons/timefeature-xs.svg +0 -0
- {timefeatures-2.2.0 → timefeatures-2.3.0}/timefeatures/widgets/icons/timefeature.svg +0 -0
|
@@ -1,23 +1,28 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: TimeFeatures
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Timefeatures add-on for Orange 3 data mining software.
|
|
5
5
|
Home-page: https://github.com/alervgr/Orange-TimeFeatures
|
|
6
6
|
Author: Alejandro Rivas García
|
|
7
7
|
Author-email: alejandrorivasgarcia@gmail.com
|
|
8
|
-
License:
|
|
8
|
+
License: GPL-3.0-or-later
|
|
9
9
|
Keywords: orange3 add-on,timefeatures,graph,time series,data mining,graph visualization,orange,addon,synthetic data
|
|
10
10
|
Classifier: Development Status :: 4 - Beta
|
|
11
11
|
Classifier: Environment :: Plugins
|
|
12
12
|
Classifier: Programming Language :: Python
|
|
13
|
-
Classifier:
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
17
|
Classifier: Operating System :: OS Independent
|
|
15
18
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
19
|
Classifier: Intended Audience :: Education
|
|
17
20
|
Classifier: Intended Audience :: Science/Research
|
|
18
21
|
Classifier: Intended Audience :: Developers
|
|
22
|
+
Requires-Python: >=3.10
|
|
19
23
|
Description-Content-Type: text/markdown
|
|
20
24
|
License-File: LICENSE
|
|
25
|
+
Requires-Dist: Orange3>=3.36.2
|
|
21
26
|
Requires-Dist: numpy>=1.22.4
|
|
22
27
|
Requires-Dist: AnyQt>=0.2.0
|
|
23
28
|
Requires-Dist: PyQt5>=5.15.6
|
|
@@ -40,13 +45,15 @@ Dynamic: license
|
|
|
40
45
|
Dynamic: license-file
|
|
41
46
|
Dynamic: provides-extra
|
|
42
47
|
Dynamic: requires-dist
|
|
48
|
+
Dynamic: requires-python
|
|
43
49
|
Dynamic: summary
|
|
44
50
|
|
|
45
51
|
# Orange3 TimeFeatures
|
|
46
52
|
|
|
47
53
|
[](https://pypi.org/project/TimeFeatures/)
|
|
48
54
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
49
|
-
[](https://www.python.org/downloads/)
|
|
56
|
+
[](https://github.com/alervgr/Orange-TimeFeatures/actions/workflows/ci.yml)
|
|
50
57
|
[](https://orangedatamining.com/)
|
|
51
58
|
|
|
52
59
|
TimeFeatures is an add-on for [Orange] 3 data mining software for generating synthetic data using datasets with time series, generating graphs of relationships between the generated variables, and includes widgets to save and load data and configuration tables from a database.
|
|
@@ -57,7 +64,7 @@ TimeFeatures is an add-on for [Orange] 3 data mining software for generating syn
|
|
|
57
64
|
|
|
58
65
|
- 🕐 **7 time-window functions** — `shift`, `sum`, `mean`, `min`, `max`, `count`, `sd` with full chunk-boundary correctness
|
|
59
66
|
- 🔗 **Chained descriptors** — derived variables can reference each other; topological sort resolves the evaluation order automatically
|
|
60
|
-
-
|
|
67
|
+
- 🧮 **Python-style expressions** — evaluated with a restricted `eval` (`__builtins__` replaced, curated whitelist only). This is **not** a security sandbox: expressions can still run arbitrary code, so only open workflows from sources you trust
|
|
61
68
|
- 🗄️ **PostgreSQL & MySQL** — persist and reload datasets via SQLAlchemy with dialect-agnostic SQL generation
|
|
62
69
|
- 📊 **Directed weighted dependency graphs** — edge weights reflect temporal window size; visualise in Network Explorer
|
|
63
70
|
- ⚡ **Bulk upload performance** — pandas `DataFrame.to_sql` with chunked multi-row INSERTs
|
|
@@ -69,7 +76,7 @@ TimeFeatures is an add-on for [Orange] 3 data mining software for generating syn
|
|
|
69
76
|
|---|---|
|
|
70
77
|
| **Time Features Constructor** | Defines new variables from existing ones using Python-style expressions and time-window functions. Supports chained descriptors with automatic topological sorting. |
|
|
71
78
|
| **Variable Dependency Graph** | Builds a directed, weighted dependency graph from the variable definitions. Edge weights summarise how far back or forward in time each variable looks. |
|
|
72
|
-
| **Save to DB** | Persists the resulting dataset to a SQL database (PostgreSQL or MySQL), with full SQL-injection defences
|
|
79
|
+
| **Save to DB** | Persists the resulting dataset to a SQL database (PostgreSQL or MySQL), with full SQL-injection defences and three write modes (create / overwrite / append). |
|
|
73
80
|
| **Load from DB** | Lists datasets previously stored by Save to DB and pulls the chosen one back into Orange, optionally marking the class column directly so no Select Columns widget is needed. |
|
|
74
81
|
|
|
75
82
|
## Installation
|
|
@@ -96,8 +103,9 @@ If using Anaconda Python distribution, simply run
|
|
|
96
103
|
|
|
97
104
|
pip install TimeFeatures
|
|
98
105
|
|
|
99
|
-
**Required Dependencies
|
|
106
|
+
**Required Dependencies** (Python 3.10 or newer):
|
|
100
107
|
|
|
108
|
+
* Orange3>=3.36.2
|
|
101
109
|
* numpy>=1.22.4
|
|
102
110
|
* AnyQt>=0.2.0
|
|
103
111
|
* PyQt5>=5.15.6
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://pypi.org/project/TimeFeatures/)
|
|
4
4
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
5
|
-
[](https://www.python.org/downloads/)
|
|
6
|
+
[](https://github.com/alervgr/Orange-TimeFeatures/actions/workflows/ci.yml)
|
|
6
7
|
[](https://orangedatamining.com/)
|
|
7
8
|
|
|
8
9
|
TimeFeatures is an add-on for [Orange] 3 data mining software for generating synthetic data using datasets with time series, generating graphs of relationships between the generated variables, and includes widgets to save and load data and configuration tables from a database.
|
|
@@ -13,7 +14,7 @@ TimeFeatures is an add-on for [Orange] 3 data mining software for generating syn
|
|
|
13
14
|
|
|
14
15
|
- 🕐 **7 time-window functions** — `shift`, `sum`, `mean`, `min`, `max`, `count`, `sd` with full chunk-boundary correctness
|
|
15
16
|
- 🔗 **Chained descriptors** — derived variables can reference each other; topological sort resolves the evaluation order automatically
|
|
16
|
-
-
|
|
17
|
+
- 🧮 **Python-style expressions** — evaluated with a restricted `eval` (`__builtins__` replaced, curated whitelist only). This is **not** a security sandbox: expressions can still run arbitrary code, so only open workflows from sources you trust
|
|
17
18
|
- 🗄️ **PostgreSQL & MySQL** — persist and reload datasets via SQLAlchemy with dialect-agnostic SQL generation
|
|
18
19
|
- 📊 **Directed weighted dependency graphs** — edge weights reflect temporal window size; visualise in Network Explorer
|
|
19
20
|
- ⚡ **Bulk upload performance** — pandas `DataFrame.to_sql` with chunked multi-row INSERTs
|
|
@@ -25,7 +26,7 @@ TimeFeatures is an add-on for [Orange] 3 data mining software for generating syn
|
|
|
25
26
|
|---|---|
|
|
26
27
|
| **Time Features Constructor** | Defines new variables from existing ones using Python-style expressions and time-window functions. Supports chained descriptors with automatic topological sorting. |
|
|
27
28
|
| **Variable Dependency Graph** | Builds a directed, weighted dependency graph from the variable definitions. Edge weights summarise how far back or forward in time each variable looks. |
|
|
28
|
-
| **Save to DB** | Persists the resulting dataset to a SQL database (PostgreSQL or MySQL), with full SQL-injection defences
|
|
29
|
+
| **Save to DB** | Persists the resulting dataset to a SQL database (PostgreSQL or MySQL), with full SQL-injection defences and three write modes (create / overwrite / append). |
|
|
29
30
|
| **Load from DB** | Lists datasets previously stored by Save to DB and pulls the chosen one back into Orange, optionally marking the class column directly so no Select Columns widget is needed. |
|
|
30
31
|
|
|
31
32
|
## Installation
|
|
@@ -52,8 +53,9 @@ If using Anaconda Python distribution, simply run
|
|
|
52
53
|
|
|
53
54
|
pip install TimeFeatures
|
|
54
55
|
|
|
55
|
-
**Required Dependencies
|
|
56
|
+
**Required Dependencies** (Python 3.10 or newer):
|
|
56
57
|
|
|
58
|
+
* Orange3>=3.36.2
|
|
57
59
|
* numpy>=1.22.4
|
|
58
60
|
* AnyQt>=0.2.0
|
|
59
61
|
* PyQt5>=5.15.6
|
|
@@ -1,23 +1,28 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: TimeFeatures
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Timefeatures add-on for Orange 3 data mining software.
|
|
5
5
|
Home-page: https://github.com/alervgr/Orange-TimeFeatures
|
|
6
6
|
Author: Alejandro Rivas García
|
|
7
7
|
Author-email: alejandrorivasgarcia@gmail.com
|
|
8
|
-
License:
|
|
8
|
+
License: GPL-3.0-or-later
|
|
9
9
|
Keywords: orange3 add-on,timefeatures,graph,time series,data mining,graph visualization,orange,addon,synthetic data
|
|
10
10
|
Classifier: Development Status :: 4 - Beta
|
|
11
11
|
Classifier: Environment :: Plugins
|
|
12
12
|
Classifier: Programming Language :: Python
|
|
13
|
-
Classifier:
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
17
|
Classifier: Operating System :: OS Independent
|
|
15
18
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
19
|
Classifier: Intended Audience :: Education
|
|
17
20
|
Classifier: Intended Audience :: Science/Research
|
|
18
21
|
Classifier: Intended Audience :: Developers
|
|
22
|
+
Requires-Python: >=3.10
|
|
19
23
|
Description-Content-Type: text/markdown
|
|
20
24
|
License-File: LICENSE
|
|
25
|
+
Requires-Dist: Orange3>=3.36.2
|
|
21
26
|
Requires-Dist: numpy>=1.22.4
|
|
22
27
|
Requires-Dist: AnyQt>=0.2.0
|
|
23
28
|
Requires-Dist: PyQt5>=5.15.6
|
|
@@ -40,13 +45,15 @@ Dynamic: license
|
|
|
40
45
|
Dynamic: license-file
|
|
41
46
|
Dynamic: provides-extra
|
|
42
47
|
Dynamic: requires-dist
|
|
48
|
+
Dynamic: requires-python
|
|
43
49
|
Dynamic: summary
|
|
44
50
|
|
|
45
51
|
# Orange3 TimeFeatures
|
|
46
52
|
|
|
47
53
|
[](https://pypi.org/project/TimeFeatures/)
|
|
48
54
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
49
|
-
[](https://www.python.org/downloads/)
|
|
56
|
+
[](https://github.com/alervgr/Orange-TimeFeatures/actions/workflows/ci.yml)
|
|
50
57
|
[](https://orangedatamining.com/)
|
|
51
58
|
|
|
52
59
|
TimeFeatures is an add-on for [Orange] 3 data mining software for generating synthetic data using datasets with time series, generating graphs of relationships between the generated variables, and includes widgets to save and load data and configuration tables from a database.
|
|
@@ -57,7 +64,7 @@ TimeFeatures is an add-on for [Orange] 3 data mining software for generating syn
|
|
|
57
64
|
|
|
58
65
|
- 🕐 **7 time-window functions** — `shift`, `sum`, `mean`, `min`, `max`, `count`, `sd` with full chunk-boundary correctness
|
|
59
66
|
- 🔗 **Chained descriptors** — derived variables can reference each other; topological sort resolves the evaluation order automatically
|
|
60
|
-
-
|
|
67
|
+
- 🧮 **Python-style expressions** — evaluated with a restricted `eval` (`__builtins__` replaced, curated whitelist only). This is **not** a security sandbox: expressions can still run arbitrary code, so only open workflows from sources you trust
|
|
61
68
|
- 🗄️ **PostgreSQL & MySQL** — persist and reload datasets via SQLAlchemy with dialect-agnostic SQL generation
|
|
62
69
|
- 📊 **Directed weighted dependency graphs** — edge weights reflect temporal window size; visualise in Network Explorer
|
|
63
70
|
- ⚡ **Bulk upload performance** — pandas `DataFrame.to_sql` with chunked multi-row INSERTs
|
|
@@ -69,7 +76,7 @@ TimeFeatures is an add-on for [Orange] 3 data mining software for generating syn
|
|
|
69
76
|
|---|---|
|
|
70
77
|
| **Time Features Constructor** | Defines new variables from existing ones using Python-style expressions and time-window functions. Supports chained descriptors with automatic topological sorting. |
|
|
71
78
|
| **Variable Dependency Graph** | Builds a directed, weighted dependency graph from the variable definitions. Edge weights summarise how far back or forward in time each variable looks. |
|
|
72
|
-
| **Save to DB** | Persists the resulting dataset to a SQL database (PostgreSQL or MySQL), with full SQL-injection defences
|
|
79
|
+
| **Save to DB** | Persists the resulting dataset to a SQL database (PostgreSQL or MySQL), with full SQL-injection defences and three write modes (create / overwrite / append). |
|
|
73
80
|
| **Load from DB** | Lists datasets previously stored by Save to DB and pulls the chosen one back into Orange, optionally marking the class column directly so no Select Columns widget is needed. |
|
|
74
81
|
|
|
75
82
|
## Installation
|
|
@@ -96,8 +103,9 @@ If using Anaconda Python distribution, simply run
|
|
|
96
103
|
|
|
97
104
|
pip install TimeFeatures
|
|
98
105
|
|
|
99
|
-
**Required Dependencies
|
|
106
|
+
**Required Dependencies** (Python 3.10 or newer):
|
|
100
107
|
|
|
108
|
+
* Orange3>=3.36.2
|
|
101
109
|
* numpy>=1.22.4
|
|
102
110
|
* AnyQt>=0.2.0
|
|
103
111
|
* PyQt5>=5.15.6
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
LICENSE
|
|
2
2
|
MANIFEST.in
|
|
3
3
|
README.md
|
|
4
|
-
setup.cfg
|
|
5
4
|
setup.py
|
|
6
5
|
TimeFeatures.egg-info/PKG-INFO
|
|
7
6
|
TimeFeatures.egg-info/SOURCES.txt
|
|
@@ -49,10 +48,12 @@ timefeatures/help_html/_sources/widgets/save-to-db.rst.txt
|
|
|
49
48
|
timefeatures/help_html/_sources/widgets/time-feature-constructor.rst.txt
|
|
50
49
|
timefeatures/help_html/_sources/widgets/variable-dependency-graph.rst.txt
|
|
51
50
|
timefeatures/help_html/_static/alabaster.css
|
|
51
|
+
timefeatures/help_html/_static/base-stemmer.js
|
|
52
52
|
timefeatures/help_html/_static/basic.css
|
|
53
53
|
timefeatures/help_html/_static/custom.css
|
|
54
54
|
timefeatures/help_html/_static/doctools.js
|
|
55
55
|
timefeatures/help_html/_static/documentation_options.js
|
|
56
|
+
timefeatures/help_html/_static/english-stemmer.js
|
|
56
57
|
timefeatures/help_html/_static/file.png
|
|
57
58
|
timefeatures/help_html/_static/github-banner.svg
|
|
58
59
|
timefeatures/help_html/_static/language_data.js
|
|
@@ -66,6 +67,7 @@ timefeatures/help_html/widgets/save-to-db.html
|
|
|
66
67
|
timefeatures/help_html/widgets/time-feature-constructor.html
|
|
67
68
|
timefeatures/help_html/widgets/variable-dependency-graph.html
|
|
68
69
|
timefeatures/widgets/__init__.py
|
|
70
|
+
timefeatures/widgets/_threads.py
|
|
69
71
|
timefeatures/widgets/owloadfromdb.py
|
|
70
72
|
timefeatures/widgets/owsavetodb.py
|
|
71
73
|
timefeatures/widgets/owtimefeaturesconstructor.py
|
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
2.3.0
|
|
5
|
+
-----
|
|
6
|
+
|
|
7
|
+
**Fixes**
|
|
8
|
+
|
|
9
|
+
- *Fix (Time Features Constructor):* time-window functions accept spaces between arguments (``shift(x, -1)``, ``mean(x, -2, 0)``) and a leading ``+`` on offsets (``shift(x,+1)``). Previously these raised ``NameError`` or ``TypeError``. ``min(``, ``max(``, ``mean(`` and ``sum(`` are no longer matched inside longer names such as ``nanmin(``.
|
|
10
|
+
- *Fix (Time Features Constructor):* columns whose names contain punctuation other than spaces or hyphens (``a.b``, ``temp (C)``) or start with a digit (``1abc``) can be referenced by their sanitised name (``a_b``, ``temp__C_``, ``_1abc``), as the documentation already stated. Previously they raised ``NameError``.
|
|
11
|
+
- *Fix (Time Features Constructor):* expressions that reference no column (constants such as ``42``, and invalid expressions that the widget blanks out) yield one value per row instead of failing with *could not broadcast input array*.
|
|
12
|
+
- *Fix (Variable Dependency Graph):* variable names are sanitised with the constructor's ``sanitized_name``, so references to columns with punctuation or a leading digit now produce edges. Node names for those columns change accordingly (``temp (C)`` → ``temp__C_``).
|
|
13
|
+
- *Fix (Variable Dependency Graph):* references and temporal weights are read from the expression's syntax tree instead of searching its text. Names inside string literals, names bound in comprehensions or lambdas, and called function names (e.g. a column called ``sum``) no longer create edges, and a temporal call only counts in the form the constructor evaluates. Expressions that cannot be parsed get no edges and a new warning names them.
|
|
14
|
+
- *Fix (Save to DB):* **Overwrite** no longer drops the existing table before uploading. The data goes into a staging table that replaces the target only once every chunk is in (atomic ``RENAME TABLE`` on MySQL). Previously, on MySQL, a failed or cancelled Overwrite lost the original table because DDL auto-commits. The same staging path means a failed or cancelled **Create** (or **Append** into a missing table) no longer leaves a half-written table behind, and **Create** now also refuses a table that exists without a ``datasets`` row.
|
|
15
|
+
- *Fix (Load from DB):* each background operation keeps its own thread. Previously the listing thread, on finishing, cleared the references of the load it had just started (auto-load on workflow reopen, or Load clicked right after listing): **Cancel** stopped working, and closing the widget could destroy the still-running thread and abort Orange (*QThread: Destroyed while thread is still running*).
|
|
16
|
+
- *Fix (Load from DB / Save to DB):* removing the widget or closing the workflow mid-operation no longer freezes the canvas waiting for the query or upload to end; the operation is cancelled and its thread ends on its own. On exit, Orange waits for any such thread to finish.
|
|
17
|
+
- *Improvement (Load from DB):* loads read through a server-side cursor (``stream_results``), so rows really arrive in 1 000-row chunks: the progress bar is accurate and **Cancel** takes effect within one chunk instead of after the whole table has been fetched. **Cancel** is no longer enabled while a dataset is being deleted.
|
|
18
|
+
- *Tests (Save to DB):* the upload worker is tested end to end on SQLite and, when ``TIMEFEATURES_TEST_POSTGRES_URL`` / ``TIMEFEATURES_TEST_MYSQL_URL`` point to disposable databases, on real PostgreSQL and MySQL servers, including failures and cancellations mid-upload.
|
|
19
|
+
|
|
20
|
+
**Packaging & CI**
|
|
21
|
+
|
|
22
|
+
- ``setup.py`` now declares ``Orange3>=3.36.2`` and ``python_requires=">=3.10"``, the oldest combination the tests pass on (older Orange3 releases do not work with NumPy 2). Previously Orange3 only arrived indirectly through Orange3-Network, and the README advertised Python 3.8+.
|
|
23
|
+
- New GitHub Actions workflow (``.github/workflows/ci.yml``): the test suite on Python 3.10 with Orange3 3.36.2 and on Python 3.11 and 3.12 with the latest releases, with the Save to DB tests also running against PostgreSQL and MySQL service containers; a package job that builds the sdist and wheel, runs ``twine check`` and installs the wheel into an empty environment to check the entry points, icons and bundled help; and a docs job that builds Sphinx with warnings as errors.
|
|
24
|
+
- Removed ``setup.cfg``: its only key (``description-file``) is deprecated and will stop being accepted by setuptools; ``setup.py`` already sets the long description.
|
|
25
|
+
- The license is declared as the SPDX expression ``GPL-3.0-or-later`` instead of the deprecated license classifier, and packages are discovered with ``find_namespace_packages`` so setuptools keeps shipping the bundled help and icons without warnings. The built wheel has exactly the same files as before.
|
|
26
|
+
- Automatic releases: after a merge to ``main``, once the tests, package and docs jobs pass, the workflow publishes the version in ``timefeatures/__version__.py`` to PyPI if it is not there yet (PyPI trusted publishing, no stored token) and creates the matching ``vX.Y.Z`` tag and GitHub release. See ``RELEASING.md``.
|
|
27
|
+
|
|
28
|
+
**Documentation**
|
|
29
|
+
|
|
30
|
+
- The README and the constructor page no longer describe the restricted ``eval`` as a secure sandbox; they warn to open workflows only from trusted sources.
|
|
31
|
+
- Removed the completion-email references from the README, the index and the Save to DB page: notifications are currently disabled.
|
|
32
|
+
- Rebuilt the bundled in-app help (``timefeatures/help_html``) so the Orange Help window shows the updated pages.
|
|
33
|
+
|
|
4
34
|
2.2.0 — 2026-06-09
|
|
5
35
|
-------------------
|
|
6
36
|
|
|
@@ -11,7 +41,7 @@ Changelog
|
|
|
11
41
|
- *Improvement (Load from DB):* **Smooth progress reporting**. The background reader now streams data in chunks (``chunksize=1000``) rather than running a single monolithic ``read_sql`` query. The progress bar updates continuously as rows arrive, preventing the UI from appearing frozen during large transfers.
|
|
12
42
|
- *UX:* Improved button alignment and spacing in both database widgets to avoid visual overlap. In ``Save to DB``, the Cancel button is stacked logically above the Save button for improved space usage.
|
|
13
43
|
|
|
14
|
-
2.1.1
|
|
44
|
+
2.1.1
|
|
15
45
|
-------------------
|
|
16
46
|
|
|
17
47
|
**Load from DB (new widget)**
|
|
@@ -22,8 +22,7 @@ built on top of an existing dataset.
|
|
|
22
22
|
how far back or forward in time each variable looks.
|
|
23
23
|
* - :doc:`widgets/save-to-db`
|
|
24
24
|
- Persists the resulting dataset to a SQL database (PostgreSQL
|
|
25
|
-
or MySQL), with full SQL-injection defences
|
|
26
|
-
completion email.
|
|
25
|
+
or MySQL), with full SQL-injection defences.
|
|
27
26
|
* - :doc:`widgets/load-from-db`
|
|
28
27
|
- Lists the datasets previously stored by Save to DB and pulls
|
|
29
28
|
the chosen one back into Orange, optionally marking the class
|
|
@@ -50,8 +50,8 @@ environment as long as Orange3 is installed there.
|
|
|
50
50
|
Dependencies
|
|
51
51
|
------------
|
|
52
52
|
|
|
53
|
-
|addon| declares the following runtime
|
|
54
|
-
``setup.py``):
|
|
53
|
+
|addon| needs Python 3.10 or newer and declares the following runtime
|
|
54
|
+
dependencies (see ``setup.py``):
|
|
55
55
|
|
|
56
56
|
.. list-table::
|
|
57
57
|
:header-rows: 1
|
|
@@ -59,6 +59,10 @@ Dependencies
|
|
|
59
59
|
* - Package
|
|
60
60
|
- Minimum version
|
|
61
61
|
- Used by
|
|
62
|
+
* - ``Orange3``
|
|
63
|
+
- 3.36.2
|
|
64
|
+
- Host application and data model. Older releases do not work with
|
|
65
|
+
NumPy 2.
|
|
62
66
|
* - ``numpy``
|
|
63
67
|
- 1.22.4
|
|
64
68
|
- All widgets.
|
|
@@ -68,6 +72,9 @@ Dependencies
|
|
|
68
72
|
* - ``PyQt5``
|
|
69
73
|
- 5.15.6
|
|
70
74
|
- Widget UI.
|
|
75
|
+
* - ``PyQtWebEngine``
|
|
76
|
+
- 5.15.6
|
|
77
|
+
- Orange's in-app help window.
|
|
71
78
|
* - ``AnyQt``
|
|
72
79
|
- 0.2.0
|
|
73
80
|
- Qt abstraction used by Orange.
|
|
@@ -84,8 +91,15 @@ Dependencies
|
|
|
84
91
|
- 1.8.0
|
|
85
92
|
- ``Network`` type produced by **Variable Dependency Graph**.
|
|
86
93
|
|
|
87
|
-
Orange3
|
|
88
|
-
|
|
94
|
+
Orange3 is listed explicitly so a clean ``pip install`` gets a version
|
|
95
|
+
the add-on is tested with. Inside an existing Orange installation that
|
|
96
|
+
already meets the minimum, pip leaves it untouched.
|
|
97
|
+
|
|
98
|
+
The CI workflow (``.github/workflows/ci.yml``) runs the test suite on
|
|
99
|
+
Python 3.10 with Orange3 3.36.2 and on Python 3.11 and 3.12 with the
|
|
100
|
+
latest releases, builds the package and installs the wheel into an
|
|
101
|
+
empty environment, and builds this documentation with warnings as
|
|
102
|
+
errors.
|
|
89
103
|
|
|
90
104
|
Running tests
|
|
91
105
|
-------------
|
|
@@ -101,3 +115,12 @@ The test suite uses ``unittest`` and lives under
|
|
|
101
115
|
The widget-level tests inherit from ``Orange.widgets.tests.base.WidgetTest``
|
|
102
116
|
and therefore require Qt; a virtual display (``Xvfb``) is enough on a
|
|
103
117
|
headless CI worker.
|
|
118
|
+
|
|
119
|
+
The Save to DB upload tests always run on SQLite. To also run them
|
|
120
|
+
against real servers, point these variables to **disposable** databases
|
|
121
|
+
(the tests create and drop tables there):
|
|
122
|
+
|
|
123
|
+
.. code-block:: bash
|
|
124
|
+
|
|
125
|
+
export TIMEFEATURES_TEST_POSTGRES_URL=postgresql://user:pass@localhost:5432/timefeatures_test
|
|
126
|
+
export TIMEFEATURES_TEST_MYSQL_URL=mysql://user:pass@127.0.0.1:3306/timefeatures_test
|
|
@@ -90,22 +90,28 @@ then spawns a background ``QThread`` that runs a
|
|
|
90
90
|
``_ListDatasetsWorker``. The worker queries the ``datasets`` metadata
|
|
91
91
|
table via SQLAlchemy and emits the result back to the GUI thread.
|
|
92
92
|
|
|
93
|
-
Selecting a dataset
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
When **Load** is clicked, a ``_LoadTableWorker``
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
93
|
+
Selecting a dataset runs ``SELECT * FROM <name> LIMIT 50`` to fill the
|
|
94
|
+
preview and the column list. This small query still runs on the GUI
|
|
95
|
+
thread, so on a slow connection the widget pauses briefly.
|
|
96
|
+
|
|
97
|
+
When **Load** is clicked, a ``_LoadTableWorker`` reads the table on a
|
|
98
|
+
background thread in 1 000-row chunks through a server-side cursor
|
|
99
|
+
(``stream_results``), so the progress bar follows the rows as they
|
|
100
|
+
arrive and **Cancel** stops the load within one chunk. The resulting
|
|
101
|
+
DataFrame is converted in the GUI thread into an ``Orange.data.Table``
|
|
102
|
+
with ``Orange.data.pandas_compat.table_from_frame``. If the user picked
|
|
103
|
+
a class column, the helper ``_build_domain_with_class`` rebuilds the
|
|
103
104
|
domain so that column becomes ``domain.class_var`` and the rest of the
|
|
104
105
|
columns stay in ``domain.attributes``.
|
|
105
106
|
|
|
106
107
|
While any worker runs, the form controls (database type, connection
|
|
107
108
|
fields, **Connect**, **Load**, dataset and class combos) are
|
|
108
109
|
temporarily disabled and the status label keeps the user informed.
|
|
110
|
+
Each operation keeps its own thread, so an operation started from the
|
|
111
|
+
end of another (the auto-load right after the listing, or the listing
|
|
112
|
+
right after a delete) is never cut short or left uncancellable.
|
|
113
|
+
Removing the widget or closing the workflow during a load cancels it
|
|
114
|
+
instead of freezing the canvas until the query ends.
|
|
109
115
|
|
|
110
116
|
Auto-load
|
|
111
117
|
---------
|
|
@@ -65,32 +65,34 @@ TimeFeatures-specific controls:
|
|
|
65
65
|
rules (see *Validation* below); MySQL accepts a superset, so
|
|
66
66
|
the same rule is safe on both.
|
|
67
67
|
* - Mode
|
|
68
|
-
- Combo
|
|
68
|
+
- Combo below the Table name field:
|
|
69
69
|
|
|
70
70
|
- **Create new (fail if table exists)** — default, refuses to
|
|
71
71
|
touch an existing table or metadata row. Use this for first
|
|
72
72
|
uploads or when you want a clear error on accidental name
|
|
73
73
|
collisions.
|
|
74
|
-
- **Overwrite (
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
- **Overwrite (replace existing table)** — uploads the new data
|
|
75
|
+
and only then replaces the existing table and its
|
|
76
|
+
``datasets`` row. If the upload fails or is cancelled, the
|
|
77
|
+
previous table is kept. Re-running the workflow stops
|
|
78
|
+
breaking.
|
|
77
79
|
- **Append (keep existing rows)** — adds rows to the existing
|
|
78
80
|
table (creating it if it doesn't exist). After the upload,
|
|
79
81
|
the widget runs ``SELECT COUNT(*)`` and rewrites the
|
|
80
82
|
``datasets`` row with the *actual* total row count, so the
|
|
81
83
|
registry stays accurate across repeated appends.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
|
|
85
|
+
.. note::
|
|
86
|
+
|
|
87
|
+
Completion-email notifications are currently disabled; the Email
|
|
88
|
+
field is hidden until they are re-enabled.
|
|
86
89
|
|
|
87
90
|
How it Works
|
|
88
91
|
------------
|
|
89
92
|
|
|
90
93
|
When **Save** is clicked, the widget:
|
|
91
94
|
|
|
92
|
-
1. Validates the table name and the form (host, database
|
|
93
|
-
email).
|
|
95
|
+
1. Validates the table name and the form (host, database).
|
|
94
96
|
2. Builds a SQLAlchemy URL from the form fields and the active dialect
|
|
95
97
|
driver (``postgresql+psycopg2://…`` or ``mysql+pymysql://…``).
|
|
96
98
|
3. Spawns a background ``QThread`` running an ``_UploadWorker``, so the
|
|
@@ -102,33 +104,40 @@ When **Save** is clicked, the widget:
|
|
|
102
104
|
and reorders the columns (class first, then metas in domain
|
|
103
105
|
order, then attributes) to match the existing schema convention;
|
|
104
106
|
- ensures the ``datasets`` metadata table exists;
|
|
105
|
-
- applies the mode-specific
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
already exists.
|
|
109
|
-
- **overwrite** — ``DROP TABLE IF EXISTS`` on the target plus
|
|
110
|
-
``DELETE`` of the matching ``datasets`` row.
|
|
111
|
-
- **append** — leave everything in place; the upload itself will
|
|
112
|
-
create the table on the first chunk if it doesn't exist.
|
|
113
|
-
|
|
107
|
+
- applies the mode-specific checks: **create** fails fast if a
|
|
108
|
+
``datasets`` row or a table with this name already exists;
|
|
109
|
+
**overwrite** and **append** leave everything in place;
|
|
114
110
|
- writes the dataset in ``PANDAS_SQL_CHUNKSIZE`` chunks (default
|
|
115
|
-
``1 000``) via ``df.to_sql(..., method='multi')
|
|
116
|
-
|
|
117
|
-
|
|
111
|
+
``1 000``) via ``df.to_sql(..., method='multi')``. **Append** into
|
|
112
|
+
an existing table writes straight into it. Every other case writes
|
|
113
|
+
into a uniquely named staging table (``_tf_staging_…``);
|
|
114
|
+
- once every chunk is in, swaps the staging table in place of the
|
|
115
|
+
target: ``DROP TABLE`` + ``ALTER TABLE … RENAME`` on PostgreSQL, a
|
|
116
|
+
single multi-table ``RENAME TABLE`` on MySQL;
|
|
118
117
|
- runs ``SELECT COUNT(*)`` on the target table and re-inserts the
|
|
119
118
|
``datasets`` row with that real row count, so the registry stays
|
|
120
119
|
consistent even after multiple appends.
|
|
121
120
|
|
|
122
121
|
Everything happens inside a single SQLAlchemy transaction
|
|
123
|
-
(``engine.begin()``)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
122
|
+
(``engine.begin()``). On PostgreSQL, DDL is transactional, so a
|
|
123
|
+
mid-upload error or a **Cancel** rolls every step back. MySQL
|
|
124
|
+
auto-commits DDL (``CREATE TABLE``, ``RENAME TABLE``), which is why the
|
|
125
|
+
upload goes through a staging table: until the final swap the target
|
|
126
|
+
table is untouched, and on failure the widget drops the staging table
|
|
127
|
+
again. Appended rows are ordinary ``INSERT`` statements and are rolled
|
|
128
|
+
back on both engines.
|
|
129
|
+
|
|
130
|
+
.. note::
|
|
131
|
+
|
|
132
|
+
If Orange is killed in the middle of an upload to MySQL, the staging
|
|
133
|
+
table cannot be cleaned up and stays behind as ``_tf_staging_…``. It
|
|
134
|
+
never appears in **Load from DB** and can be dropped by hand.
|
|
128
135
|
|
|
129
136
|
While the worker runs, the widget's progress bar and status label are
|
|
130
137
|
updated through Qt signals; the **Save**, **Connect** and form controls
|
|
131
|
-
are temporarily disabled.
|
|
138
|
+
are temporarily disabled. Removing the widget or closing the workflow
|
|
139
|
+
during an upload cancels it (rolled back as described above) instead
|
|
140
|
+
of freezing the canvas until the upload ends.
|
|
132
141
|
|
|
133
142
|
Type Mapping
|
|
134
143
|
------------
|
|
@@ -175,7 +184,6 @@ Before touching the database the widget enforces:
|
|
|
175
184
|
starts with a letter or underscore, only letters / digits /
|
|
176
185
|
underscores, max 63 characters). MySQL accepts a superset.
|
|
177
186
|
- **Connection fields present** — host and database.
|
|
178
|
-
- **Email well-formed** — only when the optional field is filled.
|
|
179
187
|
|
|
180
188
|
Security
|
|
181
189
|
--------
|
|
@@ -203,8 +211,7 @@ Usage Example
|
|
|
203
211
|
4. Click **Connect**. The status label should turn green with the
|
|
204
212
|
connection details.
|
|
205
213
|
5. Enter a valid table name, e.g. ``my_time_series_data``.
|
|
206
|
-
6.
|
|
207
|
-
7. Click **Save**. Watch the progress bar advance through the chunks
|
|
214
|
+
6. Click **Save**. Watch the progress bar advance through the chunks
|
|
208
215
|
and the status label switch to *Upload completed in Xs* when done.
|
|
209
216
|
|
|
210
217
|
Requirements
|
|
@@ -74,9 +74,21 @@ underscore.
|
|
|
74
74
|
mean(temperature, -2, 2)
|
|
75
75
|
abs(velocity) + sqrt(altitude)
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
Spaces around the arguments of the time-window functions are optional:
|
|
78
|
+
``shift(age,-20)`` and ``shift(age, -20)`` are equivalent. An expression
|
|
79
|
+
that references no column (e.g. ``42``) produces that value on every
|
|
80
|
+
row.
|
|
81
|
+
|
|
82
|
+
``__builtins__`` is replaced with an empty dict and only the names
|
|
83
|
+
listed below are exposed, so a direct call like ``__import__`` or
|
|
84
|
+
``open`` fails with ``NameError``.
|
|
85
|
+
|
|
86
|
+
.. warning::
|
|
87
|
+
|
|
88
|
+
This restricted ``eval`` is **not** a security sandbox. Python
|
|
89
|
+
introspection can still escape it and run arbitrary code, and
|
|
90
|
+
expressions stored in a workflow run as soon as the workflow is
|
|
91
|
+
opened. Only open workflows from sources you trust.
|
|
80
92
|
|
|
81
93
|
Available names
|
|
82
94
|
~~~~~~~~~~~~~~~
|
|
@@ -87,7 +99,7 @@ Available names
|
|
|
87
99
|
|
|
88
100
|
* - Group
|
|
89
101
|
- Names
|
|
90
|
-
* -
|
|
102
|
+
* - Builtins
|
|
91
103
|
- ``abs``, ``all``, ``any``, ``bin``, ``bool``, ``bytearray``,
|
|
92
104
|
``bytes``, ``chr``, ``complex``, ``dict``, ``divmod``,
|
|
93
105
|
``enumerate``, ``filter``, ``float``, ``format``, ``frozenset``,
|
|
@@ -52,10 +52,14 @@ The widget processes the input table row by row:
|
|
|
52
52
|
- A row with a valid expression is treated as a **derived variable**
|
|
53
53
|
(``var_type = Derived``).
|
|
54
54
|
|
|
55
|
-
For every derived variable, the widget
|
|
56
|
-
|
|
57
|
-
directed edge **source → dependency** (i.e. an edge
|
|
58
|
-
"X1's expression references X2").
|
|
55
|
+
For every derived variable, the widget parses its expression and
|
|
56
|
+
collects the known variable names it uses as values. Every reference
|
|
57
|
+
produces one directed edge **source → dependency** (i.e. an edge
|
|
58
|
+
``X1 → X2`` means "X1's expression references X2"). Names inside string
|
|
59
|
+
literals, names bound inside a comprehension or lambda, and the names
|
|
60
|
+
of called functions (``sqrt``, ``shift``…) are not references. If an
|
|
61
|
+
expression cannot be parsed, its variable gets no edges and the widget
|
|
62
|
+
shows a warning naming it.
|
|
59
63
|
|
|
60
64
|
Edge Weights
|
|
61
65
|
------------
|
|
@@ -71,7 +75,9 @@ For an edge ``Xᵢ → Xⱼ``:
|
|
|
71
75
|
- If ``Xⱼ`` appears inside one or more **temporal calls** in ``Xᵢ``'s
|
|
72
76
|
expression (``shift``, ``sum``, ``mean``, ``count``, ``min``, ``max``,
|
|
73
77
|
``sd``), the weight is the **maximum absolute integer argument**
|
|
74
|
-
across all such calls.
|
|
78
|
+
across all such calls. A temporal call counts only in the form the
|
|
79
|
+
Time Features Constructor evaluates: ``shift(var, n)`` or
|
|
80
|
+
``f(var, n, m)`` with integer literals.
|
|
75
81
|
- If ``Xⱼ`` only appears outside temporal calls (e.g. ``Xⱼ + 1``), the
|
|
76
82
|
weight defaults to ``1``.
|
|
77
83
|
|
|
@@ -119,7 +125,8 @@ downstream styling:
|
|
|
119
125
|
- Values
|
|
120
126
|
* - ``var_name``
|
|
121
127
|
- String
|
|
122
|
-
- Sanitised variable name (
|
|
128
|
+
- Sanitised variable name (every non-alphanumeric character
|
|
129
|
+
becomes ``_``; a leading digit gets a ``_`` prefix).
|
|
123
130
|
* - ``var_type``
|
|
124
131
|
- Discrete
|
|
125
132
|
- ``Derived`` (has an expression) or ``Original`` (source feature).
|
|
@@ -172,8 +179,10 @@ Implementation notes
|
|
|
172
179
|
|
|
173
180
|
- Variable name lookup is **O(1)** via a precomputed ``name → index``
|
|
174
181
|
map, so the full graph build is linear in the number of references.
|
|
175
|
-
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
182
|
+
- References and temporal calls are read from the expression's syntax
|
|
183
|
+
tree (``ast``), reusing the constructor's ``freevars``, so ``X1``
|
|
184
|
+
never matches inside ``X10`` or inside a string.
|
|
185
|
+
- Sanitisation reuses the **Time Features Constructor**'s
|
|
186
|
+
``sanitized_name`` (plus NFKC normalisation, as Python applies to
|
|
187
|
+
identifiers) so the names line up with how they are written inside
|
|
188
|
+
expressions (``temp (C)`` → ``temp__C_``, ``1abc`` → ``_1abc``).
|