@@ -4,15 +4,15 @@ Implementation
44On this chapter the implementation of the system is detailed, explained what
55was done in each iteration.
66After the iterations Persimmon intermediate representation is explained.
7- Finally some of the most complex technical problems along their respective
7+ Finally, some of the most complex technical problems along their respective
88solutions are detailed.
99
1010
1111First Iteration
1212---------------
1313![ Implementation of the first interface] ( images/interface.png )
1414
15- For the first iteration the priority was to get a proof of concept in order to
15+ For the first iteration, the priority was to get a proof of concept in order to
1616see where the difficulties can appear, with a few simple classifiers and
1717cross-validation techniques. As such a button-based interface with very limited
1818workflow creation was chosen.
@@ -25,8 +25,8 @@ Trees, but gives good results in wide variety of problems.
2525All these classifiers have few parameters on their respective sklearn
2626implementations, and for this prototype the interface did not allow modifying
2727any of them, as the it would have cluttered and it was not a necessary feature.
28- Also all of them are classifiers, as it simplifies the interface, since
29- regressors and clustering have some incompatibilities.
28+ Also, all of them are classifiers, as it simplifies the interface, since
29+ regression and clustering have some incompatibilities.
3030
3131Apart from the temporary interface the backend had to be built. Since the
3232workflow was fixed the backend simply received the node as arguments and
@@ -36,7 +36,7 @@ needed for this iteration.
3636
3737Second Iteration
3838----------------
39- For the second interface the drag and drop feel was the main priority.
39+ For the second iteration the drag and drop feel was the main priority.
4040As such after developing the tab panel draggable boxes were developed, these
4141boxes needed to be connected through pins.
4242The logic behind the pins and the blocks is quite heavy, as there is a tight
@@ -54,7 +54,7 @@ particular function tools such as `Numba`[^Numba] or `Cython` could be used.
5454
5555Third Iteration
5656---------------
57- For the third and final iteration the focus was on improving the visual aspect,
57+ For the third and final iteration, the focus was on improving the visual aspect,
5858adding helpful aids to the user experience.
5959The main addition being adding a notification systems that gives feedback to
6060the user about the outcome of their actions and the type systems that prevents
@@ -69,7 +69,7 @@ a warning showing up when a block has only some of their inputs connected.
6969Model View Controller
7070---------------------
7171Since the beginning of development separation of logic and presentation has
72- been a priority. For this matter the Model View Controller[ ^ MVC ] pattern has
72+ been a priority. For this reason, the Model View Controller[ ^ MVC ] pattern has
7373been applied, separating Model (represented by the subpackage backend), View
7474(represented by the ` .py ` files on view subpackage) and Controller
7575(corresponding to the ` .kv ` files on view subpackage).
@@ -79,7 +79,7 @@ the current kivy framework for another one by just changed the view, no
7979modifications to the backend needed.
8080
8181In order to avoid repetition extensive use of classes coupled with reusable
82- custom kivy Widgets was used. This for example meant that each individual pin
82+ custom kivy Widgets were used. This for example meant that each individual pin
8383on each block is a class, this proved useful for defining matching pins in
8484different blocks (like when connection a pin that sends data to a pin that
8585receives it).
@@ -89,7 +89,7 @@ For more information about internal package distribution check appendix A.
8989
9090Making a Connection
9191-------------------
92- One of the most complex part of the system is starting, reconnecting and
92+ One of the most complex parts of the system is starting, reconnecting and
9393deleting a connection between blocks, it involves several actors, asynchronous
9494callbacks and a very strong coupling between all elements.
9595
@@ -99,7 +99,7 @@ In order to understand how connections are made it is necessary to understand
9999how ` Kivy ` handles input.
100100At surface level ` Kivy ` follows the traditional event-based input management,
101101with the event propagating downwards from the root.
102- However while traditionally inputs events are only passed down to components
102+ However, while traditionally inputs events are only passed down to components
103103that are on the event position ` Kivy ` passes the events to almost all children
104104by default, this is done because in phones (one of ` Kivy ` targets is Android)
105105gestures tend to start outside the actual widget they intend to affect.
@@ -109,7 +109,7 @@ when a key is is pressed, `on_touch_move` that is notified when the touch is
109109moved, i.e. a finger moves across the screen, or on this cases when the mouse
110110moves, and ` on_touch_up ` that is fired when the touch is released.
111111
112- Lets represent the possible actions as use cases, the outer \* represents
112+ Let's represent the possible actions as use cases, the outer \* represents
113113` on_touch_down ` , - represents ` on_touch_move ` , and the inner \* ` on_touch_up ` :
114114
115115* (On pin) Start a connection.
@@ -123,9 +123,9 @@ Logic is split in two big cases, creating a connection and modifying an
123123existing one.
124124Creating a connection involves creating one end of the connection, both
125125visually and logically and preparing the line that will follow the cursor.
126- On the other hand modifying a connection means removing the end that is being
126+ On the other hand, modifying a connection means removing the end that is being
127127touched.
128- This two cases can be handled by different classes, pin on the first case and
128+ These two cases can be handled by different classes, pin on the first case and
129129connection for the last.
130130Moving and finishing the connection use the same code for both.
131131
@@ -138,14 +138,15 @@ canvas, and when a connection is destroyed (this only happens inside
138138depending if the connection is destroyed because the pin violates type safety
139139or there is no pin under the cursor respectively) it has to unbind the logical
140140connections of the pins themselves.
141- For this reason connection has high-level functions that do the unbind, rebind
141+ For this reason, connection has high-level functions that do the unbind, rebind
142142and deletion of ends, as long as the necessary elements are passed (dependency
143143injection pattern).
144144
145145This is the reconnecting logic, notice how the reconnecting is * forward* or
146146* backwards* depending on which edge the touch has happened, of course if neither
147147has been touched the touch event is not handled.
148148
149+
149150~~~ python
150151def on_touch_down (self , touch ):
151152 """ On touch down on connection means we are modifying an already
@@ -169,6 +170,9 @@ def on_touch_down(self, touch):
169170 else :
170171 return False
171172~~~
173+ \begin{figure}
174+ \caption{Connection modification handling}
175+ \end{figure}
172176
173177Visualizing the Data Flow
174178-------------------------
@@ -186,7 +190,7 @@ But the frontend does not receive the block, only the hash, since that is all
186190the backend has, and it has to compare with all block hashes to find the actual
187191block.
188192
189- After this the backend has to make the outgoing connections of that block
193+ After this, the backend has to make the outgoing connections of that block
190194pulse, meaning for example changing the value of the width of the line between
191195certain values, a function that works well for this is the sin function.
192196The tricky part is that each time the function is called it has to remember the
@@ -198,7 +202,7 @@ generator (also known as semi-coroutines).
198202But what happens when coroutine needs to be stopped from being called? Kivy
199203has a mechanism where if the scheduled function returns ` False ` it will stop
200204calling, by default our coroutine does not return any meaningful value, but
201- we can put a final ` yield False` that will stop the calls.
205+ it is possible to yield a final ` False ` that will stop the calls.
202206But how is that yield triggered? The proper solution solution is using
203207a full coroutine (either a generator-based one of the newer asyncio ones), but
204208then concurrency issues appears, such that since the coroutine is being called
@@ -256,9 +260,9 @@ importing, it also breaks resource loading at execution time (since it has to
256260create a temporary folder). This results in manually specifying hidden
257261dependencies and non python files (on this case mostly ` kv ` files).
258262
259- Unfortunately this process has to be done on a windows system, and as such
263+ Unfortunately, this process has to be done on a windows system, and as such
260264cannot be done on the CI[ ^ CI ] server, to see how Persimmon utilizes CI check
261- the appendix on how this document was made .
265+ the appendix B .
262266
263267
264268[ ^ blackboard ] : Blackboard is where the blocks and connections reside.
0 commit comments