<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tomaž Vinko</title>
    <description>The latest articles on DEV Community by Tomaž Vinko (@tvinko).</description>
    <link>https://dev.to/tvinko</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F267671%2F85d02c71-372f-4ec3-9bee-8028e9a8d445.jpg</url>
      <title>DEV Community: Tomaž Vinko</title>
      <link>https://dev.to/tvinko</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tvinko"/>
    <language>en</language>
    <item>
      <title>CI/CD from Zero To Hero 2/N</title>
      <dc:creator>Tomaž Vinko</dc:creator>
      <pubDate>Mon, 03 Jan 2022 14:29:20 +0000</pubDate>
      <link>https://dev.to/tvinko/cicd-from-zero-to-hero-2n-ll6</link>
      <guid>https://dev.to/tvinko/cicd-from-zero-to-hero-2n-ll6</guid>
      <description>&lt;p&gt;This is the second tutorial in CI/CD series. Please refer to &lt;a href="https://dev.to/tvinko/cicd-from-zero-to-hero-1n-24mg"&gt;first post&lt;/a&gt; for introduction.&lt;/p&gt;

&lt;p&gt;In this tutorial, we are going to explain what are we CI/CD-ing.&lt;br&gt;
System is hosted on &lt;a href="https://github.com/tvinko/TrackingServicePlatform"&gt;github&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;I'm not going into application logic details, because the scope of the tutorial series is to create CI/CD pipeline.&lt;br&gt;
So let's just briefly go through some technical stuff here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/tvinko/TrackingServicePlatform/tree/main/TrackingService"&gt;TrackingService&lt;/a&gt;&lt;br&gt;
This is Microservice API that receives and validates requests. GET method of TrackingServiceController is pretty much self explanatory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// Validates account and publish event if account is valid&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;param name="accountId"&amp;gt;Account to validate&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;param name="data"&amp;gt;Published event message data&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{accountId}"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IActionResult&lt;/span&gt; &lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;accountStatusData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;AccountStatusData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Validates account &lt;/span&gt;
 &lt;span class="n"&gt;_trackingServiceAccountUnit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CheckAccountStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accountStatusData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="c1"&gt;// Account has passed validation&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accountStatusData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpCode&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;HTTP_CODES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SUCCESS_ACCOUNT_ACTIVE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;_mqttService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Connect&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="n"&gt;accountStatusData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpCode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HTTP_CODES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ERROR_MQTT_CONN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
           &lt;span class="n"&gt;accountStatusData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpMessage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"MQTT Connection error"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
       &lt;span class="k"&gt;else&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="n"&gt;_mqttService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{0}/{1}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_mqttService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RootTopic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                         &lt;span class="n"&gt;JsonConvert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SerializeObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PropagatedData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
                         &lt;span class="n"&gt;MqttMsgBase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QOS_LEVEL_AT_LEAST_ONCE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ObjectResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accountStatusData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;StatusCode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;accountStatusData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpCode&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;WebApi accepts two parameters. The first is the account id that has to be validated and the second is some arbitrary data.&lt;/li&gt;
&lt;li&gt;Account can have three states: active (exists in DB with active status), non-active (exists in DB but with non-active status), and invalid (does not exist in DB) &lt;/li&gt;
&lt;li&gt;If the account is valid, then event data is forwarded and published by the MQTT broker on accountId topic &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/tvinko/TrackingServicePlatform/tree/main/TrackingServiceCLI"&gt;TrackingServiceCLI&lt;/a&gt;&lt;br&gt;
Tracking Service CLI is the command-line client which subscribes to MQTT topics to receive events from TrackingService WebAPI. It can be controlled from the command line. You can see it in action &lt;a href="https://github.com/tvinko/TrackingServicePlatform/blob/main/TrackingServiceCLI/Program.cs"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/tvinko/TrackingServicePlatform/tree/main/TrackingServiceTest"&gt;TrackingServiceTest&lt;/a&gt;&lt;br&gt;
Code unit and integration tests. You can see details &lt;a href="https://github.com/tvinko/TrackingServicePlatform/blob/main/TrackingServiceTest/TrackingServiceApiTests.cs"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A particularly interesting method is &lt;code&gt;Performance_Test_500_Requests&lt;/code&gt; which tests performance - 500 cycles must be completed in under one second. One cycle represents delivering request through MQTT to subscribing client.&lt;/p&gt;

&lt;p&gt;The platform is written in C# and uses SQL Server database. You don't have to have NET Core and SQL Server installed on your local machine because CI/CD pipeline will be executed and compiled by GitHub action.&lt;/p&gt;

&lt;p&gt;In the next tutorial, we are going to explain GitHub’s actions. You can fork the repository because you are going to create CI/CD pipeline step by step from scratch.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>CI/CD from Zero To Hero 1/N</title>
      <dc:creator>Tomaž Vinko</dc:creator>
      <pubDate>Tue, 21 Dec 2021 20:46:33 +0000</pubDate>
      <link>https://dev.to/tvinko/cicd-from-zero-to-hero-1n-24mg</link>
      <guid>https://dev.to/tvinko/cicd-from-zero-to-hero-1n-24mg</guid>
      <description>&lt;h3&gt;
  
  
  INTRO
&lt;/h3&gt;

&lt;p&gt;Grab your coffee, beer or whatever keeps you awake, because this series of articles will be a quite long journey. We are going to create a fully functional CI/CD system from the scratch.&lt;/p&gt;

&lt;p&gt;Lets start with some official documentation&lt;br&gt;
&lt;strong&gt;Continuous integration (CI)&lt;/strong&gt; is an automation process for developers. Your code changes are regularly built, tested, and merged into a shared repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Continuous delivery (CD)&lt;/strong&gt; is on the other hand a software engineering approach in which teams produce software in short cycles, ensuring that the software can be reliably released at any time and, when releasing the software, without doing so manually.&lt;/p&gt;

&lt;p&gt;Those definitions might be hard to understand if you're new to CI/CD. In practice it looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You made some code changes locally&lt;/li&gt;
&lt;li&gt;Push those changes to your code repository (github...)&lt;/li&gt;
&lt;li&gt;Code repository receives your changes and executes automated actions that compile and test the code&lt;/li&gt;
&lt;li&gt;In the final phase, the deployment to your environments (testing, staging, production...) is made. Those deployments can be on cloud (AWS, Azure, Google...) or on premises&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice, those cycles might be more complicated. But the point is that the whole procedure is fully automated - from code commit to deploying.&lt;/p&gt;

&lt;h3&gt;
  
  
  Our CI/CD pipeline
&lt;/h3&gt;

&lt;p&gt;Through the next tutorials, we are going to implement following pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;GitHub Action&lt;/em&gt; will be triggered on new code commit&lt;/li&gt;
&lt;li&gt;Action will prepare the environment for pulling your repository&lt;/li&gt;
&lt;li&gt;It will compile your system and run tests inside this environment&lt;/li&gt;
&lt;li&gt;Deploy system to Kubernetes cluster on your local machine&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5m7vhy25aiwvjzkweelj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5m7vhy25aiwvjzkweelj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  CI/CD stack
&lt;/h3&gt;

&lt;p&gt;As you might guess, there are many tools that help you reach those goals. Our stack will use following technologies:&lt;/p&gt;

&lt;h4&gt;
  
  
  Kubernetes
&lt;/h4&gt;

&lt;p&gt;Open-source container orchestration system that enables you to automate containerized application deployment, scaling, and management. You can install it from &lt;a href="https://kubernetes.io/docs/tasks/tools/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Minikube
&lt;/h4&gt;

