paroxython 0.6.4__tar.gz → 0.7.1__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.
- {paroxython-0.6.4 → paroxython-0.7.1}/PKG-INFO +7 -10
- {paroxython-0.6.4 → paroxython-0.7.1}/README.md +4 -4
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/cli.py +2 -2
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/cli_collect.py +1 -1
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/cli_tag.py +1 -1
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/flatten_ast.py +22 -36
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/make_db.py +2 -3
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/resources/spec.md +10 -7
- {paroxython-0.6.4 → paroxython-0.7.1}/pyproject.toml +4 -7
- paroxython-0.7.1/setup.py +36 -0
- paroxython-0.6.4/setup.py +0 -37
- {paroxython-0.6.4 → paroxython-0.7.1}/LICENSE +0 -0
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/__init__.py +0 -0
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/assess_costs.py +0 -0
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/cli_recommend.py +0 -0
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/compare_spans.py +0 -0
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/derived_labels_db.py +0 -0
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/filter_programs.py +0 -0
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/goodies.py +0 -0
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/label_programs.py +0 -0
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/list_programs.py +0 -0
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/map_taxonomy.py +0 -0
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/normalize_predicate.py +0 -0
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/parse_program.py +0 -0
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/preprocess_source.py +0 -0
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/recommend_programs.py +0 -0
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/resources/taxonomy.tsv +0 -0
- {paroxython-0.6.4 → paroxython-0.7.1}/paroxython/user_types.py +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: paroxython
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.1
|
|
4
4
|
Summary: Search Python code for algorithmic features
|
|
5
5
|
Home-page: https://github.com/laowantong/paroxython/
|
|
6
6
|
License: MIT
|
|
7
7
|
Keywords: education,static-analysis,algorithmic,metaprogramming,python,taxonomic-classification,knowledge-management
|
|
8
8
|
Author: Aristide Grange
|
|
9
|
-
Requires-Python: >=3.
|
|
9
|
+
Requires-Python: >=3.8,<4.0
|
|
10
10
|
Classifier: Development Status :: 5 - Production/Stable
|
|
11
11
|
Classifier: Environment :: Console
|
|
12
12
|
Classifier: Framework :: IPython
|
|
@@ -15,12 +15,10 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
15
15
|
Classifier: Natural Language :: English
|
|
16
16
|
Classifier: Operating System :: OS Independent
|
|
17
17
|
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.8
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.9
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.
|
|
23
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
24
22
|
Classifier: Programming Language :: Python :: 3.8
|
|
25
23
|
Classifier: Programming Language :: Python :: 3.9
|
|
26
24
|
Classifier: Programming Language :: SQL
|
|
@@ -29,13 +27,12 @@ Classifier: Topic :: Education
|
|
|
29
27
|
Classifier: Typing :: Typed
|
|
30
28
|
Requires-Dist: docopt (>=0.6.2,<0.7.0)
|
|
31
29
|
Requires-Dist: regex (>=2022.8.17,<2023.0.0)
|
|
32
|
-
Requires-Dist: typed-ast (>=1.5.4,<2.0.0)
|
|
33
30
|
Requires-Dist: typing-extensions (>=4.3.0,<5.0.0)
|
|
34
31
|
Project-URL: Repository, https://github.com/laowantong/paroxython/
|
|
35
32
|
Project-URL: issues, https://github.com/laowantong/paroxython/issues
|
|
36
33
|
Description-Content-Type: text/markdown
|
|
37
34
|
|
|
38
|
-
[](https://github.com/laowantong/paroxython/actions/workflows/build.yml)
|
|
39
36
|
[](https://codecov.io/gh/laowantong/paroxython)
|
|
40
37
|
[](http://mypy-lang.org/)
|
|
41
38
|
[](https://www.codacy.com/manual/laowantong/paroxython)
|
|
@@ -45,7 +42,7 @@ Description-Content-Type: text/markdown
|
|
|
45
42
|

|
|
46
43
|
[](https://github.com/laowantong/paroxython/blob/master/paroxython)
|
|
47
44
|
[](https://github.com/laowantong/paroxython/blob/master/tests)
|
|
48
|
-
[](https://github.com/laowantong/paroxython/blob/master/helpers)
|
|
49
46
|
[](https://github.com/laowantong/paroxython/blob/master/paroxython/resources/spec.md)
|
|
50
47
|
[](https://github.com/laowantong/paroxython/blob/master/paroxython/resources/taxonomy.tsv)
|
|
51
48
|

|
|
@@ -178,7 +175,7 @@ Et voilà, [your recommendation report](https://github.com/laowantong/paroxython
|
|
|
178
175
|
Much to no one's surprise:
|
|
179
176
|
|
|
180
177
|
```
|
|
181
|
-
pip install paroxython
|
|
178
|
+
python -m pip install paroxython
|
|
182
179
|
```
|
|
183
180
|
|
|
184
181
|
The following command should print a help message and exit:
|
|
@@ -195,7 +192,7 @@ If you use Jupyter notebook/lab, you've also just installed a so-called magic co
|
|
|
195
192
|
%load_ext paroxython
|
|
196
193
|
```
|
|
197
194
|
|
|
198
|
-
This should print `"paroxython 0.
|
|
195
|
+
This should print `"paroxython 0.7.0 loaded."`. Run it on a cell of Python code:
|
|
199
196
|
|
|
200
197
|
```python
|
|
201
198
|
%%paroxython # Lines
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[](https://github.com/laowantong/paroxython/actions/workflows/build.yml)
|
|
2
2
|
[](https://codecov.io/gh/laowantong/paroxython)
|
|
3
3
|
[](http://mypy-lang.org/)
|
|
4
4
|
[](https://www.codacy.com/manual/laowantong/paroxython)
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|

|
|
9
9
|
[](https://github.com/laowantong/paroxython/blob/master/paroxython)
|
|
10
10
|
[](https://github.com/laowantong/paroxython/blob/master/tests)
|
|
11
|
-
[](https://github.com/laowantong/paroxython/blob/master/helpers)
|
|
12
12
|
[](https://github.com/laowantong/paroxython/blob/master/paroxython/resources/spec.md)
|
|
13
13
|
[](https://github.com/laowantong/paroxython/blob/master/paroxython/resources/taxonomy.tsv)
|
|
14
14
|

|
|
@@ -141,7 +141,7 @@ Et voilà, [your recommendation report](https://github.com/laowantong/paroxython
|
|
|
141
141
|
Much to no one's surprise:
|
|
142
142
|
|
|
143
143
|
```
|
|
144
|
-
pip install paroxython
|
|
144
|
+
python -m pip install paroxython
|
|
145
145
|
```
|
|
146
146
|
|
|
147
147
|
The following command should print a help message and exit:
|
|
@@ -158,7 +158,7 @@ If you use Jupyter notebook/lab, you've also just installed a so-called magic co
|
|
|
158
158
|
%load_ext paroxython
|
|
159
159
|
```
|
|
160
160
|
|
|
161
|
-
This should print `"paroxython 0.
|
|
161
|
+
This should print `"paroxython 0.7.0 loaded."`. Run it on a cell of Python code:
|
|
162
162
|
|
|
163
163
|
```python
|
|
164
164
|
%%paroxython # Lines
|
|
@@ -27,8 +27,8 @@ from docopt import docopt # type: ignore
|
|
|
27
27
|
from . import PAROXYTHON_VERSION
|
|
28
28
|
from .goodies import print_exit
|
|
29
29
|
|
|
30
|
-
if sys.
|
|
31
|
-
print_exit(f"Paroxython requires Python 3.
|
|
30
|
+
if sys.version_info < (3, 8): # pragma: no cover
|
|
31
|
+
print_exit(f"Paroxython requires Python 3.8 or later to run.\nThis version is {sys.version}.")
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
def main():
|
|
@@ -30,7 +30,7 @@ OPTIONS:
|
|
|
30
30
|
-t --taxonomy=PATH The path of a TSV file mapping labels onto taxa. If not
|
|
31
31
|
specified, use the "taxonomy.tsv" present in DIRECTORY's
|
|
32
32
|
parent. If absent, use the included default taxonomy:
|
|
33
|
-
https://github.com/laowantong/paroxython/blob/0.
|
|
33
|
+
https://github.com/laowantong/paroxython/blob/0.7.0/paroxython/resources/taxonomy.tsv
|
|
34
34
|
```
|
|
35
35
|
"""
|
|
36
36
|
|
|
@@ -12,7 +12,7 @@ OPTIONS:
|
|
|
12
12
|
-l --labels Output the labels instead of the taxa.
|
|
13
13
|
-t --taxonomy=PATH The path of a TSV file mapping labels onto taxa.
|
|
14
14
|
If not specified, use the included default taxonomy:
|
|
15
|
-
https://github.com/laowantong/paroxython/blob/0.
|
|
15
|
+
https://github.com/laowantong/paroxython/blob/0.7.0/paroxython/resources/taxonomy.tsv
|
|
16
16
|
```
|
|
17
17
|
"""
|
|
18
18
|
|
|
@@ -11,8 +11,8 @@ tree) of the program to analyze. For instance, when the string:
|
|
|
11
11
|
'print("hello, world")'
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
... is fed to the function `parse()` of the
|
|
15
|
-
|
|
14
|
+
... is fed to the function `parse()` of the module [`ast`](https://docs.python.org/3/library/ast.html),
|
|
15
|
+
the following object is returned:
|
|
16
16
|
|
|
17
17
|
```plain
|
|
18
18
|
Module()
|
|
@@ -90,28 +90,6 @@ of this text to make it more suitable for regular expression parsing.
|
|
|
90
90
|
|
|
91
91
|
## Implementation details
|
|
92
92
|
|
|
93
|
-
### Libraries used
|
|
94
|
-
|
|
95
|
-
When Paroxython is launched from Python 3.7 or lower, the parsing of source code into an AST is
|
|
96
|
-
performed by the third-party library [typed-ast](https://github.com/python/typed_ast). To quote the
|
|
97
|
-
README:
|
|
98
|
-
|
|
99
|
-
> `typed_ast` is a Python 3 package that provides a [...] parser similar to the standard `ast` library.
|
|
100
|
-
> Unlike `ast`, the parsers [...] are independent of the version of Python under which they are run.
|
|
101
|
-
> [...] `typed_ast` runs on CPython 3.5-3.8
|
|
102
|
-
|
|
103
|
-
So far so good. However:
|
|
104
|
-
|
|
105
|
-
> `typed_ast` will not be updated to support parsing Python 3.8 and newer.
|
|
106
|
-
|
|
107
|
-
This means that `typed_ast`, although convenient to parse Python 3.5 and newer, will start choping on
|
|
108
|
-
Python 3.8 specific syntax, as assignment expressions.
|
|
109
|
-
|
|
110
|
-
This is the reason why, when launched from Python 3.8 or higher, Paroxython switches to the parser of
|
|
111
|
-
the standard library [`ast`](https://docs.python.org/3/library/ast.html). However, the ASTs generated
|
|
112
|
-
by the two libraries are not 100% identical. Wrapping their parsers requires us to erase as much
|
|
113
|
-
differences as possible. Some of the functions presented below are written for this purpose.
|
|
114
|
-
|
|
115
93
|
### On the fly: modification of the AST
|
|
116
94
|
|
|
117
95
|
#### Field reordering
|
|
@@ -334,6 +312,7 @@ and classes would incorrectly be marked as starting from the line of their first
|
|
|
334
312
|
"""
|
|
335
313
|
|
|
336
314
|
|
|
315
|
+
import ast
|
|
337
316
|
import sys
|
|
338
317
|
from typing import Any, Callable, Match
|
|
339
318
|
|
|
@@ -343,24 +322,24 @@ import regex # type: ignore
|
|
|
343
322
|
def select_ast_post_processing():
|
|
344
323
|
"""Customize the post-treatment of the AST depending on the parser used to create it."""
|
|
345
324
|
|
|
346
|
-
if sys.version_info >= (3,
|
|
325
|
+
if sys.version_info >= (3, 10):
|
|
347
326
|
|
|
348
327
|
def post_process(flat_ast):
|
|
349
328
|
flat_ast = suppress_kinds(flat_ast)
|
|
329
|
+
flat_ast = suppress_alias_pos(flat_ast)
|
|
350
330
|
flat_ast = suppress_posonlyargs(flat_ast)
|
|
351
331
|
flat_ast = backport_all_constants(flat_ast)
|
|
352
332
|
flat_ast = simplify_negative_literals(flat_ast)
|
|
353
333
|
flat_ast = unquote(flat_ast)
|
|
354
334
|
return flat_ast
|
|
355
335
|
|
|
356
|
-
elif sys.version_info >= (3,
|
|
336
|
+
elif sys.version_info >= (3, 9):
|
|
357
337
|
|
|
358
338
|
def post_process(flat_ast):
|
|
359
339
|
flat_ast = suppress_kinds(flat_ast)
|
|
360
340
|
flat_ast = suppress_posonlyargs(flat_ast)
|
|
361
341
|
flat_ast = backport_all_constants(flat_ast)
|
|
362
342
|
flat_ast = simplify_negative_literals(flat_ast)
|
|
363
|
-
flat_ast = simplify_indexes(flat_ast)
|
|
364
343
|
flat_ast = unquote(flat_ast)
|
|
365
344
|
return flat_ast
|
|
366
345
|
|
|
@@ -368,22 +347,17 @@ def select_ast_post_processing():
|
|
|
368
347
|
|
|
369
348
|
def post_process(flat_ast):
|
|
370
349
|
flat_ast = suppress_kinds(flat_ast)
|
|
350
|
+
flat_ast = suppress_posonlyargs(flat_ast)
|
|
351
|
+
flat_ast = backport_all_constants(flat_ast)
|
|
371
352
|
flat_ast = simplify_negative_literals(flat_ast)
|
|
372
353
|
flat_ast = simplify_indexes(flat_ast)
|
|
373
354
|
flat_ast = unquote(flat_ast)
|
|
374
|
-
flat_ast = correct_all_decorated_callable_starts(flat_ast)
|
|
375
355
|
return flat_ast
|
|
376
356
|
|
|
377
357
|
return post_process
|
|
378
358
|
|
|
379
359
|
|
|
380
|
-
# fmt: off
|
|
381
|
-
if sys.version_info >= (3, 8):
|
|
382
|
-
import ast
|
|
383
|
-
else:
|
|
384
|
-
from typed_ast import ast3 as ast # type: ignore
|
|
385
360
|
post_process = select_ast_post_processing()
|
|
386
|
-
# fmt: on
|
|
387
361
|
|
|
388
362
|
|
|
389
363
|
def flatten_ast(tree) -> str:
|
|
@@ -411,7 +385,7 @@ def flatten_node(
|
|
|
411
385
|
prefix (str, optional): The prefix of the current line to dump. Defaults to `""`.
|
|
412
386
|
path (str, optional): The path of the current node. Defaults to `""`.
|
|
413
387
|
remove_context (Callable, optional): A function removing the node context encoded in the
|
|
414
|
-
result of `
|
|
388
|
+
result of `ast.dump()`.
|
|
415
389
|
[Not to be explicitly provided.](developer_manual/index.html#default-argument-trick)
|
|
416
390
|
Defaults to `regex.compile(r", ctx=.+?\(\)").sub`.
|
|
417
391
|
|
|
@@ -565,11 +539,23 @@ def suppress_kinds(
|
|
|
565
539
|
return sub("", flat_ast)
|
|
566
540
|
|
|
567
541
|
|
|
542
|
+
def suppress_alias_pos(
|
|
543
|
+
flat_ast: str,
|
|
544
|
+
sub: Callable = regex.compile(r"(?m)^(.+/_type=alias\n).+_pos=.+\n").sub,
|
|
545
|
+
) -> str:
|
|
546
|
+
"""Suppress the AST line following import aliases. Since Python 3.10, it contains a position,
|
|
547
|
+
useless in the following.
|
|
548
|
+
|
|
549
|
+
Argument `sub` [not to be explicitly provided.](developer_manual/index.html#default-argument-trick)
|
|
550
|
+
"""
|
|
551
|
+
return sub(r"\1", flat_ast)
|
|
552
|
+
|
|
553
|
+
|
|
568
554
|
def suppress_posonlyargs(
|
|
569
555
|
flat_ast: str,
|
|
570
556
|
sub: Callable = regex.compile(r"(?m)^.+/args/posonlyargs/_length=\d+\n").sub,
|
|
571
557
|
) -> str:
|
|
572
|
-
"""
|
|
558
|
+
"""Suppress positional-only parameters in function definitions.
|
|
573
559
|
|
|
574
560
|
Argument `sub` [not to be explicitly provided.](developer_manual/index.html#default-argument-trick)
|
|
575
561
|
"""
|
|
@@ -193,9 +193,8 @@ class TagDatabase:
|
|
|
193
193
|
)
|
|
194
194
|
)
|
|
195
195
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
connexion = sqlite3.connect(str(db_path)) # str() for Python 3.6 compatibility
|
|
196
|
+
db_path.unlink(missing_ok=True)
|
|
197
|
+
connexion = sqlite3.connect(db_path)
|
|
199
198
|
c = connexion.cursor()
|
|
200
199
|
|
|
201
200
|
fill = lambda columns: ",".join("?" * len(columns))
|
|
@@ -5696,6 +5696,7 @@ Match sequential loops, along with their iteration variable(s).
|
|
|
5696
5696
|
[⬇️ feature `accumulate_some_elements`](#feature-accumulate_some_elements)
|
|
5697
5697
|
[⬇️ feature `find_best_element`](#feature-find_best_element)
|
|
5698
5698
|
[⬇️ feature `find_best_element_index`](#feature-find_best_element_index)
|
|
5699
|
+
[⬇️ feature `find_first_good_element`](#feature-find_first_good_element)
|
|
5699
5700
|
[⬇️ feature `for_range`](#feature-for_range)
|
|
5700
5701
|
[⬇️ feature `nested_for`](#feature-nested_for)
|
|
5701
5702
|
[⬇️ feature `universal_quantification|existential_quantification`](#feature-universal_quantificationexistential_quantification)
|
|
@@ -5881,10 +5882,6 @@ GROUP BY path
|
|
|
5881
5882
|
|
|
5882
5883
|
Iterate over the elements of a (named) collection.
|
|
5883
5884
|
|
|
5884
|
-
##### Derivations
|
|
5885
|
-
|
|
5886
|
-
[⬇️ feature `find_first_good_element`](#feature-find_first_good_element)
|
|
5887
|
-
|
|
5888
5885
|
##### Specification
|
|
5889
5886
|
|
|
5890
5887
|
```re
|
|
@@ -7461,7 +7458,7 @@ Linear search. Return the first element of a sequence satisfying a predicate.
|
|
|
7461
7458
|
|
|
7462
7459
|
##### Derivations
|
|
7463
7460
|
|
|
7464
|
-
[⬆️ feature `
|
|
7461
|
+
[⬆️ feature `for`](#feature-for)
|
|
7465
7462
|
[⬆️ feature `if`](#feature-if)
|
|
7466
7463
|
[⬆️ feature `if_test_atom`](#feature-if_test_atom)
|
|
7467
7464
|
[⬆️ feature `return`](#feature-return)
|
|
@@ -7473,7 +7470,7 @@ SELECT "find_first_good_element",
|
|
|
7473
7470
|
lp.name_suffix,
|
|
7474
7471
|
lp.span,
|
|
7475
7472
|
lp.path
|
|
7476
|
-
FROM
|
|
7473
|
+
FROM t_for lp -- A for each loop...
|
|
7477
7474
|
JOIN t_if ON (t_if.path GLOB lp.path || "*-")-- enclosing an if statement...
|
|
7478
7475
|
JOIN t_if_test_atom x ON (x.span_start = t_if.span_start
|
|
7479
7476
|
AND x.name_suffix = lp.name_suffix)-- which tests the iteration variable...
|
|
@@ -7487,7 +7484,12 @@ JOIN t_return ret ON (ret.path GLOB t_if.path || "*-" -- and returns...
|
|
|
7487
7484
|
1 def search_element(iterable):
|
|
7488
7485
|
2 for element in iterable:
|
|
7489
7486
|
3 if is_good(element):
|
|
7490
|
-
4
|
|
7487
|
+
4 return element
|
|
7488
|
+
5 def largest_prime_below(n):
|
|
7489
|
+
6 for i in range(n - 1, 1, -1):
|
|
7490
|
+
7 if is_prime(i):
|
|
7491
|
+
8 return i
|
|
7492
|
+
9 return None
|
|
7491
7493
|
```
|
|
7492
7494
|
|
|
7493
7495
|
##### Matches
|
|
@@ -7495,6 +7497,7 @@ JOIN t_return ret ON (ret.path GLOB t_if.path || "*-" -- and returns...
|
|
|
7495
7497
|
| Label | Lines |
|
|
7496
7498
|
|:--|:--|
|
|
7497
7499
|
| `find_first_good_element:element` | 2-4 |
|
|
7500
|
+
| `find_first_good_element:i` | 6-8 |
|
|
7498
7501
|
|
|
7499
7502
|
--------------------------------------------------------------------------------
|
|
7500
7503
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "paroxython"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.7.1"
|
|
4
4
|
description = "Search Python code for algorithmic features"
|
|
5
5
|
authors = ["Aristide Grange"]
|
|
6
6
|
license = "MIT"
|
|
7
7
|
readme = "README.md"
|
|
8
|
-
homepage = ""
|
|
8
|
+
homepage = "https://github.com/laowantong/paroxython/"
|
|
9
9
|
repository = "https://github.com/laowantong/paroxython/"
|
|
10
10
|
keywords = ["education",
|
|
11
11
|
"static-analysis",
|
|
@@ -22,8 +22,6 @@ classifiers = [
|
|
|
22
22
|
"License :: OSI Approved :: MIT License",
|
|
23
23
|
"Natural Language :: English",
|
|
24
24
|
"Operating System :: OS Independent",
|
|
25
|
-
"Programming Language :: Python :: 3.6",
|
|
26
|
-
"Programming Language :: Python :: 3.7",
|
|
27
25
|
"Programming Language :: Python :: 3.8",
|
|
28
26
|
"Programming Language :: Python :: 3.9",
|
|
29
27
|
"Programming Language :: SQL",
|
|
@@ -34,15 +32,14 @@ classifiers = [
|
|
|
34
32
|
|
|
35
33
|
[tool.poetry.dependencies]
|
|
36
34
|
docopt = "^0.6.2"
|
|
37
|
-
python = "^3.
|
|
35
|
+
python = "^3.8"
|
|
38
36
|
regex = "^2022.8.17"
|
|
39
|
-
typed-ast = "^1.5.4"
|
|
40
37
|
typing-extensions = "^4.3.0"
|
|
41
38
|
|
|
42
39
|
[tool.poetry.dev-dependencies]
|
|
43
40
|
mypy = "^0.782"
|
|
44
41
|
pdoc3 = "^0.9.1"
|
|
45
|
-
pre-commit = "^2.
|
|
42
|
+
pre-commit = "^2.20.0"
|
|
46
43
|
pytest = "^7.1.3"
|
|
47
44
|
pytest-icdiff = "^2.4.7"
|
|
48
45
|
sqlparse = "^0.4.2"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from setuptools import setup
|
|
3
|
+
|
|
4
|
+
packages = \
|
|
5
|
+
['paroxython']
|
|
6
|
+
|
|
7
|
+
package_data = \
|
|
8
|
+
{'': ['*'], 'paroxython': ['resources/*']}
|
|
9
|
+
|
|
10
|
+
install_requires = \
|
|
11
|
+
['docopt>=0.6.2,<0.7.0',
|
|
12
|
+
'regex>=2022.8.17,<2023.0.0',
|
|
13
|
+
'typing-extensions>=4.3.0,<5.0.0']
|
|
14
|
+
|
|
15
|
+
entry_points = \
|
|
16
|
+
{'console_scripts': ['paroxython = paroxython.cli:main']}
|
|
17
|
+
|
|
18
|
+
setup_kwargs = {
|
|
19
|
+
'name': 'paroxython',
|
|
20
|
+
'version': '0.7.1',
|
|
21
|
+
'description': 'Search Python code for algorithmic features',
|
|
22
|
+
'long_description': '[](https://github.com/laowantong/paroxython/actions/workflows/build.yml)\n[](https://codecov.io/gh/laowantong/paroxython)\n[](http://mypy-lang.org/)\n[](https://www.codacy.com/manual/laowantong/paroxython)\n[](https://pyup.io/repos/github/laowantong/paroxython/)\n\n[]()\n\n[](https://github.com/laowantong/paroxython/blob/master/paroxython)\n[](https://github.com/laowantong/paroxython/blob/master/tests)\n[](https://github.com/laowantong/paroxython/blob/master/helpers)\n[](https://github.com/laowantong/paroxython/blob/master/paroxython/resources/spec.md)\n[](https://github.com/laowantong/paroxython/blob/master/paroxython/resources/taxonomy.tsv)\n\n[](https://pepy.tech/project/paroxython/week)\n[](https://github.com/psf/black)\n[](https://opensource.org/licenses/MIT)\n[](https://youtu.be/QcbR1J_4ICg?t=54)\n\n<p align="center">\n <a href="https://laowantong.github.io/paroxython/index.html">\n <img src="docs/resources/logo.png">\n </a>\n</p>\n\n## Introduction\n\nParoxython is a set of command line tools which **tag** and **filter** by algorithmic features your collection of Python programming exercises.\n\n### Audience\n\nYou are a teacher, in charge of an introductory programming course in an educational institution. Over the years, you have accumulated many—far too many—programs and code snippets that may be of interest to your students.\n\nOr, as a seasoned developer, you would like to share your knowledge by helping a loved one learn how to code. A cursory search for pedagogical material yields an overwhelming amount of websites and repositories stuffed with Python programs of various levels (e.g.,\n[1](https://github.com/TheAlgorithms/Python),\n[2](http://rosettacode.org/wiki/Category:Python),\n[3](https://www.programming-idioms.org/about#about-block-language-coverage),\n[4](https://github.com/codebasics/py),\n[5](https://github.com/keon/algorithms),\n[6](https://github.com/OmkarPathak/Python-Programs),\nand a lot more from [Awesome Python in Education](https://github.com/quobit/awesome-python-in-education)).\n\nIn any case, the Python source codes you have gathered are typically\n**numerous** (hundreds or even thousands),\n**reasonably sized** (anything below 100 lines of code),\nand **educational** in nature (e.g., snippets, examples, quizzes, exercise solutions, classic algorithms).\nThe programming concepts you plan to teach remain relatively **low level** (e.g. assignments, nested loops, accumulation patterns, tail recursive functions, etc.).\n\nIf all that sounds familiar, keep reading me.\n\n### Main goals\n\nParoxython aims to help you select, from your collection, the one program that best suits your needs. For instance, it will gladly answer the following questions:\n\n> - How can this concept be illustrated?\n> - What problems use the same algorithmic and data structures as this one?\n> - What homework assignment should I give my students so they can practice the content of the last lesson?\n\nMoreover, since Paroxython knows what your class knows, it can recommend the right program at the right time:\n\n> - What would make a good review exercise?\n> - Which exercises can I give on this exam?\n> - What is the current learning cost of this example?\n\nIn the long run, Paroxython may guide you and somehow make you rethink your course outline:\n\n> - What are the prerequisites for the concept of assignment?\n> - Do I have enough material to introduce subroutines before I even talk about conditionals and loops?\n> - Among the loops, which must come first: the most powerful (`while`), or the most useful (`for`)?\n> - How to logically structure this bunch of usual iterative patterns?\n> - What are the _basics_, exactly?\n\nAll issues on which the author changed his mind since he started to work on this project!\n\nIn an ideal world, Paroxython could even put an end to the deadliest religious wars, with rational, data-driven arguments:\n\n> - Father, is it a sin to exit early?\n> - Should a real byte use a mask?\n\n### How it works\n\n<p align="center">\n <a href="https://laowantong.github.io/paroxython/developer_manual/index.html">\n <img src="docs/resources/waterfall.png">\n </a>\n</p>\n\nParoxython starts from a given folder of **programs**. Its contents is parsed, and all features that meet the provided **specifications** are labelled and associated with their spans (e.g., `"assignment_lhs_identifier:a": 4, 6, 18` or `"loop_with_late_exit:while": 3-7, 20-29`).\n\nThese **labels** constitute only scattered knowledge. The next step is to map them onto a **taxonomy** designed with basic hierarchical constraints in mind (e.g., the fact that the introduction of the concept of early exit must come after that of loop, which itself requires that of control flow, is expressed by the _taxon_ `"flow/loop/exit/early"`).\n\n<p align="center">\n <a href="https://laowantong.github.io/paroxython/user_manual/index.html#taxonomy">\n <img src="docs/resources/tree.png" alt="A taxonomy.">\n </a>\n <br>\n <em>Extract of the taxonomy generated from <a href="https://github.com/TheAlgorithms/Python">The Algorithms - Python</a>.<br>Click to jump to its full dynamic version in the user manual.</em>\n</p>\n\nEverything is then persisted in a tag **database**, which can later be filtered through a **pipeline** of commands, for instance:\n\n- _include_ only the programs which feature a recursive function;\n- _exclude_ this or that program you want to set aside for the exam;\n- “_impart_” all programs studied so far, _i.e_, consider that all the notions they implement are acquired.\n\nThe result is a list of program **recommendations** ordered by increasing learning cost.\n\n### Example\n\nSuppose that the `programs` directory contains [these simple programs](https://wiki.python.org/moin/SimplePrograms).\n\nFirst, build [this tag database](https://github.com/laowantong/paroxython/blob/master/examples/simple/programs_db.json):\n\n```shell\n> paroxython collect programs\nLabelling 21 programs.\nMapping taxonomy on 21 programs.\nWriting programs_db.json.\n```\n\nThen, filter it through [this pipeline](https://github.com/laowantong/paroxython/blob/master/examples/simple/programs_pipe.py):\n\n```shell\n> paroxython recommend programs\nProcessing 5 commands on 21 programs.\n 19 programs remaining after operation 1 (impart).\n 18 programs remaining after operation 2 (exclude).\n 12 programs remaining after operation 3 (exclude).\n 10 programs remaining after operation 4 (include).\n 10 programs remaining after operation 5 (hide).\nDumped: programs_recommendations.md.\n```\n\nEt voilà, [your recommendation report](https://github.com/laowantong/paroxython/blob/master/examples/simple/programs_recommendations.md)!\n\n\n## Installation and test-drive\n\n### Command line\n\nMuch to no one\'s surprise:\n\n```\npython -m pip install paroxython\n```\n\nThe following command should print a help message and exit:\n\n```\nparoxython --help\n```\n\n### IPython magic command\n\nIf you use Jupyter notebook/lab, you\'ve also just installed a so-called magic command. Load it like this:\n\n```python\n%load_ext paroxython\n```\n\nThis should print `"paroxython 0.7.0 loaded."`. Run it on a cell of Python code:\n\n```python\n%%paroxython # Lines\ndef fibonacci(n): # 2\n result = [] # 3\n (a, b) = (0, 1) # 4\n while a < n: # 5\n result.append(a) # 6\n (a, b) = (b, a + b) # 7\n return result # 8\n```\n\n| Taxon | Lines |\n|:--|:--|\n| `call/subroutine/method/sequence/list/append` | 6 |\n| `condition/inequality` | 5 |\n| `def/subroutine/function/impure` | 2-8 |\n| `def/subroutine/parameter/arg` | 2 |\n| `flow/loop/exit/late` | 5-7 |\n| `flow/loop/while` | 5-7 |\n| `meta/count/program/sloc/8` | 2-8 |\n| `meta/count/subroutine/sloc/7` | 2-8 |\n| `meta/count/variety/3` | 2-8 |\n| `meta/program` | 2-8 |\n| `operator/arithmetic/addition` | 7 |\n| `style/procedural` | 2-8 |\n| `type/number/integer/literal` | 4 |\n| `type/number/integer/literal/zero` | 4 |\n| `type/sequence/list` | 6 |\n| `type/sequence/list/literal/empty` | 3 |\n| `type/sequence/tuple/literal` | 4, 4, 7, 7 |\n| `var/assignment/explicit/parallel` | 4 |\n| `var/assignment/explicit/parallel/slide` | 7 |\n| `var/assignment/explicit/single` | 3 |\n| `var/assignment/implicit/parameter` | 2 |\n| `var/scope/local` | 2-8, 2-8, 2-8, 2-8 |\n\nAs you can see, in this program, Paroxython identifies among others:\n\n- the use of the [procedural paradigm](https://en.wikipedia.org/wiki/Procedural_programming) (`style/procedural`);\n- an im[pure function](https://en.wikipedia.org/wiki/Pure_function) (`def/subroutine/function/impure`);\n- a `while` loop (`flow/loop/while`) with a late exit (`flow/loop/exit/late`);\n- a little bit of voodoo on lists (`type/sequence/list/literal/empty` and `call/subroutine/method/sequence/list/append`);\n- a simple [tuple assignment](https://en.wikibooks.org/wiki/Python_Programming/Tuples#Packing_and_Unpacking) (`var/assignment/explicit/parallel`). Note that we distinguish between explicit (with `=`) and implicit (parameters and iteration variables) assignments;\n- a “sliding” tuple assignment (`var/assignment/explicit/parallel/slide`). If the denomination is unique to us, the pattern itself occurs in a number of programs: implementations of [C-finite sequences](https://en.wikipedia.org/wiki/Constant-recursive_sequence) with C greater than 1, [Greatest Common Divisor](https://en.wikipedia.org/wiki/Greatest_common_divisor), [Quicksort](https://en.wikipedia.org/wiki/Quicksort), etc.\n- four local variables (`var/scope/local`);\n- an estimation of the variety of concepts involved (`meta/count/variety/***`), depending on the number of lines, features and distinct features.\n\nThe magic command `%%paroxython` (corresponding to the subcommand [`tag`](https://laowantong.github.io/paroxython/cli_tag.html)) only scratches the surface of the system. As shown before, to estimate the learning cost of the features and get actionable recommendations, you will need first to construct the tag database with [`collect`](https://laowantong.github.io/paroxython/cli_collect.html), and then call [`recommend`](https://laowantong.github.io/paroxython/cli_recommend.html) on a pipeline of yours.\n\n# Read them\n\nAlthough this is still a work-in-progress, Paroxython should already be fairly well [documented](https://laowantong.github.io/paroxython/index.html):\n\n- [User manual](https://laowantong.github.io/paroxython/user_manual/index.html):\n - [write a command pipeline to get recommendations](https://laowantong.github.io/paroxython/user_manual/index.html#pipeline-tutorial),\n - [prepare your program collections for better results](https://laowantong.github.io/paroxython/user_manual/index#preparing-your-program-collection),\n - [understand and modify the taxonomic classification](https://laowantong.github.io/paroxython/user_manual/index#taxonomy),\n - and more.\n- [Developer manual](https://laowantong.github.io/paroxython/developer_manual/index.html):\n - [get a rough idea of the program structure and operations](https://laowantong.github.io/paroxython/developer_manual/index.html#bird-view),\n - [use the provided helpers to contribute to the code](helper-programs),\n - and more.\n- [Module reference](https://laowantong.github.io/paroxython/#header-submodules).\n- [Feature specifications](https://github.com/laowantong/paroxython/blob/master/paroxython/resources/spec.md): a document mixing prose, tests, regular expressions and SQL queries to describe which algorithmic features are recognized and how.\n- [User types](https://github.com/laowantong/paroxython/blob/master/paroxython/user_types.py): all objects of interest are precisely typed and checked by [mypy](http://mypy-lang.org).\n\nFinally, a [battery of examples](https://github.com/laowantong/paroxython/tree/master/examples) and [comprehensive test coverage](https://github.com/laowantong/paroxython/tree/master/tests) should help answer any remaining question.\n',
|
|
23
|
+
'author': 'Aristide Grange',
|
|
24
|
+
'author_email': 'None',
|
|
25
|
+
'maintainer': 'None',
|
|
26
|
+
'maintainer_email': 'None',
|
|
27
|
+
'url': 'https://github.com/laowantong/paroxython/',
|
|
28
|
+
'packages': packages,
|
|
29
|
+
'package_data': package_data,
|
|
30
|
+
'install_requires': install_requires,
|
|
31
|
+
'entry_points': entry_points,
|
|
32
|
+
'python_requires': '>=3.8,<4.0',
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
setup(**setup_kwargs)
|
paroxython-0.6.4/setup.py
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
from setuptools import setup
|
|
3
|
-
|
|
4
|
-
packages = \
|
|
5
|
-
['paroxython']
|
|
6
|
-
|
|
7
|
-
package_data = \
|
|
8
|
-
{'': ['*'], 'paroxython': ['resources/*']}
|
|
9
|
-
|
|
10
|
-
install_requires = \
|
|
11
|
-
['docopt>=0.6.2,<0.7.0',
|
|
12
|
-
'regex>=2022.8.17,<2023.0.0',
|
|
13
|
-
'typed-ast>=1.5.4,<2.0.0',
|
|
14
|
-
'typing-extensions>=4.3.0,<5.0.0']
|
|
15
|
-
|
|
16
|
-
entry_points = \
|
|
17
|
-
{'console_scripts': ['paroxython = paroxython.cli:main']}
|
|
18
|
-
|
|
19
|
-
setup_kwargs = {
|
|
20
|
-
'name': 'paroxython',
|
|
21
|
-
'version': '0.6.4',
|
|
22
|
-
'description': 'Search Python code for algorithmic features',
|
|
23
|
-
'long_description': '[](https://travis-ci.com/laowantong/paroxython)\n[](https://codecov.io/gh/laowantong/paroxython)\n[](http://mypy-lang.org/)\n[](https://www.codacy.com/manual/laowantong/paroxython)\n[](https://pyup.io/repos/github/laowantong/paroxython/)\n\n[]()\n\n[](https://github.com/laowantong/paroxython/blob/master/paroxython)\n[](https://github.com/laowantong/paroxython/blob/master/tests)\n[](https://github.com/laowantong/paroxython/blob/master/helpers)\n[](https://github.com/laowantong/paroxython/blob/master/paroxython/resources/spec.md)\n[](https://github.com/laowantong/paroxython/blob/master/paroxython/resources/taxonomy.tsv)\n\n[](https://pepy.tech/project/paroxython/week)\n[](https://github.com/psf/black)\n[](https://opensource.org/licenses/MIT)\n[](https://youtu.be/QcbR1J_4ICg?t=54)\n\n<p align="center">\n <a href="https://laowantong.github.io/paroxython/index.html">\n <img src="docs/resources/logo.png">\n </a>\n</p>\n\n## Introduction\n\nParoxython is a set of command line tools which **tag** and **filter** by algorithmic features your collection of Python programming exercises.\n\n### Audience\n\nYou are a teacher, in charge of an introductory programming course in an educational institution. Over the years, you have accumulated many—far too many—programs and code snippets that may be of interest to your students.\n\nOr, as a seasoned developer, you would like to share your knowledge by helping a loved one learn how to code. A cursory search for pedagogical material yields an overwhelming amount of websites and repositories stuffed with Python programs of various levels (e.g.,\n[1](https://github.com/TheAlgorithms/Python),\n[2](http://rosettacode.org/wiki/Category:Python),\n[3](https://www.programming-idioms.org/about#about-block-language-coverage),\n[4](https://github.com/codebasics/py),\n[5](https://github.com/keon/algorithms),\n[6](https://github.com/OmkarPathak/Python-Programs),\nand a lot more from [Awesome Python in Education](https://github.com/quobit/awesome-python-in-education)).\n\nIn any case, the Python source codes you have gathered are typically\n**numerous** (hundreds or even thousands),\n**reasonably sized** (anything below 100 lines of code),\nand **educational** in nature (e.g., snippets, examples, quizzes, exercise solutions, classic algorithms).\nThe programming concepts you plan to teach remain relatively **low level** (e.g. assignments, nested loops, accumulation patterns, tail recursive functions, etc.).\n\nIf all that sounds familiar, keep reading me.\n\n### Main goals\n\nParoxython aims to help you select, from your collection, the one program that best suits your needs. For instance, it will gladly answer the following questions:\n\n> - How can this concept be illustrated?\n> - What problems use the same algorithmic and data structures as this one?\n> - What homework assignment should I give my students so they can practice the content of the last lesson?\n\nMoreover, since Paroxython knows what your class knows, it can recommend the right program at the right time:\n\n> - What would make a good review exercise?\n> - Which exercises can I give on this exam?\n> - What is the current learning cost of this example?\n\nIn the long run, Paroxython may guide you and somehow make you rethink your course outline:\n\n> - What are the prerequisites for the concept of assignment?\n> - Do I have enough material to introduce subroutines before I even talk about conditionals and loops?\n> - Among the loops, which must come first: the most powerful (`while`), or the most useful (`for`)?\n> - How to logically structure this bunch of usual iterative patterns?\n> - What are the _basics_, exactly?\n\nAll issues on which the author changed his mind since he started to work on this project!\n\nIn an ideal world, Paroxython could even put an end to the deadliest religious wars, with rational, data-driven arguments:\n\n> - Father, is it a sin to exit early?\n> - Should a real byte use a mask?\n\n### How it works\n\n<p align="center">\n <a href="https://laowantong.github.io/paroxython/developer_manual/index.html">\n <img src="docs/resources/waterfall.png">\n </a>\n</p>\n\nParoxython starts from a given folder of **programs**. Its contents is parsed, and all features that meet the provided **specifications** are labelled and associated with their spans (e.g., `"assignment_lhs_identifier:a": 4, 6, 18` or `"loop_with_late_exit:while": 3-7, 20-29`).\n\nThese **labels** constitute only scattered knowledge. The next step is to map them onto a **taxonomy** designed with basic hierarchical constraints in mind (e.g., the fact that the introduction of the concept of early exit must come after that of loop, which itself requires that of control flow, is expressed by the _taxon_ `"flow/loop/exit/early"`).\n\n<p align="center">\n <a href="https://laowantong.github.io/paroxython/user_manual/index.html#taxonomy">\n <img src="docs/resources/tree.png" alt="A taxonomy.">\n </a>\n <br>\n <em>Extract of the taxonomy generated from <a href="https://github.com/TheAlgorithms/Python">The Algorithms - Python</a>.<br>Click to jump to its full dynamic version in the user manual.</em>\n</p>\n\nEverything is then persisted in a tag **database**, which can later be filtered through a **pipeline** of commands, for instance:\n\n- _include_ only the programs which feature a recursive function;\n- _exclude_ this or that program you want to set aside for the exam;\n- “_impart_” all programs studied so far, _i.e_, consider that all the notions they implement are acquired.\n\nThe result is a list of program **recommendations** ordered by increasing learning cost.\n\n### Example\n\nSuppose that the `programs` directory contains [these simple programs](https://wiki.python.org/moin/SimplePrograms).\n\nFirst, build [this tag database](https://github.com/laowantong/paroxython/blob/master/examples/simple/programs_db.json):\n\n```shell\n> paroxython collect programs\nLabelling 21 programs.\nMapping taxonomy on 21 programs.\nWriting programs_db.json.\n```\n\nThen, filter it through [this pipeline](https://github.com/laowantong/paroxython/blob/master/examples/simple/programs_pipe.py):\n\n```shell\n> paroxython recommend programs\nProcessing 5 commands on 21 programs.\n 19 programs remaining after operation 1 (impart).\n 18 programs remaining after operation 2 (exclude).\n 12 programs remaining after operation 3 (exclude).\n 10 programs remaining after operation 4 (include).\n 10 programs remaining after operation 5 (hide).\nDumped: programs_recommendations.md.\n```\n\nEt voilà, [your recommendation report](https://github.com/laowantong/paroxython/blob/master/examples/simple/programs_recommendations.md)!\n\n\n## Installation and test-drive\n\n### Command line\n\nMuch to no one\'s surprise:\n\n```\npip install paroxython\n```\n\nThe following command should print a help message and exit:\n\n```\nparoxython --help\n```\n\n### IPython magic command\n\nIf you use Jupyter notebook/lab, you\'ve also just installed a so-called magic command. Load it like this:\n\n```python\n%load_ext paroxython\n```\n\nThis should print `"paroxython 0.6.3 loaded."`. Run it on a cell of Python code:\n\n```python\n%%paroxython # Lines\ndef fibonacci(n): # 2\n result = [] # 3\n (a, b) = (0, 1) # 4\n while a < n: # 5\n result.append(a) # 6\n (a, b) = (b, a + b) # 7\n return result # 8\n```\n\n| Taxon | Lines |\n|:--|:--|\n| `call/subroutine/method/sequence/list/append` | 6 |\n| `condition/inequality` | 5 |\n| `def/subroutine/function/impure` | 2-8 |\n| `def/subroutine/parameter/arg` | 2 |\n| `flow/loop/exit/late` | 5-7 |\n| `flow/loop/while` | 5-7 |\n| `meta/count/program/sloc/8` | 2-8 |\n| `meta/count/subroutine/sloc/7` | 2-8 |\n| `meta/count/variety/3` | 2-8 |\n| `meta/program` | 2-8 |\n| `operator/arithmetic/addition` | 7 |\n| `style/procedural` | 2-8 |\n| `type/number/integer/literal` | 4 |\n| `type/number/integer/literal/zero` | 4 |\n| `type/sequence/list` | 6 |\n| `type/sequence/list/literal/empty` | 3 |\n| `type/sequence/tuple/literal` | 4, 4, 7, 7 |\n| `var/assignment/explicit/parallel` | 4 |\n| `var/assignment/explicit/parallel/slide` | 7 |\n| `var/assignment/explicit/single` | 3 |\n| `var/assignment/implicit/parameter` | 2 |\n| `var/scope/local` | 2-8, 2-8, 2-8, 2-8 |\n\nAs you can see, in this program, Paroxython identifies among others:\n\n- the use of the [procedural paradigm](https://en.wikipedia.org/wiki/Procedural_programming) (`style/procedural`);\n- an im[pure function](https://en.wikipedia.org/wiki/Pure_function) (`def/subroutine/function/impure`);\n- a `while` loop (`flow/loop/while`) with a late exit (`flow/loop/exit/late`);\n- a little bit of voodoo on lists (`type/sequence/list/literal/empty` and `call/subroutine/method/sequence/list/append`);\n- a simple [tuple assignment](https://en.wikibooks.org/wiki/Python_Programming/Tuples#Packing_and_Unpacking) (`var/assignment/explicit/parallel`). Note that we distinguish between explicit (with `=`) and implicit (parameters and iteration variables) assignments;\n- a “sliding” tuple assignment (`var/assignment/explicit/parallel/slide`). If the denomination is unique to us, the pattern itself occurs in a number of programs: implementations of [C-finite sequences](https://en.wikipedia.org/wiki/Constant-recursive_sequence) with C greater than 1, [Greatest Common Divisor](https://en.wikipedia.org/wiki/Greatest_common_divisor), [Quicksort](https://en.wikipedia.org/wiki/Quicksort), etc.\n- four local variables (`var/scope/local`);\n- an estimation of the variety of concepts involved (`meta/count/variety/***`), depending on the number of lines, features and distinct features.\n\nThe magic command `%%paroxython` (corresponding to the subcommand [`tag`](https://laowantong.github.io/paroxython/cli_tag.html)) only scratches the surface of the system. As shown before, to estimate the learning cost of the features and get actionable recommendations, you will need first to construct the tag database with [`collect`](https://laowantong.github.io/paroxython/cli_collect.html), and then call [`recommend`](https://laowantong.github.io/paroxython/cli_recommend.html) on a pipeline of yours.\n\n# Read them\n\nAlthough this is still a work-in-progress, Paroxython should already be fairly well [documented](https://laowantong.github.io/paroxython/index.html):\n\n- [User manual](https://laowantong.github.io/paroxython/user_manual/index.html):\n - [write a command pipeline to get recommendations](https://laowantong.github.io/paroxython/user_manual/index.html#pipeline-tutorial),\n - [prepare your program collections for better results](https://laowantong.github.io/paroxython/user_manual/index#preparing-your-program-collection),\n - [understand and modify the taxonomic classification](https://laowantong.github.io/paroxython/user_manual/index#taxonomy),\n - and more.\n- [Developer manual](https://laowantong.github.io/paroxython/developer_manual/index.html):\n - [get a rough idea of the program structure and operations](https://laowantong.github.io/paroxython/developer_manual/index.html#bird-view),\n - [use the provided helpers to contribute to the code](helper-programs),\n - and more.\n- [Module reference](https://laowantong.github.io/paroxython/#header-submodules).\n- [Feature specifications](https://github.com/laowantong/paroxython/blob/master/paroxython/resources/spec.md): a document mixing prose, tests, regular expressions and SQL queries to describe which algorithmic features are recognized and how.\n- [User types](https://github.com/laowantong/paroxython/blob/master/paroxython/user_types.py): all objects of interest are precisely typed and checked by [mypy](http://mypy-lang.org).\n\nFinally, a [battery of examples](https://github.com/laowantong/paroxython/tree/master/examples) and [comprehensive test coverage](https://github.com/laowantong/paroxython/tree/master/tests) should help answer any remaining question.\n',
|
|
24
|
-
'author': 'Aristide Grange',
|
|
25
|
-
'author_email': 'None',
|
|
26
|
-
'maintainer': 'None',
|
|
27
|
-
'maintainer_email': 'None',
|
|
28
|
-
'url': 'https://github.com/laowantong/paroxython/',
|
|
29
|
-
'packages': packages,
|
|
30
|
-
'package_data': package_data,
|
|
31
|
-
'install_requires': install_requires,
|
|
32
|
-
'entry_points': entry_points,
|
|
33
|
-
'python_requires': '>=3.6.1,<4.0.0',
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
setup(**setup_kwargs)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|