easycoder 250116.1__tar.gz → 250116.4__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.
Potentially problematic release.
This version of easycoder might be problematic. Click here for more details.
- {easycoder-250116.1 → easycoder-250116.4}/PKG-INFO +28 -14
- {easycoder-250116.1 → easycoder-250116.4}/README.md +27 -13
- {easycoder-250116.1 → easycoder-250116.4}/easycoder/__init__.py +1 -1
- {easycoder-250116.1 → easycoder-250116.4}/easycoder/ec_compiler.py +2 -2
- {easycoder-250116.1 → easycoder-250116.4}/easycoder/ec_graphics.py +88 -141
- {easycoder-250116.1 → easycoder-250116.4}/easycoder/ec_gutils.py +6 -6
- easycoder-250116.4/scripts/testg.ecg +48 -0
- easycoder-250116.1/scripts/testg.ecg +0 -44
- {easycoder-250116.1 → easycoder-250116.4}/LICENSE +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/README.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/README.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/boolean.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/empty.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/ends.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/even.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/exists.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/greater.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/hasProperty.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/includes.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/is.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/less.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/list.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/none.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/not.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/numeric.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/object.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/odd.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/starts.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/conditions/string.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/add.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/append.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/assert.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/begin.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/clear.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/close.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/create.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/debug.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/decrement.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/delete.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/divide.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/exit.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/file.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/fork.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/get.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/go.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/gosub.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/if.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/import.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/increment.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/index.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/init.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/input.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/load.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/lock.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/module.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/multiply.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/negate.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/open.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/pop.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/post.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/print.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/push.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/put.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/read.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/release.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/replace.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/return.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/run.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/save.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/script.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/set.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/split.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/stack.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/stop.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/system.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/take.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/toggle.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/truncate.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/unlock.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/variable.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/wait.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/while.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/keywords/write.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/arg.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/args.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/cos.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/datime.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/decode.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/element.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/elements.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/empty.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/encode.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/error.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/files.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/float.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/from.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/hash.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/index.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/integer.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/json.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/keys.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/left.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/length.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/lowercase.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/memory.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/modification.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/modulo.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/newline.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/now.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/position.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/property.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/random.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/right.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/sin.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/stringify.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/tab.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/tan.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/timestamp.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/today.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/trim.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/type.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/uppercase.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/value.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/core/values/weekday.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/graphics/README.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/graphics/keywords/attach.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/graphics/keywords/close.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/graphics/keywords/create.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/graphics/keywords/ellipse.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/graphics/keywords/image.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/graphics/keywords/move.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/graphics/keywords/on.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/graphics/keywords/rectangle.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/graphics/keywords/render.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/graphics/keywords/run.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/graphics/keywords/set.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/graphics/keywords/text.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/graphics/values/attribute.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/doc/graphics/values/window.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/easycoder/README.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/easycoder/ec_classes.py +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/easycoder/ec_condition.py +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/easycoder/ec_core.py +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/easycoder/ec_handler.py +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/easycoder/ec_program.py +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/easycoder/ec_timestamp.py +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/easycoder/ec_value.py +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/images/Semoigo Dawn.jpg +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/json/graphics-demo.json +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/plugins/ec_keyboard.py +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/plugins/ec_p100.py +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/plugins/example.py +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/plugins/keyboards/4-function.json +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/plugins/keyboards/4-function.png +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/plugins/keyboards/qwerty-0.json +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/plugins/keyboards/qwerty-0.png +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/plugins/keyboards/qwerty-1.json +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/plugins/keyboards/qwerty-1.png +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/plugins/keyboards/qwerty-2.json +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/plugins/keyboards/qwerty-2.png +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/plugins/keyboards/qwerty-3.json +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/plugins/keyboards/qwerty-3.png +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/pyproject.toml +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/scripts/README.md +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/scripts/benchmark.ecs +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/scripts/ec_keyboard.py +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/scripts/fizzbuzz.ecs +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/scripts/hello.ecs +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/scripts/points.ecs +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/scripts/test.ecs +0 -0
- {easycoder-250116.1 → easycoder-250116.4}/scripts/tests.ecs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: easycoder
|
|
3
|
-
Version: 250116.
|
|
3
|
+
Version: 250116.4
|
|
4
4
|
Summary: Rapid scripting in English
|
|
5
5
|
Keywords: compiler,scripting,prototyping,programming,coding,python,low code,hypertalk,computer language,learn to code
|
|
6
6
|
Author-email: Graham Trott <gtanyware@gmail.com>
|
|
@@ -22,15 +22,30 @@ Website: [https://easycoder.github.io](https://easycoder.github.io)
|
|
|
22
22
|
## Quick Start
|
|
23
23
|
Install **_EasyCoder_** in your Python environment:
|
|
24
24
|
```
|
|
25
|
-
pip install easycoder
|
|
25
|
+
pip install requests pytz easycoder
|
|
26
26
|
```
|
|
27
|
-
You may also need to install `pytz`, as some commands need it.
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
Test the install by typing the command `easycoder`.
|
|
29
|
+
<hr>
|
|
30
|
+
On Linux, this will probably fail as the installer places the executable file in the `$HOME/.local/bin` directory. So give the command
|
|
31
|
+
```
|
|
32
|
+
export PATH=$HOME/.local/bin:$PATH
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
To make this change permanent, edit your `.profile` file, adding the following:
|
|
36
|
+
```
|
|
37
|
+
# set PATH so it includes user's private .local/bin if it exists
|
|
38
|
+
if [ -d "$HOME/.local/bin" ] ; then
|
|
39
|
+
PATH="$HOME/.local/bin:$PATH"
|
|
40
|
+
fi
|
|
41
|
+
```
|
|
42
|
+
<hr>
|
|
43
|
+
|
|
44
|
+
Now write a test script, 'hello.ecs', containing the following:
|
|
30
45
|
```
|
|
31
46
|
print `Hello, world!`
|
|
32
47
|
```
|
|
33
|
-
This is traditionally the first program to be written in virtually any language. To run it, use `easycoder hello.ecs`.
|
|
48
|
+
(Note the backticks.) This is traditionally the first program to be written in virtually any language. To run it, use `easycoder hello.ecs`.
|
|
34
49
|
|
|
35
50
|
The output will look like this (the version number will differ):
|
|
36
51
|
```
|
|
@@ -63,19 +78,18 @@ Here in the repository is a folder called `scripts` containing some sample scrip
|
|
|
63
78
|
`benchmark.ecs` allows the performance of **_EasyCoder_** to be compared to other languages if a similar script is written for each one.
|
|
64
79
|
|
|
65
80
|
## Graphical programmming
|
|
66
|
-
**_EasyCoder_** includes a graphical programming environment that is in the early stages of development.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
Some demo graphical scripts are included in the `scripts` directory:
|
|
81
|
+
**_EasyCoder_** includes a graphical programming environment that is in the early stages of development. Some demo scripts will be included in the `scripts` directory; these can be recognised by the extension`.ecg`. To run them, first install `tkinter`. On Linux this is done with
|
|
82
|
+
```
|
|
83
|
+
sudo apt install python3-tk
|
|
84
|
+
```
|
|
71
85
|
|
|
72
|
-
|
|
86
|
+
Next, install the Python `pySimpleGUI` graphics library; this is done with `pip install pysimplegui`. Then run your **_EasyCoder_** script using `easycoder {scriptname}.ecg`.
|
|
73
87
|
|
|
74
|
-
`
|
|
88
|
+
Graphical scripts look much like any other script but their file names must use the extension `.ecg` to signal to **_EasyCoder_** that it needs to load the graphics module. Non-graphical applications can use any extension but `.ecs` is recommended. This allows the **_EasyCoder_** application to be used wherever Python is installed, in either a command-line or a graphical environment, but graphics will of course not be available in the former.
|
|
75
89
|
|
|
76
|
-
|
|
90
|
+
Some demo graphical scripts will included in the `scripts` directory as development proceeds.
|
|
77
91
|
|
|
78
|
-
|
|
92
|
+
`gtest.ecg` contains sample code to demonstrate and test basic features.
|
|
79
93
|
|
|
80
94
|
## Significant features
|
|
81
95
|
|
|
@@ -11,15 +11,30 @@ Website: [https://easycoder.github.io](https://easycoder.github.io)
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
Install **_EasyCoder_** in your Python environment:
|
|
13
13
|
```
|
|
14
|
-
pip install easycoder
|
|
14
|
+
pip install requests pytz easycoder
|
|
15
15
|
```
|
|
16
|
-
You may also need to install `pytz`, as some commands need it.
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
Test the install by typing the command `easycoder`.
|
|
18
|
+
<hr>
|
|
19
|
+
On Linux, this will probably fail as the installer places the executable file in the `$HOME/.local/bin` directory. So give the command
|
|
20
|
+
```
|
|
21
|
+
export PATH=$HOME/.local/bin:$PATH
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
To make this change permanent, edit your `.profile` file, adding the following:
|
|
25
|
+
```
|
|
26
|
+
# set PATH so it includes user's private .local/bin if it exists
|
|
27
|
+
if [ -d "$HOME/.local/bin" ] ; then
|
|
28
|
+
PATH="$HOME/.local/bin:$PATH"
|
|
29
|
+
fi
|
|
30
|
+
```
|
|
31
|
+
<hr>
|
|
32
|
+
|
|
33
|
+
Now write a test script, 'hello.ecs', containing the following:
|
|
19
34
|
```
|
|
20
35
|
print `Hello, world!`
|
|
21
36
|
```
|
|
22
|
-
This is traditionally the first program to be written in virtually any language. To run it, use `easycoder hello.ecs`.
|
|
37
|
+
(Note the backticks.) This is traditionally the first program to be written in virtually any language. To run it, use `easycoder hello.ecs`.
|
|
23
38
|
|
|
24
39
|
The output will look like this (the version number will differ):
|
|
25
40
|
```
|
|
@@ -52,19 +67,18 @@ Here in the repository is a folder called `scripts` containing some sample scrip
|
|
|
52
67
|
`benchmark.ecs` allows the performance of **_EasyCoder_** to be compared to other languages if a similar script is written for each one.
|
|
53
68
|
|
|
54
69
|
## Graphical programmming
|
|
55
|
-
**_EasyCoder_** includes a graphical programming environment that is in the early stages of development.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
Some demo graphical scripts are included in the `scripts` directory:
|
|
70
|
+
**_EasyCoder_** includes a graphical programming environment that is in the early stages of development. Some demo scripts will be included in the `scripts` directory; these can be recognised by the extension`.ecg`. To run them, first install `tkinter`. On Linux this is done with
|
|
71
|
+
```
|
|
72
|
+
sudo apt install python3-tk
|
|
73
|
+
```
|
|
60
74
|
|
|
61
|
-
|
|
75
|
+
Next, install the Python `pySimpleGUI` graphics library; this is done with `pip install pysimplegui`. Then run your **_EasyCoder_** script using `easycoder {scriptname}.ecg`.
|
|
62
76
|
|
|
63
|
-
`
|
|
77
|
+
Graphical scripts look much like any other script but their file names must use the extension `.ecg` to signal to **_EasyCoder_** that it needs to load the graphics module. Non-graphical applications can use any extension but `.ecs` is recommended. This allows the **_EasyCoder_** application to be used wherever Python is installed, in either a command-line or a graphical environment, but graphics will of course not be available in the former.
|
|
64
78
|
|
|
65
|
-
|
|
79
|
+
Some demo graphical scripts will included in the `scripts` directory as development proceeds.
|
|
66
80
|
|
|
67
|
-
|
|
81
|
+
`gtest.ecg` contains sample code to demonstrate and test basic features.
|
|
68
82
|
|
|
69
83
|
## Significant features
|
|
70
84
|
|
|
@@ -98,11 +98,11 @@ class Compiler:
|
|
|
98
98
|
return self.tokens[self.index].lino
|
|
99
99
|
|
|
100
100
|
def warning(self, message):
|
|
101
|
-
self.warnings.append(message)
|
|
101
|
+
self.warnings.append(f'Warning at line {self.getLino() + 1} of {self.program.name}: {message}')
|
|
102
102
|
|
|
103
103
|
def showWarnings(self):
|
|
104
104
|
for warning in self.warnings:
|
|
105
|
-
print(
|
|
105
|
+
print(warning)
|
|
106
106
|
|
|
107
107
|
def getSymbolRecord(self):
|
|
108
108
|
token = self.getToken()
|
|
@@ -9,6 +9,7 @@ class Graphics(Handler):
|
|
|
9
9
|
def __init__(self, compiler):
|
|
10
10
|
Handler.__init__(self, compiler)
|
|
11
11
|
self.utils = GUtils()
|
|
12
|
+
self.eventHandlers = {}
|
|
12
13
|
|
|
13
14
|
def getName(self):
|
|
14
15
|
return 'graphics'
|
|
@@ -18,17 +19,17 @@ class Graphics(Handler):
|
|
|
18
19
|
|
|
19
20
|
def k_add(self, command):
|
|
20
21
|
elements = []
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
22
|
+
token = self.nextToken()
|
|
23
|
+
if self.isSymbol():
|
|
24
|
+
symbolRecord = self.getSymbolRecord()
|
|
25
|
+
name = symbolRecord['name']
|
|
26
|
+
if symbolRecord['keyword'] == 'layout':
|
|
27
|
+
elements.append(name)
|
|
28
|
+
command['args'] = name
|
|
29
|
+
else: FatalError(self.compiler.program, f'\'{name}\' is not a layout')
|
|
30
|
+
else:
|
|
31
|
+
command['type'] = token
|
|
32
|
+
command['args'] = self.utils.getArgs(self)
|
|
32
33
|
if self.nextIs('to'):
|
|
33
34
|
if self.nextIsSymbol():
|
|
34
35
|
symbolRecord = self.getSymbolRecord()
|
|
@@ -40,14 +41,36 @@ class Graphics(Handler):
|
|
|
40
41
|
|
|
41
42
|
def r_add(self, command):
|
|
42
43
|
target = self.getVariable(command['target'])
|
|
43
|
-
|
|
44
|
+
type = command['type']
|
|
45
|
+
args = command['args']
|
|
44
46
|
if not 'layout' in target:
|
|
45
47
|
target['layout'] = []
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
if args[0] == '{':
|
|
49
|
+
layout = json.loads(self.getRuntimeValue(json.loads(args)))
|
|
50
|
+
default = self.utils.getDefaultArgs(type)
|
|
51
|
+
for n in range(0, len(layout)):
|
|
52
|
+
args = self.utils.decode(default, layout[n])
|
|
53
|
+
target['layout'].append(self.utils.createElement(type, args))
|
|
54
|
+
else:
|
|
55
|
+
v = self.getVariable(args)
|
|
48
56
|
target['layout'].append(v['layout'])
|
|
49
57
|
return self.nextPC()
|
|
50
58
|
|
|
59
|
+
def k_capture(self, command):
|
|
60
|
+
if self.nextIs('event'):
|
|
61
|
+
if self.nextIs('as'):
|
|
62
|
+
if self.nextIsSymbol():
|
|
63
|
+
record = self.getSymbolRecord()
|
|
64
|
+
command['target'] = record['name']
|
|
65
|
+
self.addCommand(command)
|
|
66
|
+
return True
|
|
67
|
+
return False
|
|
68
|
+
|
|
69
|
+
def r_capture(self, command):
|
|
70
|
+
target = self.getVariable(command['target'])
|
|
71
|
+
self.putSymbolValue(target, self.getConstant(self.eventValues))
|
|
72
|
+
return self.nextPC()
|
|
73
|
+
|
|
51
74
|
def k_close(self, command):
|
|
52
75
|
if self.nextIsSymbol():
|
|
53
76
|
symbolRecord = self.getSymbolRecord()
|
|
@@ -79,10 +102,6 @@ class Graphics(Handler):
|
|
|
79
102
|
command['layout'] = symbolRecord['name']
|
|
80
103
|
self.addCommand(command)
|
|
81
104
|
return True
|
|
82
|
-
elif type[0:2] == 'g_':
|
|
83
|
-
command['args'] = self.compileConstant(self.utils.getArgs(self))
|
|
84
|
-
self.addCommand(command)
|
|
85
|
-
return True
|
|
86
105
|
return False
|
|
87
106
|
|
|
88
107
|
def r_create(self, command):
|
|
@@ -96,79 +115,10 @@ class Graphics(Handler):
|
|
|
96
115
|
self.mainLoop()
|
|
97
116
|
self.program.kill()
|
|
98
117
|
return 0
|
|
99
|
-
elif 'iselement' in record:
|
|
100
|
-
layout = json.loads(self.getRuntimeValue(command['args']))
|
|
101
|
-
args = self.utils.getDefaultArgs(type)
|
|
102
|
-
content = json.loads(layout['content'])
|
|
103
|
-
for n in range(0, len(content)):
|
|
104
|
-
args = self.utils.decode(args, content[n])
|
|
105
|
-
element = self.utils.createElement(type, args)
|
|
106
|
-
record['layout'] = element
|
|
107
|
-
return self.nextPC()
|
|
108
118
|
else:
|
|
109
119
|
RuntimeError(self.program, 'Variable is not a window or an element')
|
|
110
120
|
|
|
111
|
-
def k_g_button(self, command):
|
|
112
|
-
command['iselement'] = True
|
|
113
|
-
return self.compileVariable(command)
|
|
114
|
-
|
|
115
|
-
def r_g_button(self, command):
|
|
116
|
-
return self.nextPC()
|
|
117
|
-
|
|
118
|
-
def k_g_input(self, command):
|
|
119
|
-
command['iselement'] = True
|
|
120
|
-
return self.compileVariable(command)
|
|
121
|
-
|
|
122
|
-
def r_g_input(self, command):
|
|
123
|
-
return self.nextPC()
|
|
124
|
-
|
|
125
|
-
def k_g_text(self, command):
|
|
126
|
-
command['iselement'] = True
|
|
127
|
-
return self.compileVariable(command)
|
|
128
|
-
|
|
129
|
-
def r_g_text(self, command):
|
|
130
|
-
return self.nextPC()
|
|
131
|
-
|
|
132
|
-
def k_init(self, command):
|
|
133
|
-
if self.nextIsSymbol():
|
|
134
|
-
record = self.getSymbolRecord()
|
|
135
|
-
if record['keyword'] == 'layout':
|
|
136
|
-
command['target'] = record['name']
|
|
137
|
-
if self.peek() == 'with':
|
|
138
|
-
self.nextToken()
|
|
139
|
-
if self.nextIsSymbol():
|
|
140
|
-
record = self.getSymbolRecord()
|
|
141
|
-
name = record['name']
|
|
142
|
-
if record['iselement']:
|
|
143
|
-
command['args'] = name
|
|
144
|
-
else: FatalError(self.program.compiler, f'\'{name}\' is not a graphic element')
|
|
145
|
-
else:
|
|
146
|
-
command['type'] = self.getToken()
|
|
147
|
-
command['args'] = self.utils.getArgs(self)
|
|
148
|
-
else: command['args'] = None
|
|
149
|
-
self.addCommand(command)
|
|
150
|
-
return True
|
|
151
|
-
return False
|
|
152
|
-
|
|
153
|
-
def r_init(self, command):
|
|
154
|
-
record = self.getVariable(command['target'])
|
|
155
|
-
record['layout'] = []
|
|
156
|
-
type = command['type']
|
|
157
|
-
args = command['args']
|
|
158
|
-
if args != None:
|
|
159
|
-
if args[0] == '{':
|
|
160
|
-
layout = json.loads(self.getRuntimeValue(json.loads(args)))
|
|
161
|
-
args = self.utils.getDefaultArgs(type)
|
|
162
|
-
for n in range(0, len(layout)):
|
|
163
|
-
args = self.utils.decode(args, layout[n])
|
|
164
|
-
record['layout'].append(self.utils.createElement(type, args))
|
|
165
|
-
else:
|
|
166
|
-
v = self.getVariable(args)
|
|
167
|
-
record['layout'].append(v['layout'])
|
|
168
|
-
return self.nextPC()
|
|
169
|
-
|
|
170
121
|
def k_layout(self, command):
|
|
171
|
-
command['iselement'] = True
|
|
172
122
|
return self.compileVariable(command)
|
|
173
123
|
|
|
174
124
|
def r_layout(self, command):
|
|
@@ -176,42 +126,8 @@ class Graphics(Handler):
|
|
|
176
126
|
|
|
177
127
|
def k_on(self, command):
|
|
178
128
|
token = self.nextToken()
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
command['event'] = token
|
|
182
|
-
if self.peek() == 'in':
|
|
183
|
-
self.nextToken()
|
|
184
|
-
if self.nextIs('screen'):
|
|
185
|
-
command['target'] = None
|
|
186
|
-
elif self.isSymbol():
|
|
187
|
-
target = self.getSymbolRecord()
|
|
188
|
-
command['target'] = target['name']
|
|
189
|
-
else:
|
|
190
|
-
FatalError(self.program.compiler, f'{self.getToken()} is not a screen element')
|
|
191
|
-
return False
|
|
192
|
-
command['goto'] = self.getPC() + 2
|
|
193
|
-
self.add(command)
|
|
194
|
-
self.nextToken()
|
|
195
|
-
pcNext = self.getPC()
|
|
196
|
-
cmd = {}
|
|
197
|
-
cmd['domain'] = 'core'
|
|
198
|
-
cmd['lino'] = command['lino']
|
|
199
|
-
cmd['keyword'] = 'gotoPC'
|
|
200
|
-
cmd['goto'] = 0
|
|
201
|
-
cmd['debug'] = False
|
|
202
|
-
self.addCommand(cmd)
|
|
203
|
-
self.compileOne()
|
|
204
|
-
cmd = {}
|
|
205
|
-
cmd['domain'] = 'core'
|
|
206
|
-
cmd['lino'] = command['lino']
|
|
207
|
-
cmd['keyword'] = 'stop'
|
|
208
|
-
cmd['debug'] = False
|
|
209
|
-
self.addCommand(cmd)
|
|
210
|
-
# Fixup the link
|
|
211
|
-
self.getCommandAt(pcNext)['goto'] = self.getPC()
|
|
212
|
-
return True
|
|
213
|
-
elif token == 'tick':
|
|
214
|
-
command['event'] = token
|
|
129
|
+
if token == 'event':
|
|
130
|
+
command['key'] = self.nextValue()
|
|
215
131
|
command['goto'] = self.getPC() + 2
|
|
216
132
|
self.add(command)
|
|
217
133
|
self.nextToken()
|
|
@@ -236,17 +152,9 @@ class Graphics(Handler):
|
|
|
236
152
|
return False
|
|
237
153
|
|
|
238
154
|
def r_on(self, command):
|
|
155
|
+
key = self.getRuntimeValue(command['key'])
|
|
239
156
|
pc = command['goto']
|
|
240
|
-
|
|
241
|
-
event = command['event']
|
|
242
|
-
if event == 'click':
|
|
243
|
-
target = command['target']
|
|
244
|
-
if target == None:
|
|
245
|
-
value = 'screen'
|
|
246
|
-
else:
|
|
247
|
-
widget = self.getVariable(target)
|
|
248
|
-
value = widget['value'][widget['index']]
|
|
249
|
-
self.renderer.setOnClick(value['content'], lambda: self.run(pc))
|
|
157
|
+
self.eventHandlers[key] = lambda: self.run(pc)
|
|
250
158
|
return self.nextPC()
|
|
251
159
|
|
|
252
160
|
def k_popup(self, command):
|
|
@@ -259,9 +167,37 @@ class Graphics(Handler):
|
|
|
259
167
|
return self.nextPC()
|
|
260
168
|
|
|
261
169
|
def k_set(self, command):
|
|
262
|
-
|
|
170
|
+
if self.nextIsSymbol():
|
|
171
|
+
record = self.getSymbolRecord()
|
|
172
|
+
keyword = record['keyword']
|
|
173
|
+
if keyword == 'layout':
|
|
174
|
+
command['target'] = record['name']
|
|
175
|
+
if self.peek() == 'to':
|
|
176
|
+
self.nextToken()
|
|
177
|
+
command['type'] = self.nextToken()
|
|
178
|
+
command['args'] = self.utils.getArgs(self)
|
|
179
|
+
else: command['args'] = None
|
|
180
|
+
self.addCommand(command)
|
|
181
|
+
return True
|
|
182
|
+
elif keyword == 'event':
|
|
183
|
+
pass
|
|
184
|
+
return False
|
|
263
185
|
|
|
264
186
|
def r_set(self, command):
|
|
187
|
+
target = self.getVariable(command['target'])
|
|
188
|
+
target['layout'] = []
|
|
189
|
+
type = command['type']
|
|
190
|
+
args = command['args']
|
|
191
|
+
if args != None:
|
|
192
|
+
if args[0] == '{':
|
|
193
|
+
layout = json.loads(self.getRuntimeValue(json.loads(args)))
|
|
194
|
+
default = self.utils.getDefaultArgs(type)
|
|
195
|
+
for n in range(0, len(layout)):
|
|
196
|
+
args = self.utils.decode(default, layout[n])
|
|
197
|
+
target['layout'].append(self.utils.createElement(type, args))
|
|
198
|
+
else:
|
|
199
|
+
v = self.getVariable(args)
|
|
200
|
+
target['layout'].append(v['layout'])
|
|
265
201
|
return self.nextPC()
|
|
266
202
|
|
|
267
203
|
def k_window(self, command):
|
|
@@ -274,19 +210,20 @@ class Graphics(Handler):
|
|
|
274
210
|
# Compile a value in this domain
|
|
275
211
|
def compileValue(self):
|
|
276
212
|
value = {}
|
|
277
|
-
value['domain'] =
|
|
213
|
+
value['domain'] = self.getName()
|
|
278
214
|
token = self.getToken()
|
|
279
215
|
if self.isSymbol():
|
|
216
|
+
value['name'] = token
|
|
217
|
+
symbolRecord = self.getSymbolRecord()
|
|
218
|
+
keyword = symbolRecord['keyword']
|
|
219
|
+
if keyword == 'event':
|
|
220
|
+
value['type'] = 'symbol'
|
|
221
|
+
return value
|
|
280
222
|
return None
|
|
281
223
|
|
|
282
|
-
if self.tokenIs('the'):
|
|
283
|
-
self.nextToken()
|
|
284
|
-
token = self.getToken()
|
|
285
|
-
|
|
286
224
|
value['type'] = token
|
|
287
225
|
|
|
288
226
|
if token == 'test':
|
|
289
|
-
name = self.nextToken()
|
|
290
227
|
value = {}
|
|
291
228
|
value['type'] = 'text'
|
|
292
229
|
value['content'] = 'test'
|
|
@@ -302,6 +239,13 @@ class Graphics(Handler):
|
|
|
302
239
|
#############################################################################
|
|
303
240
|
# Value handlers
|
|
304
241
|
|
|
242
|
+
# This is used by the expression evaluator to get the value of a symbol
|
|
243
|
+
def v_symbol(self, symbolRecord):
|
|
244
|
+
if symbolRecord['keyword'] == 'event':
|
|
245
|
+
return self.getSymbolValue(symbolRecord)
|
|
246
|
+
else:
|
|
247
|
+
return None
|
|
248
|
+
|
|
305
249
|
def v_test(self, v):
|
|
306
250
|
return v
|
|
307
251
|
|
|
@@ -323,4 +267,7 @@ class Graphics(Handler):
|
|
|
323
267
|
break
|
|
324
268
|
if event == '__TIMEOUT__': self.program.flushCB()
|
|
325
269
|
else:
|
|
326
|
-
|
|
270
|
+
if event in self.eventHandlers:
|
|
271
|
+
self.eventValues = values
|
|
272
|
+
self.eventHandlers[event]()
|
|
273
|
+
|
|
@@ -21,13 +21,13 @@ class GUtils:
|
|
|
21
21
|
# Get the default args for a graphic element
|
|
22
22
|
def getDefaultArgs(self, type):
|
|
23
23
|
args = {}
|
|
24
|
-
if type == '
|
|
24
|
+
if type == 'Text':
|
|
25
25
|
args['text'] = '(empty)'
|
|
26
26
|
args['expand_x'] = False
|
|
27
|
-
elif type == '
|
|
27
|
+
elif type == 'Input':
|
|
28
28
|
args['key'] = None
|
|
29
29
|
args['size'] = (None, None)
|
|
30
|
-
elif type == '
|
|
30
|
+
elif type == 'Button':
|
|
31
31
|
args['button_text'] = '(empty)'
|
|
32
32
|
return args
|
|
33
33
|
|
|
@@ -43,10 +43,10 @@ class GUtils:
|
|
|
43
43
|
|
|
44
44
|
# Create an element
|
|
45
45
|
def createElement(self, type, args):
|
|
46
|
-
if type == '
|
|
47
|
-
elif type == '
|
|
46
|
+
if type == 'Text': return psg.Text(text=args['text'], expand_x=args['expand_x'])
|
|
47
|
+
elif type == 'Input':
|
|
48
48
|
size = args['size'].split()
|
|
49
49
|
size = (size[0], size[1])
|
|
50
50
|
return psg.Input(key=args['key'], size=size)
|
|
51
|
-
elif type == '
|
|
51
|
+
elif type == 'Button': return psg.Button(button_text=args['button_text'])
|
|
52
52
|
else: return None
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
! A test script
|
|
2
|
+
|
|
3
|
+
script Test
|
|
4
|
+
|
|
5
|
+
layout Row
|
|
6
|
+
layout Layout
|
|
7
|
+
window Window
|
|
8
|
+
variable Event
|
|
9
|
+
variable N
|
|
10
|
+
|
|
11
|
+
popup `Hello!`
|
|
12
|
+
! debug step
|
|
13
|
+
|
|
14
|
+
set Row to Text text `Date (YYYY-MM-DD):` and expand_x true
|
|
15
|
+
add Input key `-DATE-` and size `20 1` to Row
|
|
16
|
+
add Row to Layout
|
|
17
|
+
|
|
18
|
+
set Row to Text text `Time (HH:MM):` and expand_x true
|
|
19
|
+
add Input key `-TIME-` and size `20 1` to Row
|
|
20
|
+
add Row to Layout
|
|
21
|
+
|
|
22
|
+
set Row to Text text `Your name:` and expand_x true
|
|
23
|
+
add Input key `-NAME-` and size `20 1` to Row
|
|
24
|
+
add Row to Layout
|
|
25
|
+
|
|
26
|
+
set Row to Button button_text `Click me`
|
|
27
|
+
add Row to Layout
|
|
28
|
+
|
|
29
|
+
create Window `Graphics Test`
|
|
30
|
+
layout Layout
|
|
31
|
+
|
|
32
|
+
on event `Click me`
|
|
33
|
+
begin
|
|
34
|
+
capture event as Event
|
|
35
|
+
print `Date: ` cat property `-DATE-` of Event
|
|
36
|
+
print `Time: ` cat property `-TIME-` of Event
|
|
37
|
+
print `Name: ` cat property `-NAME-` of Event
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
put 0 into N
|
|
41
|
+
while true
|
|
42
|
+
begin
|
|
43
|
+
if N modulo 1000 is 0 print `Running ` cat N
|
|
44
|
+
increment N
|
|
45
|
+
wait 10 ticks
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
stop
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
! A test script
|
|
2
|
-
|
|
3
|
-
script Test
|
|
4
|
-
|
|
5
|
-
layout Row
|
|
6
|
-
layout Layout
|
|
7
|
-
window Window
|
|
8
|
-
g_input Input
|
|
9
|
-
g_button Button
|
|
10
|
-
variable N
|
|
11
|
-
|
|
12
|
-
init Layout
|
|
13
|
-
|
|
14
|
-
! popup `Hello!`
|
|
15
|
-
! debug step
|
|
16
|
-
|
|
17
|
-
init Row with g_text text `Date (YYYY-MM-DD):` and expand_x true
|
|
18
|
-
create Input key `-DATE-` and size `20 1`
|
|
19
|
-
add Input to Row
|
|
20
|
-
add Row to Layout
|
|
21
|
-
init Row with g_text text `Time (HH:MM):` and expand_x true
|
|
22
|
-
create Input key `-TIME-` and size `20 1`
|
|
23
|
-
add Input to Row
|
|
24
|
-
add Row to Layout
|
|
25
|
-
init Row with g_text text `Your name:` and expand_x true
|
|
26
|
-
create Input key `-NAME-` and size `20 1`
|
|
27
|
-
add Input to Row
|
|
28
|
-
add Row to Layout
|
|
29
|
-
create Button button_text `Click me`
|
|
30
|
-
init Row with Button
|
|
31
|
-
add Row to Layout
|
|
32
|
-
|
|
33
|
-
create Window `Graphics Test`
|
|
34
|
-
layout Layout
|
|
35
|
-
|
|
36
|
-
put 0 into N
|
|
37
|
-
while true
|
|
38
|
-
begin
|
|
39
|
-
if N modulo 1000 is 0 print `Running ` cat N
|
|
40
|
-
increment N
|
|
41
|
-
wait 10 ticks
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
stop
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|