&lt;p&gt;Kubernetes cluster contains master and worker nodes running on different machines. Deploying those kind of system would be overkill for your daily development work.&lt;br&gt;
Minikube enables you to run a single-node Kubernetes cluster right on your development PC.&lt;/p&gt;

&lt;h4&gt;
  
  
  GitHub
&lt;/h4&gt;

&lt;p&gt;We will trigger code compilation and testing with the &lt;em&gt;GitHub Actions&lt;/em&gt;. You will need a GitHub account&lt;/p&gt;

&lt;h4&gt;
  
  
  ngrok
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;GitHub Actions&lt;/em&gt; will deploy system on Kubernetes cluster running on your development machine. You probably don't have your PC accessible from outside. &lt;br&gt;
&lt;em&gt;ngrok&lt;/em&gt; is a free tunneling system to expose your local services externally.&lt;br&gt;
You can create a free account from official &lt;a href="https://ngrok.com/" rel="noopener noreferrer"&gt;ngrok&lt;/a&gt; site&lt;/p&gt;

&lt;h4&gt;
  
  
  Helm
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://helm.sh/docs/intro/install/" rel="noopener noreferrer"&gt;Package manager&lt;/a&gt; for Kubernetes.&lt;/p&gt;

&lt;h3&gt;
  
  
  WHAT ARE WE CI/CD-ing?
&lt;/h3&gt;

&lt;p&gt;Note that focus won't be application per se as we're deep diving into CI/CD, but let's describe it anyway. &lt;br&gt;
You could use CI/CD template described in this tutorial for any kind of application, regardless of programming language (with a minor adoption)&lt;/p&gt;

&lt;p&gt;Our project will be &lt;em&gt;Tracking Service Platform&lt;/em&gt; made of three parts:&lt;/p&gt;

&lt;h4&gt;
  
  
  API Microservice
&lt;/h4&gt;

&lt;p&gt;API receives events which contain two-piece information: user account and any arbitrary data. &lt;br&gt;
When the event arrives at our almighty API, it checks the account status that can be active, disabled or non-existing.&lt;br&gt;
If account is active (found in database with active status) then some interesting things happen - it broadcasts it to subscribers.&lt;/p&gt;

&lt;h4&gt;
  
  
  Mosquitto
&lt;/h4&gt;

&lt;p&gt;Broadcasting events to subscribers lead us to need for some kind of publisher/subscriber system. &lt;br&gt;
The middleman between API and clients is Mosquitto - message broker which implements MQTT protocol.&lt;/p&gt;

&lt;h4&gt;
  
  
  Clients
&lt;/h4&gt;

&lt;p&gt;Those can be different types of clients that receive published events. In our case, it's a console application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwyu0rjtb6qygj2c4o3bn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwyu0rjtb6qygj2c4o3bn.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
The code is hosted on &lt;a href="https://github.com/tvinko/TrackingServicePlatform" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; where each CI/CD step will be explained in the next tutorials.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Flex Tables In Vertica</title>
      <dc:creator>Tomaž Vinko</dc:creator>
      <pubDate>Fri, 16 Jul 2021 11:56:20 +0000</pubDate>
      <link>https://dev.to/tvinko/flex-tables-in-vertica-2nai</link>
      <guid>https://dev.to/tvinko/flex-tables-in-vertica-2nai</guid>
      <description>&lt;h1&gt;
  
  
  Vertica Analytics Platform
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Column-oriented Vertica Analytics Platform was designed to manage large, fast-growing volumes of data and provide very fast query performance when used for data warehouses and other query-intensive applications.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This Wikipedia citation was enough for me to start exploring the Vertica database.&lt;/p&gt;

&lt;p&gt;After my journey into the realm of Vertica, I found great support for machine learning, efficient columnar storage, great performance and Flex Tables among others.&lt;/p&gt;

&lt;p&gt;I found the latter one very interesting, so let's dive into it.&lt;/p&gt;

&lt;h1&gt;
  
  
  What are Flex Tables
&lt;/h1&gt;

&lt;p&gt;Flex Tables are nothing more than flexible tables :)&lt;br&gt;
They are different kinds of database tables, designed for loading and querying unstructured data.&lt;br&gt;
Flex tables can contain only unstructured, raw data, or both unstructured and columnar data.&lt;br&gt;
 You can create a flex table with or without a schema or real columns. Hybrid tables consist of both unstructured and real columns.&lt;/p&gt;
&lt;h1&gt;
  
  
  Let's get our hands dirty
&lt;/h1&gt;

&lt;p&gt;If you don't have Vertica already, &lt;a href="//www.vertica.com/download/vertica"&gt;grab free version&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I run queries in &lt;a href="https://www.dbvis.com/"&gt;DbVisualizer&lt;/a&gt;, but you can also use other Vertica compatible tools.&lt;/p&gt;

&lt;p&gt;We'll import 1 million records from the CSV file into Flex Table.&lt;br&gt;
First, download and extract the &lt;a href="https://github.com/tvinko/VerticaFlexTables/releases"&gt;SalesRecords.zip&lt;/a&gt; archive.&lt;/p&gt;

&lt;p&gt;Then create flex table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;FLEX&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;csv_hello_world&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We created two tables with the previous command.&lt;br&gt;
First one is flex table &lt;em&gt;csv_hello_world&lt;/em&gt; and the second one is auto generated &lt;em&gt;normal&lt;/em&gt; table &lt;em&gt;csv_hello_world_keys&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;csv_hello_world_keys&lt;/em&gt; table contains three columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;key_name: The name of the virtual column (key).&lt;/li&gt;
&lt;li&gt;frequency: The number of times the key occurs in the map.&lt;/li&gt;
&lt;li&gt;data_type_guess: The type guess that the helper functions determine for each distinct key in the map data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll need to use &lt;em&gt;COMPUTE_FLEXTABLE_KEYS&lt;/em&gt; to calculate this information for the flex keys table columns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;compute_flextable_keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'csv_hello_world'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's fire query command to see the content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;csv_hello_world_keys&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As expected, the table is empty. We didn't import our CSV yet, so the function doesn't have any information for type guessing.&lt;/p&gt;

&lt;p&gt;Import CSV with following statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; &lt;span class="n"&gt;csv_hello_world&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="s1"&gt;'/home/dbadmin/docker/data/SalesRecords.csv'&lt;/span&gt; &lt;span class="n"&gt;PARSER&lt;/span&gt; &lt;span class="n"&gt;fcsvparser&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change file path to your local path where you extracted the archive. I'm running Vertica in docker so this is mapped to my host machine.&lt;/p&gt;

&lt;p&gt;Now run &lt;em&gt;COMPUTE_FLEXTABLE_KEYS&lt;/em&gt; command again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;compute_flextable_keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'csv_hello_world'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and check csv_hello_world_keys table for updated keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;csv_hello_world_keys&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Voila, we have columns information now:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k8vKL5ns--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0zhaxxmimy34g27u9msz.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k8vKL5ns--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0zhaxxmimy34g27u9msz.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we query our &lt;em&gt;csv_hello_world&lt;/em&gt; table, we'll see two columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;identity&lt;/strong&gt; which is just auto increment field&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;raw&lt;/strong&gt; binary column that stores loaded data
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sTRFW8yE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hm6nze1rnkfb8m01slof.PNG" alt="Alt Text"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This doesn't help us much. But if we query virtual columns explicitly, we'll get the values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
        &lt;span class="nv"&gt;"Region"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;"Country"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;"Item Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;"Sales Channel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;"Order Priority"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;"Order Date"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;"Order ID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;"Ship Date"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;"Units Sold"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;"Unit Price"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;"Unit Cost"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;"Total Revenue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;"Total Cost"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;"Total Profit"&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;csv_hello_world&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xbxd8_lT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84vwp56fsa9ebypuxdlr.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xbxd8_lT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84vwp56fsa9ebypuxdlr.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Flex tables are just one of the many interesting Vertica features. I encourage you to dive deeper, especially the machine learning part.&lt;br&gt;
