Working with strings using Engee blocks¶
In this example, we will create some "custom blocks" that will allow us to perform operations on strings as arrays.
Sometimes working with strings requires the use of substantial mathematical apparatus, which in educational materials and articles is usually presented through flowcharts (for example, in cryptorgaphy). In such problems it is very useful to be able to quickly model the solution, explore alternatives and perform experiments. Representation of an algorithm in the form of blocks improves readability and simplifies work with their structure, allows to easily combine the algorithm with other stages of information processing, visualise interfaces, etc.
The custom blocks we have created for this example are intended to demonstrate one of the approaches for working with strings using graphical modelling tools in Engee.
In the properties of each block, there is a field through which you can enter a string.
Further work with this string is performed in the mask editor, which converts it into a numerical vector using the required method:
- converts it to a bit representation,
- or encodes each letter by its position in the Latin alphabet (in lower case -
AbC
becomes 123
),
- or does the same in the Cyrillic alphabet (
бвГ
becomes 234
).
The mask performs preprocessing and converts the string entered in the "Text" field into the required encoding. It is also possible to organise encoding selection directly in the mask.
What the block mask does¶
A mask of each custom block:
- translates the text to the desired encoding and sets it as a parameter of
Value
block Constant
, hidden under the mask,
- sets a special sampling time (
SampleTime
) to block Constant
so that after passing through block Unbuffer
the vector of output parameters is output one character per second,
- updates the appearance of the block.
Blocks return an array of some length. To make it easier to work with individual bits or symbols, the sampling step of the block output value is made equal to the length of the string. *If the integration step of the model is 1s, a string of 5 characters long will be output by the Constant block only every 5 seconds. After each such block there is an Unbuffer block, which decomposes the input vector into individual elements and returns an element for each simulation step.
Start this model using software control commands:
Let's plot the output of the first block Unicode String To Bytes
:
We get the string "A" (Latin character A
, code 0x41
or 65
in decimal system) in binary representation: 0100 0001
.
To get the string in "byte representation" you can use the command codeunits(ваша_строка)
, but you should keep in mind that the source string is encoded in Unicode, so Cyrillic characters will be double-byte.
Out[0]:
1×12 adjoint(::Base.CodeUnits{UInt8, String}) with eltype UInt8:
0xd0 0x9f 0xd1 0x80 0xd0 0xb8 0xd0 0xb2 0xd0 0xb5 0xd1 0x82
Representing a term as an array of numbers comes in handy in protocol analysis and cryptography.
The use of such blocks allows to hide unnecessary levels of technical work with strings from the profile specialist and concentrate on demonstration of the modelled process or algorithm.
{"id": "db94afce-9c7b-49b7-b8b6-83ab310436d5", "data": [{"showlegend": false, "mode": "markers", "xaxis": "x", "colorbar": {"y": 0.7395833333333333, "title": {"text": ""}, "len": 0.40392607174103246, "x": 0.9934383202099738}, "name": "", "yaxis": "y", "legendgroup": "", "marker": {"symbol": "circle", "color": "rgba(108, 159, 51, 1.000)", "line": {"color": "rgba(0, 0, 0, 1)", "width": 1}, "size": 8}, "y": [0.01, 0.01, 0.01], "type": "scatter", "x": [0, 8, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 3, "currentCount": 3}}}, {"showlegend": true, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.7395833333333333, "title": {"text": ""}, "len": 0.40392607174103246, "x": 0.9934383202099738}, "name": "y1", "yaxis": "y", "legendgroup": "y1", "line": {"color": "rgba(0, 154, 250, 1.000)", "shape": "linear", "dash": "solid", "width": 1}, "y": [0.01, 0.01, 0.01, 0.01, 0.01], "type": "scatter", "x": [0, 8, 8, 16, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 5, "currentCount": 5}}}, {"showlegend": false, "mode": "markers", "xaxis": "x", "colorbar": {"y": 0.7395833333333333, "title": {"text": ""}, "len": 0.40392607174103246, "x": 0.9934383202099738}, "name": "", "yaxis": "y", "legendgroup": "", "marker": {"symbol": "circle", "color": "rgba(0, 154, 250, 1.000)", "line": {"color": "rgba(0, 0, 0, 1)", "width": 1}, "size": 8}, "y": [1.02, 1.02, 1.02], "type": "scatter", "x": [0, 8, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 3, "currentCount": 3}}}, {"showlegend": true, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.7395833333333333, "title": {"text": ""}, "len": 0.40392607174103246, "x": 0.9934383202099738}, "name": "y2", "yaxis": "y", "legendgroup": "y2", "line": {"color": "rgba(227, 111, 71, 1.000)", "shape": "linear", "dash": "solid", "width": 1}, "y": [1.02, 1.02, 1.02, 1.02, 1.02], "type": "scatter", "x": [0, 8, 8, 16, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 5, "currentCount": 5}}}, {"showlegend": false, "mode": "markers", "xaxis": "x", "colorbar": {"y": 0.7395833333333333, "title": {"text": ""}, "len": 0.40392607174103246, "x": 0.9934383202099738}, "name": "", "yaxis": "y", "legendgroup": "", "marker": {"symbol": "circle", "color": "rgba(227, 111, 71, 1.000)", "line": {"color": "rgba(0, 0, 0, 1)", "width": 1}, "size": 8}, "y": [0.03, 0.03, 0.03], "type": "scatter", "x": [0, 8, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 3, "currentCount": 3}}}, {"showlegend": true, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.7395833333333333, "title": {"text": ""}, "len": 0.40392607174103246, "x": 0.9934383202099738}, "name": "y3", "yaxis": "y", "legendgroup": "y3", "line": {"color": "rgba(62, 164, 78, 1.000)", "shape": "linear", "dash": "solid", "width": 1}, "y": [0.03, 0.03, 0.03, 0.03, 0.03], "type": "scatter", "x": [0, 8, 8, 16, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 5, "currentCount": 5}}}, {"showlegend": false, "mode": "markers", "xaxis": "x", "colorbar": {"y": 0.7395833333333333, "title": {"text": ""}, "len": 0.40392607174103246, "x": 0.9934383202099738}, "name": "", "yaxis": "y", "legendgroup": "", "marker": {"symbol": "circle", "color": "rgba(62, 164, 78, 1.000)", "line": {"color": "rgba(0, 0, 0, 1)", "width": 1}, "size": 8}, "y": [0.04, 0.04, 0.04], "type": "scatter", "x": [0, 8, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 3, "currentCount": 3}}}, {"showlegend": true, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.7395833333333333, "title": {"text": ""}, "len": 0.40392607174103246, "x": 0.9934383202099738}, "name": "y4", "yaxis": "y", "legendgroup": "y4", "line": {"color": "rgba(195, 113, 210, 1.000)", "shape": "linear", "dash": "solid", "width": 1}, "y": [0.04, 0.04, 0.04, 0.04, 0.04], "type": "scatter", "x": [0, 8, 8, 16, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 5, "currentCount": 5}}}, {"showlegend": false, "mode": "markers", "xaxis": "x", "colorbar": {"y": 0.7395833333333333, "title": {"text": ""}, "len": 0.40392607174103246, "x": 0.9934383202099738}, "name": "", "yaxis": "y", "legendgroup": "", "marker": {"symbol": "circle", "color": "rgba(195, 113, 210, 1.000)", "line": {"color": "rgba(0, 0, 0, 1)", "width": 1}, "size": 8}, "y": [0.05, 0.05, 0.05], "type": "scatter", "x": [0, 8, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 3, "currentCount": 3}}}, {"showlegend": true, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.7395833333333333, "title": {"text": ""}, "len": 0.40392607174103246, "x": 0.9934383202099738}, "name": "y5", "yaxis": "y", "legendgroup": "y5", "line": {"color": "rgba(172, 142, 24, 1.000)", "shape": "linear", "dash": "solid", "width": 1}, "y": [0.05, 0.05, 0.05, 0.05, 0.05], "type": "scatter", "x": [0, 8, 8, 16, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 5, "currentCount": 5}}}, {"showlegend": false, "mode": "markers", "xaxis": "x", "colorbar": {"y": 0.7395833333333333, "title": {"text": ""}, "len": 0.40392607174103246, "x": 0.9934383202099738}, "name": "", "yaxis": "y", "legendgroup": "", "marker": {"symbol": "circle", "color": "rgba(172, 142, 24, 1.000)", "line": {"color": "rgba(0, 0, 0, 1)", "width": 1}, "size": 8}, "y": [0.06, 0.06, 0.06], "type": "scatter", "x": [0, 8, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 3, "currentCount": 3}}}, {"showlegend": true, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.7395833333333333, "title": {"text": ""}, "len": 0.40392607174103246, "x": 0.9934383202099738}, "name": "y6", "yaxis": "y", "legendgroup": "y6", "line": {"color": "rgba(0, 170, 174, 1.000)", "shape": "linear", "dash": "solid", "width": 1}, "y": [0.06, 0.06, 0.06, 0.06, 0.06], "type": "scatter", "x": [0, 8, 8, 16, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 5, "currentCount": 5}}}, {"showlegend": false, "mode": "markers", "xaxis": "x", "colorbar": {"y": 0.7395833333333333, "title": {"text": ""}, "len": 0.40392607174103246, "x": 0.9934383202099738}, "name": "", "yaxis": "y", "legendgroup": "", "marker": {"symbol": "circle", "color": "rgba(0, 170, 174, 1.000)", "line": {"color": "rgba(0, 0, 0, 1)", "width": 1}, "size": 8}, "y": [0.07, 0.07, 0.07], "type": "scatter", "x": [0, 8, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 3, "currentCount": 3}}}, {"showlegend": true, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.7395833333333333, "title": {"text": ""}, "len": 0.40392607174103246, "x": 0.9934383202099738}, "name": "y7", "yaxis": "y", "legendgroup": "y7", "line": {"color": "rgba(237, 94, 147, 1.000)", "shape": "linear", "dash": "solid", "width": 1}, "y": [0.07, 0.07, 0.07, 0.07, 0.07], "type": "scatter", "x": [0, 8, 8, 16, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 5, "currentCount": 5}}}, {"showlegend": false, "mode": "markers", "xaxis": "x", "colorbar": {"y": 0.7395833333333333, "title": {"text": ""}, "len": 0.40392607174103246, "x": 0.9934383202099738}, "name": "", "yaxis": "y", "legendgroup": "", "marker": {"symbol": "circle", "color": "rgba(237, 94, 147, 1.000)", "line": {"color": "rgba(0, 0, 0, 1)", "width": 1}, "size": 8}, "y": [1.08, 1.08, 1.08], "type": "scatter", "x": [0, 8, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 3, "currentCount": 3}}}, {"showlegend": true, "mode": "lines", "xaxis": "x", "colorbar": {"y": 0.7395833333333333, "title": {"text": ""}, "len": 0.40392607174103246, "x": 0.9934383202099738}, "name": "y8", "yaxis": "y", "legendgroup": "y8", "line": {"color": "rgba(198, 130, 37, 1.000)", "shape": "linear", "dash": "solid", "width": 1}, "y": [1.08, 1.08, 1.08, 1.08, 1.08], "type": "scatter", "x": [0, 8, 8, 16, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 5, "currentCount": 5}}}, {"showlegend": false, "mode": "markers", "xaxis": "x2", "colorbar": {"y": 0.23958333333333323, "title": {"text": ""}, "len": 0.4039260717410324, "x": 0.9934383202099738}, "name": "", "yaxis": "y2", "legendgroup": "", "marker": {"symbol": "circle", "color": "rgba(108, 159, 51, 1.000)", "line": {"color": "rgba(0, 0, 0, 1)", "width": 1}, "size": 8}, "y": [0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0], "type": "scatter", "x": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 17, "currentCount": 17}}}, {"showlegend": true, "mode": "lines", "xaxis": "x2", "colorbar": {"y": 0.23958333333333323, "title": {"text": ""}, "len": 0.4039260717410324, "x": 0.9934383202099738}, "name": "y1", "yaxis": "y2", "legendgroup": "y1", "line": {"color": "rgba(0, 154, 250, 1.000)", "shape": "linear", "dash": "solid", "width": 1}, "y": [0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0], "type": "scatter", "x": [0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 33, "currentCount": 33}}}], "config": {"showlegend": false, "paper_bgcolor": "rgba(255, 255, 255, 1.000)", "height": 400, "yaxis2": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [0, 0.25, 0.5, 0.75, 1], "range": [-0.030000000000000027, 1.03], "domain": [0.03762029746281702, 0.44154636920384943], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["0.00", "0.25", "0.50", "0.75", "1.00"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "x2", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "xaxis2": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [0, 5, 10, 15], "range": [-0.4800000000000004, 16.48], "domain": [0.0658209390492855, 0.9934383202099738], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["0", "5", "10", "15"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "y2", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "annotations": [{"yanchor": "top", "xanchor": "center", "rotation": 0, "y": 1, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 20}, "yref": "paper", "showarrow": false, "text": "Кадры (8 бит в каждом + смещение для визуализации)", "xref": "paper", "x": 0.5296296296296296}, {"yanchor": "top", "xanchor": "center", "rotation": 0, "y": 0.49999999999999994, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 20}, "yref": "paper", "showarrow": false, "text": "Поток битов", "xref": "paper", "x": 0.5296296296296296}], "plot_bgcolor": "rgba(255, 255, 255, 1.000)", "margin": {"l": 0, "b": 20, "r": 0, "t": 20}, "width": 1320.375, "xaxis": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [0, 5, 10, 15], "range": [-0.4800000000000004, 16.48], "domain": [0.0658209390492855, 0.9934383202099738], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["0", "5", "10", "15"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "y", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "yaxis": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [0, 0.25, 0.5, 0.75, 1], "range": [-0.02210000000000001, 1.1121], "domain": [0.537620297462817, 0.9415463692038495], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["0.00", "0.25", "0.50", "0.75", "1.00"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "x", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}}}