SQL script for this tutorial can be found &lt;a href="https://github.com/tvinko/VerticaFlexTables"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>database</category>
      <category>sql</category>
    </item>
    <item>
      <title>Control .NET runtime from native code</title>
      <dc:creator>Tomaž Vinko</dc:creator>
      <pubDate>Thu, 15 Jul 2021 06:06:06 +0000</pubDate>
      <link>https://dev.to/tvinko/control-net-runtime-from-native-code-473f</link>
      <guid>https://dev.to/tvinko/control-net-runtime-from-native-code-473f</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;You can find many examples how to P/Invoke C++ code from C#, but there aren't so many the other way around - calling C# functions from C++.&lt;/p&gt;

&lt;p&gt;There are many advantages of hosting .NET runtime from C++, but the main two I deal with in real life are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's not mandatory for the customer to have installed .NET Core. NET Core can be shipped within your application so you can control the version&lt;/li&gt;
&lt;li&gt;Second goodie is that you can load heavy work to C++ and not so performance critical to C#. So you have two benefits - power of C++ and coding speed of C#. Of course you can achieve the same with P/Invoke but I like it another way, because I have more control over .NET runtime. But hey, that's just me :)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example is taken from the official dotnet github repository, I just made a few adoptions.&lt;/p&gt;

&lt;p&gt;Code is located &lt;a href="https://github.com/tvinko/HostWithHostFxr" rel="noopener noreferrer"&gt;here&lt;/a&gt;, so let's dive right into it. &lt;/p&gt;

&lt;h1&gt;
  
  
  C# code
&lt;/h1&gt;

&lt;p&gt;This is managed C# function that we're going to call from C++:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IntPtr&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argLength&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argLength&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InteropServices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SizeOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LibArgs&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;LibArgs&lt;/span&gt; &lt;span class="n"&gt;libArgs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PtrToStructure&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LibArgs&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Hello, world! from &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Lib&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s"&gt; [count: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s_CallCount&lt;/span&gt;&lt;span class="p"&gt;++}&lt;/span&gt;&lt;span class="s"&gt;]"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;PrintLibArgs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;libArgs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;There's nothing fancy about it. It just prints some text (Hello world of course).&lt;br&gt;
But if you look closely, you can see strange parameter type &lt;em&gt;IntPtr&lt;/em&gt;. &lt;br&gt;
You don't see many of those declarations when coding strictly inside the .NET environment. But as soon as you start with languages interoperability, this is your only channel for passing arguments back and forth.&lt;br&gt;
Official explanation is a little boring: &lt;em&gt;A platform-specific type that is used to represent a pointer or a handle.&lt;/em&gt;&lt;br&gt;
You can think of it as the starting position of the memory chunk where the argument is located. &lt;/p&gt;

&lt;p&gt;Some more details for bravest ones: it's internally represented as &lt;em&gt;void*&lt;/em&gt; but exposed as an integer. You can use it whenever you need to store an unmanaged pointer and don't want to use unsafe code.&lt;br&gt;
You don't have to know what void* pointer is atm, but that would be a must when you'll dive deeper into the magic world of languages interoperability by yourself.&lt;/p&gt;

&lt;p&gt;Ok, let's move forward. We have some sanity checks at the start. The size of &lt;em&gt;LibArgs&lt;/em&gt; (structure is explained in following steps) must match the size passed as second argument.&lt;/p&gt;

&lt;p&gt;But the winning line of our function is&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="n"&gt;LibArgs&lt;/span&gt; &lt;span class="n"&gt;libArgs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PtrToStructure&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LibArgs&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Marshal.PtrToStructure&lt;/em&gt; copies (marshals) data from unmanaged block of memory to managed (C#) object.&lt;br&gt;
This is the most crucial part in the whole story. There are some caveats when writing functions that are &lt;em&gt;shared&lt;/em&gt; between languages. &lt;br&gt;
You'll earn some of the hardest memory bugs if you screw up here.&lt;/p&gt;

&lt;p&gt;Let's take a closer look at the &lt;em&gt;LibArgs&lt;/em&gt; structure definition:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;StructLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LayoutKind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sequential&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;LibArgs&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IntPtr&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is fundamental type in C# (and other modern languages). They are simple at the first sight, but can become complicated very fast.&lt;br&gt;
If you stay just inside the .NET environment, you don't have to worry how fields are laid out in memory.&lt;/p&gt;

&lt;p&gt;Let's say that you have a few byte fields, int and short fields and you calculate that struct size is 12 bytes.&lt;br&gt;
No, no, wrong. The fact is that compiler add padding bytes to align data within a struct. The reason is that some CPUs like data to be aligned on address boundaries.&lt;br&gt;
Holy s**t, you created the application that crashes randomly.&lt;/p&gt;

&lt;p&gt;But don't worry (or you maybe should with complicated structs), because this padding can be controlled explicitly with &lt;em&gt;StructLayout&lt;/em&gt; attribute:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;StructLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LayoutKind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sequential&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We are using &lt;em&gt;Sequential&lt;/em&gt; enum (this is also the default value).&lt;br&gt;
Compiler will assign structure sequentionaly as listed in the definition. &lt;br&gt;
With &lt;em&gt;Explicit&lt;/em&gt; enum for example, we could specify the size of each field.&lt;/p&gt;

&lt;p&gt;Armed with knowledge till now, it's not hard to figure out what one more interesting line in our application does:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;PtrToStringUni&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;libArgs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's move now to C++ side.&lt;/p&gt;

&lt;h1&gt;
  
  
  C++ code
&lt;/h1&gt;

&lt;p&gt;There are few steps before starting with C# interaction.&lt;/p&gt;

&lt;h3&gt;
  
  
  Load HostFxr
&lt;/h3&gt;

&lt;p&gt;First step is to load &lt;em&gt;HostFxr&lt;/em&gt; and get pointers to a few functions that we're gonna need. &lt;br&gt;
Those are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hostfxr_initialize_for_runtime_config: initializes a host context and prepares for initialization of the .NET Core runtime&lt;/li&gt;
&lt;li&gt;hostfxr_get_runtime_delegate: gets a delegate for runtime functionality&lt;/li&gt;
&lt;li&gt;hostfxr_close: closes a host context
```cpp
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;bool load_hostfxr()&lt;br&gt;
{&lt;br&gt;
    // Pre-allocate a large buffer for the path to hostfxr&lt;br&gt;
    char_t buffer[MAX_PATH];&lt;br&gt;
    size_t buffer_size = sizeof(buffer) / sizeof(char_t);&lt;br&gt;
    int rc = get_hostfxr_path(buffer, &amp;amp;buffer_size, nullptr);&lt;br&gt;
    if (rc != 0)&lt;br&gt;
        return false;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Load hostfxr and get desired exports
void *lib = load_library(buffer);
init_fptr = (hostfxr_initialize_for_runtime_config_fn)get_export(lib, "hostfxr_initialize_for_runtime_config");
get_delegate_fptr = (hostfxr_get_runtime_delegate_fn)get_export(lib, "hostfxr_get_runtime_delegate");
close_fptr = (hostfxr_close_fn)get_export(lib, "hostfxr_close");

return (init_fptr &amp;amp;&amp;amp; get_delegate_fptr &amp;amp;&amp;amp; close_fptr);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;It's worth to mention that the function *get_hostfxr_path* locates the right hostfxr which is then loaded with *load_library* call.
You can also load it from your custom location. But let's just keep things simple for now.

###Initialize &amp;amp; start the .NET Core runtime
Now we need to get a runtime delegate that allows loading a managed assembly.
```cpp


const string_t config_path = root_path + STR("DotNetLib.runtimeconfig.json");
    load_assembly_and_get_function_pointer_fn load_assembly_and_get_function_pointer = nullptr;
    load_assembly_and_get_function_pointer = get_dotnet_load_assembly(config_path.c_str());
    assert(load_assembly_and_get_function_pointer != nullptr &amp;amp;&amp;amp; "Failure: get_dotnet_load_assembly()");


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Load managed assembly and get function pointer to a managed method
&lt;/h3&gt;

&lt;p&gt;Now it's time to load our managed library and get a function pointer to the managed Hello method.&lt;br&gt;
To do this, we need few information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;assembly path&lt;/li&gt;
&lt;li&gt;type name&lt;/li&gt;
&lt;li&gt;method name
```cpp
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;const string_t dotnetlib_path = root_path + STR("DotNetLib.dll");&lt;br&gt;
const char_t &lt;em&gt;dotnet_type = STR("DotNetLib.Lib, DotNetLib");&lt;br&gt;
const char_t *dotnet_type_method = STR("Hello");&lt;br&gt;
// &lt;br&gt;
// Function pointer to managed delegate&lt;br&gt;
component_entry_point_fn hello = nullptr;&lt;br&gt;
int rc = load_assembly_and_get_function_pointer(&lt;br&gt;
    dotnetlib_path.c_str(),&lt;br&gt;
    dotnet_type,&lt;br&gt;
    dotnet_type_method,&lt;br&gt;
    nullptr /*delegate_type_name&lt;/em&gt;/,&lt;br&gt;
    nullptr,&lt;br&gt;
    (void**)&amp;amp;hello);&lt;br&gt;
// &lt;br&gt;
assert(rc == 0 &amp;amp;&amp;amp; hello != nullptr &amp;amp;&amp;amp; "Failure: load_assembly_and_get_function_pointer()");&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;### Run managed code
Finally! It's time to fire our Hello World managed function.
```cpp


for (int i = 0; i &amp;lt; 3; ++i)
{
    // &amp;lt;SnippetCallManaged&amp;gt;
    lib_args args
    {
        STR("from host!"),
        i
    };

    hello(&amp;amp;args, sizeof(args));
    // &amp;lt;/SnippetCallManaged&amp;gt;
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And here is the result of our hard work&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6obidgm3tznsxzx6169v.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6obidgm3tznsxzx6169v.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Although the result of this tutorial isn't much - black screen with Hello World text, you can just imagine the possibilities that opens up.&lt;/p&gt;

&lt;p&gt;You can also check my &lt;a href="https://dev.to/tvinko/languages-interoperability-406f"&gt;Languages Interoperability&lt;/a&gt; project that seamlessly combines different programming languages.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>cpp</category>
      <category>interoperability</category>
    </item>
    <item>
      <title>The Power Of Power BI</title>
      <dc:creator>Tomaž Vinko</dc:creator>
      <pubDate>Tue, 06 Jul 2021 05:44:17 +0000</pubDate>
      <link>https://dev.to/tvinko/the-power-of-power-bi-4ko7</link>
      <guid>https://dev.to/tvinko/the-power-of-power-bi-4ko7</guid>
      <description>&lt;p&gt;Power BI is a tool for data modeling and visualisation. &lt;br&gt;
It can connect to various sources like SQL Server, Vertica, Business Central etc.&lt;/p&gt;

&lt;p&gt;But what most impressed me is the web data source. It's basically a web scraper that can extract tables from web pages. This is a very powerful feature which allows you to bring data from web pages that you can visualise and model along with your data warehouse source.&lt;/p&gt;

&lt;p&gt;Let’s see Power BI in action on a stock market data example.&lt;br&gt;
We are going to import tables from &lt;a href="https://www.barchart.com/stocks"&gt;this page&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don’t have it already, download &lt;a href="https://powerbi.microsoft.com/en-us/downloads/"&gt;free Power BI desktop version&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Launch Power BI, click on Get data and find Web data source&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OTS6_LO3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ytmhz8hemzvee1c8fjv5.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OTS6_LO3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ytmhz8hemzvee1c8fjv5.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter url &lt;a href="https://www.barchart.com/stocks"&gt;https://www.barchart.com/stocks&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hm44avkF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kxc83btb1yujccwkgsr5.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hm44avkF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kxc83btb1yujccwkgsr5.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select table and click Load&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NaGddBaE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9676ysth9maof27auoqz.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NaGddBaE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9676ysth9maof27auoqz.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Visualise and model data&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VbbzWitn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bkny049e8kvejz4og0ig.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VbbzWitn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bkny049e8kvejz4og0ig.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Languages Interoperability</title>
      <dc:creator>Tomaž Vinko</dc:creator>
      <pubDate>Mon, 22 Mar 2021 08:28:38 +0000</pubDate>
      <link>https://dev.to/tvinko/languages-interoperability-406f</link>
      <guid>https://dev.to/tvinko/languages-interoperability-406f</guid>
      <description>&lt;h1&gt;
  
  
  Table Of Contents
&lt;/h1&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    * Introduction to Visual Microservices&lt;br&gt;
    * Environment Setup&lt;br&gt;
    * Executing Algonia project&lt;br&gt;
    * Project description&lt;br&gt;
    * Conclusion&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Introduction to Visual Microservices &lt;a&gt;&lt;/a&gt;&lt;br&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Modern world challenges
&lt;/h2&gt;

&lt;p&gt;The requirements and expectations of the modern world drive us to the point where specialists from different fields must collaborate and work in tandem.&lt;/p&gt;

&lt;p&gt;Software engineers are focused on developing backends and UI engineers on designing applications. Data scientists and analysts are gathering and analyzing data. System integrators are implementing solutions in end customer environments.&lt;/p&gt;

&lt;p&gt;The specialists mostly use different and incompatible technologies as there is no one that rules them all.&lt;/p&gt;

&lt;p&gt;Python is the most sought-after among data professionals because it provides an environment for easily setting up foundations for Machine and Deep learning. Software engineers may prefer C# which has great support for developing multithreaded applications. On the other hand, C/C++  and Rust are very good at solving performance bottlenecks. &lt;/p&gt;

&lt;h2&gt;
  
  
  Algonia vision
&lt;/h2&gt;

&lt;p&gt;Algonia's vision is to overcome those technology barriers and create tool for smooth collaboration between different technical profiles.&lt;/p&gt;

&lt;p&gt;The first step onward to accomplish this goal is ensuring interoperability between programming languages. &lt;/p&gt;

&lt;p&gt;Data scientists must be able to seamlessly share their algorithms and models with Software Engineers. On the other hand Software Engineers must provide data sources to data scientists. &lt;br&gt;
UI engineers must be able to flawlessly integrate developed designs with backends, without much of concern about technology powering the backend.&lt;/p&gt;

&lt;p&gt;Another problem is that complex systems are hard to maintain. Software is a living creature, constantly developed and driven by new requirements that can easily break existing codebase. Sometimes new features just cannot be added due to current codebase foundations.&lt;/p&gt;

&lt;p&gt;Lets see how Algonia deals with those problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Language interoperability
&lt;/h3&gt;

&lt;p&gt;Everyone who has ever worked on a system that involves a mix of different languages and technologies can witness that project can easily turn into a nightmare. Calling functions from one language to another can easily lead to improper memory releasing causing hard-to-find bugs, memory leaks and crashes. &lt;br&gt;
Algonia’s main advantage is a solution where engineers can easily pack their code into drag'n droppable visual boxes. Once packed, they become a part of the existing ecosystem. They can be connected to other algorithms in any order, regardless of programming language.&lt;br&gt;
Many programming languages are supported and new ones are adding constantly. &lt;/p&gt;

&lt;h3&gt;
  
  
  Easy maintenance
&lt;/h3&gt;

&lt;p&gt;Visual programming languages offer easy maintenance and there is no exception here. Visual boxes can be re-connected, deleted from and added to visual workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;p&gt;If you used some of the visual programming tools already, then you know that performance was sacrificed for that benefit. &lt;br&gt;
Algonia is lightning fast and low memory usage on-premise environment that executes visual workflows. It is by far the most powerful visual programming language ever created, with more raw processing horsepower than anything available at any price.&lt;/p&gt;

&lt;h3&gt;
  
  
  For non developers
&lt;/h3&gt;

&lt;p&gt;System integrators, end users and other non-developers can create new functionality by purchasing visual boxes from the marketplace and connecting them into existing workflows. &lt;/p&gt;

&lt;h1&gt;
  
  
  Setting up Algonia Environment
&lt;/h1&gt;

&lt;p&gt;An introductory example will be an application for displaying charts of the historical stock prices.&lt;/p&gt;

&lt;p&gt;Architecture, demonstrated on practical Stock Prices project could serve for other projects, even larger ones. Of course you can adopt it also to your needs.&lt;/p&gt;

&lt;p&gt;C# is going to be used for fetching data from api, Python for creating charts and JS/HTML for designing user interface. &lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Make sure you have met following requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows or MacOS&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/downloads" rel="noopener noreferrer"&gt;Git&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VS Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.python.org/downloads/" rel="noopener noreferrer"&gt;Python 36, 37 or 38&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dotnet.microsoft.com/download/dotnet/3.1" rel="noopener noreferrer"&gt;NetCore 3.1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.alphavantage.co/support/#api-key" rel="noopener noreferrer"&gt;Alpha Vantage api key&lt;/a&gt;. It's for free. We’ll use this API for getting Stock prices.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Environment setup &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Clone StockPrices project
&lt;/h3&gt;

&lt;p&gt;Open command prompt and type command &lt;br&gt;
&lt;em&gt;git clone &lt;a href="https://github.com/tvinko/algonia.git" rel="noopener noreferrer"&gt;https://github.com/tvinko/algonia.git&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
Go to the repository folder after cloning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install Python Packages
&lt;/h3&gt;

&lt;p&gt;We’ll use &lt;strong&gt;virtualenv&lt;/strong&gt; to install Python packages. There are many benefits of using virtualenv for package management. It really shines in an environment with many projects that don’t share the same Python installation. This way we solve conflicting requirements.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Run &lt;em&gt;virtualenv --version&lt;/em&gt; command to check if you have installed virtualenv.&lt;br&gt;
If you don’t have it then install it with command &lt;em&gt;pip install virtualenv&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next step is to create a virtual environment with the name &lt;strong&gt;venv_38&lt;/strong&gt;. Run the &lt;em&gt;python --version&lt;/em&gt; command to check your python default version.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then run the command according to your default Python version &lt;br&gt;
&lt;em&gt;virtualenv venv_38 --python=python3.8&lt;/em&gt;&lt;br&gt;
&lt;em&gt;virtualenv venv_37 --python=python3.7&lt;/em&gt;&lt;br&gt;
&lt;em&gt;virtualenv venv_38 --python=python3.6&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This command will create a new folder in your project root:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ycxfp4h8kofxelo171u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ycxfp4h8kofxelo171u.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Activate virtual environment with &lt;em&gt;.\venv_38\Scripts\activate&lt;/em&gt; &lt;br&gt;
(Windows)  or &lt;br&gt;
&lt;em&gt;source venv_38/bin/activate&lt;/em&gt; (macos) command&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install packages from requirements: &lt;em&gt;pip install -r requirements.txt&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now the packages are installed in your virtual, isolated python environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Download Algonia Bundle
&lt;/h3&gt;

&lt;p&gt;Download &lt;strong&gt;Algonia Bundle&lt;/strong&gt; from  &lt;a href="https://github.com/tvinko/algonia/releases" rel="noopener noreferrer"&gt;github repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Windows&lt;/strong&gt;&lt;br&gt;
Use the latest release and extract &lt;strong&gt;algonia-bundle-win64.zip&lt;/strong&gt; to your repository folder. &lt;br&gt;
Your folder structure should now look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3guo1a0flwlycj6ikvjp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3guo1a0flwlycj6ikvjp.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MacOS&lt;/strong&gt;&lt;br&gt;
Download &lt;strong&gt;algonia-bundle-macos.zip&lt;/strong&gt;, extract it and drag &lt;strong&gt;algonia-designer&lt;/strong&gt; to your &lt;strong&gt;Applications&lt;/strong&gt; folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project structure description
&lt;/h2&gt;

&lt;p&gt;First and foremost, the weapon of choice here is VSCode because of its versatility. It is a source code editor that can be used with a variety of programming languages and supports multiple platforms such as Linux, Windows, and macOS.&lt;/p&gt;

&lt;h3&gt;
  
  
  algonia-bundle-win64 / algonia-bundle-macos
&lt;/h3&gt;

&lt;p&gt;Bundle contains a &lt;strong&gt;development tool&lt;/strong&gt; (IDE) for gluing your algorithms (Algonia Visual Designer) and an &lt;strong&gt;environment&lt;/strong&gt; for executing visual scripts (Algonia Engine).&lt;br&gt;
Algonia Visual Designer contains (among other things) bundled .NET Core SDK, so it doesn't have to be installed on production environment. However, it must be installed on development machine.&lt;/p&gt;

&lt;p&gt;When you ship your project to customers, you’ll create a package. This is a lightweight executing environment containing only Algonia Engine, without Algonia Designer. &lt;/p&gt;

&lt;p&gt;Using your own .NET Core version and creating Algonia Engine packages will be explained in the following tutorials.&lt;/p&gt;

&lt;h3&gt;
  
  
  algos
&lt;/h3&gt;

&lt;p&gt;Your team’s projects. Stock Prices contains three projects. They are located in &lt;em&gt;algos&lt;/em&gt; directory of repository:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python project for graphs imaging &lt;em&gt;algos/py/graphs/plot_graph.py&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;NetCore project for fetching data from api &lt;em&gt;algos/netcore/StockPrices/StockPrices.csproj&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;HTML/Js for user interface &lt;em&gt;algos/html/assets&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those projects will be glued together in &lt;strong&gt;Algonia Visual Designer&lt;/strong&gt; and executed by &lt;strong&gt;Algonia Engine&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  templates
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Algonia Visual Designer&lt;/strong&gt; projects are called &lt;strong&gt;visual templates&lt;/strong&gt; - drawing canvases for connecting your projects. Templates folder contains those Algonia Visual Designer projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  venv_36/venv_37/venv_38
&lt;/h3&gt;

&lt;p&gt;Python packages, required for the Stock Prices project.&lt;/p&gt;

&lt;h3&gt;
  
  
  requirements.txt
&lt;/h3&gt;

&lt;p&gt;Python requirements file&lt;/p&gt;

&lt;h3&gt;
  
  
  sync.bat / sync.sh
&lt;/h3&gt;

&lt;p&gt;Scripts for synchronizing your teams and 3rd party projects with &lt;strong&gt;Algonia Designer&lt;/strong&gt;. Use &lt;strong&gt;sync.bat&lt;/strong&gt; on Windows and &lt;strong&gt;sync.sh&lt;/strong&gt; on MacOS systems.&lt;br&gt;
Algonia Designer "glues" your project results (&lt;em&gt;.dll, *.so., *.py, *.js,&lt;/em&gt;.html and similar files).&lt;br&gt;
When you compile code in your preferred IDE (VisualStudio Code, Visual Studio...) the library is normally created in the bin folder of your project which is out of Algonia Designer reach. &lt;br&gt;
Those scripts synchronize your libraries with Algonia Designer.&lt;br&gt;
The rule of thumb is: run sync script when you make changes outside of Algonia Designer (in VS Code or your preferred IDE)&lt;/p&gt;

&lt;h1&gt;
  
  
  Executing Algonia project&lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Compile StockPrices project (C#)
&lt;/h3&gt;

&lt;p&gt;Open algonia.code-workspace in VSCode.&lt;br&gt;
Click on &lt;strong&gt;CTRL+Shift+B&lt;/strong&gt; (Win) or &lt;strong&gt;Shift+Command+B&lt;/strong&gt; (MacOS) to get a list of build tasks and select &lt;strong&gt;StockPricesTest&lt;/strong&gt; project. &lt;/p&gt;

&lt;h3&gt;
  
  
  Sync libraries and Algonia Designer
&lt;/h3&gt;

&lt;p&gt;Synchronize .Net Core library with Algonia Designer by executing sync.bat/sync.sh script. Script will also synchronize our Python and HTML files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set python virtual environment packages
&lt;/h3&gt;

&lt;p&gt;You need to set the location to virtualenv packages so that Algonia Engine will add it to it’s packages path.&lt;/p&gt;

&lt;p&gt;Open algonia-designer.&lt;br&gt;
On Windows navigate to the algonia-bundle-win64 folder and click on algonia-designer executable to launch Algonia Designer.&lt;/p&gt;

&lt;p&gt;On MacOS go to Applications and open algonia-designer. On the first run you’ll get following warning:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrqwr8ngaa78bxvzwfdy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrqwr8ngaa78bxvzwfdy.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on &lt;em&gt;Cancel&lt;/em&gt;, navigate to &lt;em&gt;Security &amp;amp; Privacy -&amp;gt; General&lt;/em&gt; and click &lt;em&gt;Open Anyway&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Click on the &lt;em&gt;Project&lt;/em&gt; menu tab and select &lt;em&gt;Open&lt;/em&gt;. Navigate to the &lt;em&gt;templates/StockPrices&lt;/em&gt; folder  of your cloned repository and select &lt;em&gt;StockPrices.algo&lt;/em&gt; to open the Algonia project.&lt;/p&gt;

&lt;p&gt;Packages are located in the &lt;em&gt;site-packages&lt;/em&gt; directory. &lt;br&gt;
On Mac this is normally in your cloned repository under  &lt;em&gt;StockPrices/venv_38/lib/python3.8/site-packages&lt;/em&gt; and on Windows &lt;em&gt;venv_38\Lib\site-packages&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Click on the &lt;em&gt;Settings&lt;/em&gt; tab, select &lt;em&gt;Open&lt;/em&gt; and enter &lt;strong&gt;full&lt;/strong&gt; path to the packages:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpt05u46mp7z1bqkf0fvx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpt05u46mp7z1bqkf0fvx.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Set Alpha Vantage api key
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Alpha Vantage API&lt;/em&gt; is used to fetch Stock prices.&lt;/p&gt;

&lt;p&gt;Select &lt;em&gt;PRICES_OBJECT&lt;/em&gt; visual box:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsa9dnn8yc9ef8e500pju.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsa9dnn8yc9ef8e500pju.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the &lt;em&gt;Add args&lt;/em&gt; in the properties window:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbvzuvunh75x4y6ji7vrj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbvzuvunh75x4y6ji7vrj.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter your API key in the value field of &lt;em&gt;API_KEY&lt;/em&gt; property&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2fvwucl1832cgbvcte7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2fvwucl1832cgbvcte7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the &lt;em&gt;Save&lt;/em&gt; button&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhr4zk4dqo8ff6dmqd9i9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhr4zk4dqo8ff6dmqd9i9.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;em&gt;Project&lt;/em&gt; and &lt;em&gt;Save&lt;/em&gt; to save the project. You can also use shortcut &lt;em&gt;CTRL+S&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set Python version if needed
&lt;/h3&gt;

&lt;p&gt;Project is currently set for the Python 3.8 environment. If you’re using Python 3.6 or 3.7 then the version must be set on Python visual boxes. &lt;br&gt;
Select &lt;em&gt;GUI&lt;/em&gt; visual box and change Python version:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Funwhjedbq31rnfnpivgu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Funwhjedbq31rnfnpivgu.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select &lt;em&gt;SAVE_GRAPH&lt;/em&gt; visual box and repeat procedure. &lt;br&gt;
Click on the &lt;em&gt;Project&lt;/em&gt; menu item and click on &lt;em&gt;Save&lt;/em&gt; to save the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Run project
&lt;/h3&gt;

&lt;p&gt;Press F5 to run the application and open main application window&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnnsq5tjy7crn06yzj266.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnnsq5tjy7crn06yzj266.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
Click on the &lt;em&gt;Draw Graph&lt;/em&gt; button&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fztrnlonbdqxtcoppbcdj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fztrnlonbdqxtcoppbcdj.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can change the value from MSFT to let's say ETH and see the result.&lt;/p&gt;

&lt;h1&gt;
  
  
  Project description &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;In the main project window you’ll see green boxes, some of them connected and some of them just floating around:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwjcsn0ask6fi68s0wwi7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwjcsn0ask6fi68s0wwi7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
Those boxes are wrappers around our C# and Python projects.&lt;/p&gt;

&lt;p&gt;For example, &lt;em&gt;SET_SYMBOL&lt;/em&gt; visual box calls C# function &lt;em&gt;ChangeSymbol&lt;/em&gt; from &lt;em&gt;StockPrices&lt;/em&gt; project (&lt;strong&gt;algos\netcore\StockPrices&lt;/strong&gt;):&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3wzvq2cbiz7f8u0hdupw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3wzvq2cbiz7f8u0hdupw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the &lt;em&gt;GET_PRICES&lt;/em&gt; visual box calls function &lt;em&gt;GetPrices&lt;/em&gt; from the same solution.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;SAVE_GRAPH&lt;/em&gt; visual box for instance calls &lt;em&gt;plotGraph&lt;/em&gt; method from Python project (&lt;strong&gt;algos\py\graphs\plot_graph.py&lt;/strong&gt;):&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3oa148mkm4br9kcjzs37.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3oa148mkm4br9kcjzs37.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Confused? How can “visual box” just call the function from our, or someone else’s project? Create an object instance? &lt;br&gt;
Don’t worry, it’s going to be explained in the next sections.&lt;/p&gt;

&lt;p&gt;But I hope that you briefly got some clue at this point: projects created with different technologies and programming languages can be glued together inside &lt;strong&gt;Algonia Designer&lt;/strong&gt;. You can connect them in any meaningful order you want. &lt;/p&gt;

&lt;p&gt;Now, let’s rewind to the beginning and take a look at the first row of the boxes:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo7jvdufk6n6vn4uvjqke.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo7jvdufk6n6vn4uvjqke.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Start box
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Start&lt;/em&gt; box is the entry point to our application. Applications can have multiple entry points running in parallel, but there is no need for this in our Stock Prices project.&lt;/p&gt;

&lt;h2&gt;
  
  
  PRICES_OBJECT
&lt;/h2&gt;

&lt;p&gt;Next, &lt;em&gt;PRICES_OBJECT&lt;/em&gt; box, creates an object from the &lt;em&gt;StockPrices&lt;/em&gt; class defined in &lt;strong&gt;algos/netcore/StockPrices/StockPrices.csproj&lt;/strong&gt; project.&lt;/p&gt;

&lt;p&gt;Select the box and click on the &lt;em&gt;Add code&lt;/em&gt; button in it’s properties window:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9i68worcevme0l3fld37.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9i68worcevme0l3fld37.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is ordinal C# code, with some extensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In &lt;strong&gt;header&lt;/strong&gt; section we reference C# dlls and write using directives &lt;/li&gt;
&lt;li&gt;Code is written in the &lt;strong&gt;code&lt;/strong&gt; section. Tags containing attribute &lt;strong&gt;run&lt;/strong&gt; with value &lt;strong&gt;true&lt;/strong&gt; are entry points to visual boxes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rest of the code should  look familiar to you. Except for the two functions, &lt;strong&gt;get_arg&lt;/strong&gt; and &lt;strong&gt;set_result&lt;/strong&gt;.&lt;br&gt;
Those two functions are part of the &lt;strong&gt;Algonia SDK&lt;/strong&gt; and their purpose is to control visual boxes and workflows. There are few more functions for that purpose and will be explained later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;get_arg&lt;/strong&gt;&lt;br&gt;
this function receives the argument key and returns it’s value. We can set those arguments programmatically or through Algonia Designer user interface. In fact you already set argument on Algonia Designer UI when you set your API key:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F515osla37qs5lpjl57ec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F515osla37qs5lpjl57ec.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;set_result&lt;/strong&gt; &lt;br&gt;
this function takes an object and saves it into the current &lt;em&gt;Visual Box&lt;/em&gt;. Each &lt;em&gt;Visual Box&lt;/em&gt; can store some result that is accessible to other &lt;em&gt;Visual Boxes&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  GUI Box
&lt;/h2&gt;

&lt;p&gt;This is a Python visual box containing a user interface. It uses the Python Eel package for making Electron-like offline HTML/JS GUI apps. I’m not going into Eel details as this would be out of scope for our tutorial, but I strongly recommend that you check it out &lt;a href="https://martin-thoma.com/eel/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The wrapper code inside Visual Box is:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa1x84rvihu7ufogjx6z6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa1x84rvihu7ufogjx6z6.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s just go through a few interesting points.&lt;br&gt;
&lt;strong&gt;def registerGui(self)&lt;/strong&gt;&lt;br&gt;
Entry point to Visual Box is &lt;em&gt;registerGui&lt;/em&gt; function, set in it’s properties window:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ka0hx4e69zmsqz1rw4f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ka0hx4e69zmsqz1rw4f.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This function starts gui with &lt;em&gt;main.html&lt;/em&gt;. This is Eel’s way of starting UI: &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcbo4by1un8kn9l7i1ro5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcbo4by1un8kn9l7i1ro5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;def getPricesRequest(symbol)&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcrm2zcyec3s7uf0dcmey.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcrm2zcyec3s7uf0dcmey.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Algonia SDK functions here are:&lt;br&gt;
&lt;strong&gt;algonia_helpers.set_element_arg&lt;/strong&gt;&lt;br&gt;
sets the value of the visual box’s argument. First parameter is the name of the visual box that argument is set and the second parameter is it’s value (besides storing results, visual boxes can also store arguments).&lt;/p&gt;

&lt;p&gt;This function is exposed to Javascript with &lt;em&gt;eel.expose&lt;/em&gt; attribute.&lt;br&gt;
It receives a Stock symbol parameter from html input and it’s called by jQuery (we’ll get to HTML and jQuery part later).&lt;br&gt;
The call to &lt;strong&gt;set_element_arg&lt;/strong&gt; stores this symbol as an argument.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;algonia_helpers.exec&lt;/strong&gt;  executes Visual Box and all chained boxes connected into the same workflow. The parameter of this function is the visual box name.&lt;/p&gt;

&lt;p&gt;Lets just recap what we just did:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We set the &lt;em&gt;SET_SYMBOL&lt;/em&gt; argument to the current Stock symbol that we got from the user interface and then executed it. &lt;/li&gt;
&lt;li&gt;After &lt;em&gt;SET_SYMBOL&lt;/em&gt; finishes, &lt;em&gt;GET_PRICES&lt;/em&gt; is automatically executed (because those two boxes are visually connected).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzdksztc6ul4hdzgjvxrd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzdksztc6ul4hdzgjvxrd.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;def registerExecNodes(self)&lt;/strong&gt;&lt;br&gt;
There is another Algonia system function, or more precise system callback:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ye1t8au0z59c68u1c5k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ye1t8au0z59c68u1c5k.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All Visual Boxes names, that are executed dynamically with the &lt;strong&gt;algonia_helpers.exec&lt;/strong&gt; method, must be registered and returned as string.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;def saveGraphReuest()&lt;/strong&gt;&lt;br&gt;
This function returns graph image, encoded as base64 string and will be explained in following steps&lt;/p&gt;

&lt;p&gt;Lets go to the next row of Visual Boxes &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9rekdlkk3npro4oujkz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9rekdlkk3npro4oujkz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SET_SYMBOL box
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foli91t3gemvgic2w42yn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foli91t3gemvgic2w42yn.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a new algonia SDK function here that gets the result of Visual Box - &lt;strong&gt;get_result_raw&lt;/strong&gt;.&lt;br&gt;
It takes the name of the box as a parameter.&lt;/p&gt;

&lt;p&gt;Remember, Visual boxes can see each other’s results. &lt;em&gt;StockPrices&lt;/em&gt; object is stored in a &lt;strong&gt;PRICES_OBJECT&lt;/strong&gt; box.&lt;br&gt;
Now we are going to use this object and call the &lt;em&gt;ChangeSymbol&lt;/em&gt; function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;get_element_arg&lt;/strong&gt;  gets the box’s current argument. We set it in previously described eel exposed Python function:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqq52ba9gvw9g8jktu2w3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqq52ba9gvw9g8jktu2w3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GET_PRICES box
&lt;/h2&gt;

&lt;p&gt;This box calls the &lt;em&gt;GetPrices&lt;/em&gt; method. There is nothing new here, as we already described all Algonia SDK functions contained in this box:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7yfpelgabqi6h9dxcwdh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7yfpelgabqi6h9dxcwdh.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lets recap what we did:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;getPricesRequest&lt;/em&gt; Python function is called from Javascript&lt;/li&gt;
&lt;li&gt;This function set the symbol name of the &lt;em&gt;SET_SYMBOL&lt;/em&gt; box argument and executed it&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;SET_SYMBOL&lt;/em&gt; called our C# StockPrices &lt;em&gt;ChangeSymbol&lt;/em&gt; method.&lt;/li&gt;
&lt;li&gt;After the &lt;em&gt;SET_SYMBOL&lt;/em&gt;, &lt;em&gt;GET_PRICES&lt;/em&gt; is executed, because those two boxes are directly connected with virtual wire. &lt;em&gt;GET_PRICES&lt;/em&gt; call our &lt;em&gt;GetPrices&lt;/em&gt; method defined in &lt;em&gt;StockPrices&lt;/em&gt; object&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  SAVE_GRAPH box
&lt;/h3&gt;

&lt;p&gt;Let's move to the last Visual Box. If you open the code, you can see following Python script:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy1zwefruwhf90zq97hxw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy1zwefruwhf90zq97hxw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Visual Box reads result from &lt;em&gt;GET_PRICES&lt;/em&gt; (prices in CSV format):&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjhnlqpy7aaptt1kwilw0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjhnlqpy7aaptt1kwilw0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Interesting part is call to function &lt;em&gt;plotGraph&lt;/em&gt;, which is defined in our &lt;em&gt;plot_graph&lt;/em&gt; Python project and returns an image in base64 string format:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9u550gtiek7witebrupv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9u550gtiek7witebrupv.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image is then shown on UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  User Interface
&lt;/h2&gt;

&lt;p&gt;All six Visual Boxes from Algonia Designer canvas were described, but there is one topic left - User Interface.&lt;/p&gt;

&lt;p&gt;It is located in &lt;strong&gt;libs\algonia\html\assets\main.html&lt;/strong&gt; file.&lt;br&gt;
The Javascript part that communicates with Visual Boxes is:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmq9kbf4ymz04hnjdx0ur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmq9kbf4ymz04hnjdx0ur.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  STEP 1
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Draw Graph&lt;/em&gt; button on the user interface executes &lt;em&gt;eel.getPricesRequest&lt;/em&gt; function and passes currently selected symbol from html input (ETH, MSFT...)&lt;br&gt;
This call is handled by Eel in Python &lt;em&gt;GUI box&lt;/em&gt; that executes &lt;em&gt;SET_SYMBOL&lt;/em&gt; visual box:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6axym9u9eufnjil4wk2t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6axym9u9eufnjil4wk2t.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  STEP 2
&lt;/h3&gt;

&lt;p&gt;Python code executes callback to javascript &lt;em&gt;onGetPricesCompleted&lt;/em&gt; function:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmccpqghlj99a09ieqvna.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmccpqghlj99a09ieqvna.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This function then calls &lt;em&gt;saveGraphRequest&lt;/em&gt; in &lt;em&gt;GUI box&lt;/em&gt;:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqswr6fhr653ftbxhg66c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqswr6fhr653ftbxhg66c.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we execute the &lt;em&gt;SAVE_GRAPH box&lt;/em&gt; to get a base64 encoded image string and call the javascript function &lt;em&gt;onSaveGraphCompleted&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  STEP 3
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;onSaveGraphCompleted&lt;/em&gt; function shows a graph image in &lt;em&gt;divGraph&lt;/em&gt; div&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv4ejl8v2butnik1vtidt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv4ejl8v2butnik1vtidt.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion&lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;We just went through all steps of our Stock Prices example. In real life we should handle exceptions and errors more conveniently. We could also simplify workflow by reconnecting Visual Boxes differently. But the purpose of the introduction tutorial was to show different ways of Visual Boxes execution.&lt;/p&gt;

&lt;p&gt;Main Algonia purpose is technology interoperability, collaboration foundations between different specialists. In our example we used just C# and Python, but of course there are many more choices.&lt;/p&gt;

&lt;p&gt;Algonia also forces loosely coupled and modular architecture from the start. You can easily rearrange visual boxes, adding new and deleting existing ones.&lt;br&gt;
Full blown code including all object oriented goodies can be written right inside Visual Boxes. But the biggest strength of Visual Boxes is that they act like wrappers to your and 3rd party libraries. Libraries are developed independently but their functions are wrapped inside boxes.&lt;br&gt;
Visual Boxes hold their object state - there are not just fire’n’forget function executions.&lt;/p&gt;

&lt;p&gt;And last but not least, system integrators and non-developers can maintain systems on their own by adding or removing Visual Boxes purchased from Algonia Marketplace.&lt;/p&gt;

&lt;p&gt;We are just entering the next era of programming - Visual Microservices.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Visual Microservices</title>
      <dc:creator>Tomaž Vinko</dc:creator>
      <pubDate>Tue, 22 Dec 2020 12:13:31 +0000</pubDate>
      <link>https://dev.to/tvinko/visual-microservices-1m10</link>
      <guid>https://dev.to/tvinko/visual-microservices-1m10</guid>
      <description>&lt;h2&gt;
  
  
  Inheriting dysfunctional code can be nightmare
&lt;/h2&gt;

&lt;p&gt;I frequently struggle with fixing bugs and debugging code that I inherited. The problem is that the code is poorly written,&lt;br&gt;
without programming design principles and many unnecessary duplicate parts of code.&lt;/p&gt;

&lt;p&gt;This made me to start brainstorm what would be an ideal solution. I started thinking outside the box, beyond classic object oriented concepts.&lt;br&gt;&lt;br&gt;
I came up with the idea that reusable parts of code would be in the form of drag'n droppable visual boxes of algorithms that I could connect in any order.&lt;/p&gt;

&lt;p&gt;I could then run those visual boxes from my code by executing first box (some kind of entry point). Complete chain of connected boxes would be executed and last box will return some computed result back to my main application.  &lt;/p&gt;

&lt;p&gt;That will give me simple overview what application does. The other advantage is reusability. I could just connect visual boxes in different order and create different application logic. Without recompiling my codebase. Maintenance would be much easier this way instead of doing changes in spaghetti code.&lt;/p&gt;

&lt;p&gt;There are no Object Oriented Desing Patterns in this direction yet. Or I'm not aware of them. I'm just going to call it Visual Microservices for now.&lt;br&gt;
Visual because they are represented in form of visual boxes.&lt;br&gt;
Microservices because each box represent some isolated, loosely coupled service. &lt;/p&gt;

&lt;h2&gt;
  
  
  Visual programming
&lt;/h2&gt;

&lt;p&gt;Of course Visual Programming is nothing new. But curently there aren't solutions there yet, which would solve real life demands. The problems are mostly interoperability and poor performance.&lt;/p&gt;

&lt;p&gt;Some of the benefits that must be sacrified by using existing Visual Programming tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I don't want that tool use more resources (memory, CPU) than needed. Just firing up an almost empty project created in visual tool takes 50MB of memory. Really??!&lt;/li&gt;
&lt;li&gt;I want to be fast. Let's say that we have two or more connected Visual Microservices. I don't want that transition from one microservice to another takes longer then actual microservice execution.&lt;/li&gt;
&lt;li&gt;I want to include Visual Microservices written in different programming languages. I like coding in C# but the truth is that in some areas, especially in ML, Python has better support. I want to effortlessly include my C# and Python libraries in Visual Microservices. My ideal tool has to support as much as possible different languages, because there is no tool to rule them all.&lt;/li&gt;
&lt;li&gt;Everyone that tells you that a complete solution can be created just with a visual programming tool is a big lie. Yes you can do small projects, but as long  as you have complex real world project, your hands are tied. It's nothing worse than when tool dictate which portion must be used. It might happen that in middle of project you realize it's weaknesses and you must start project from scratch with different technology. So I want that my tool could be easily integrated with my code&lt;/li&gt;
&lt;li&gt;I want to have debugging capabilities. Not just "Console.log()", but a full blown debugger with breakpoints and run time variables inspection.&lt;/li&gt;
&lt;li&gt;I want to share a state between Visual Microservices. I want to share objects - with all their states, properties and functions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My attempt to create "ideal" Visual Tool
&lt;/h2&gt;

&lt;p&gt;As the wish list grows, I decided to make a tool that will overcome all these obstacles. I decided to write my Visual Tool in C because I wanted top-notch performance, portability and support for hosting many different programming languages on the top of it.&lt;/p&gt;

&lt;p&gt;At the moment tool supports :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;C# and Python languages&lt;/li&gt;
&lt;li&gt;Visual Studio and web-pdb integration  for debugging Visual Microservices&lt;/li&gt;
&lt;li&gt;it can be referenced as library from 3rd party code. This gives me ability to seamlessly experience to include my Visual Workflows into projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, tool is hybrid between visual and ordinary programming. Existing or new algorithms can be easily represented and combined visually. For that reason I also created marketplace for exchanging those algorithms.&lt;/p&gt;

&lt;p&gt;I'm going to demonstrate it in the next posts. In meantime, you can check it &lt;a href="https://www.algonia.net/Home/Documentation/project_hello_world"&gt;here&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Happy Coding :)&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>machinelearning</category>
      <category>python</category>
      <category>csharp</category>
    </item>
  </channel>
</rss>
