<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Julia - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Julia - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 29 May 2026 10:35:22 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/julia/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Deep Learning with Julia – How to Build and Train a Model using a Neural Network ]]>
                </title>
                <description>
                    <![CDATA[ By Andrey Germanov Julia is a general purpose programming language well suited for numerical analysis and computational science. Some consider it the future of machine learning and the most natural replacement for Python in this field. In the previou... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/deep-learning-with-julia/</link>
                <guid isPermaLink="false">66d45edb230dff01669057f5</guid>
                
                    <category>
                        <![CDATA[ Deep Learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Julia ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Machine Learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ neural networks ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 07 Mar 2023 21:34:07 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/03/cover-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Andrey Germanov</p>
<p><a target="_blank" href="https://julialang.org/">Julia</a> is a general purpose programming language well suited for numerical analysis and computational science. Some consider it the future of machine learning and the most natural replacement for Python in this field.</p>
<p>In the previous post "<a target="_blank" href="https://www.freecodecamp.org/news/machine-learning-using-julia/">Machine learning with Julia – How to Build and Deploy a Trained AI Model as a Web Service</a>" I introduced the basic machine learning features of Julia and explained why it's so good for this.</p>
<p>In this article, I want to move one step forward and explore deep learning features of Julia to show how you can use it to solve computer vision tasks using neural networks. </p>
<p>Computer vision is one of the most impressive areas of artificial intelligence. It includes such interesting tasks as image classification, text recognition, object detection and image segmentation. Neural networks showed the best performance in solving computer vision problems.</p>
<p>In this tutorial, I will guide you through the process of building and training a neural network to recognize handwritten digits using Julia. I will also explain how to create a website that will use the trained model to read handwritten phone numbers. </p>
<p>Here's what we'll cover:</p>
<ol>
<li><a class="post-section-overview" href="#heading-what-should-you-know-in-advance">What should you know in advance</a></li>
<li><a class="post-section-overview" href="#heading-handwritten-digits-recognition-workflow">Handwritten digits recognition workflow</a></li>
<li><a class="post-section-overview" href="#heading-how-to-collect-initial-image-data">How to collect initial image data</a></li>
<li><a class="post-section-overview" href="#heading-how-to-work-with-images-in-julia">How to work with images in Julia</a></li>
<li><a class="post-section-overview" href="#heading-how-to-prepare-the-image-data-for-machine-learning">How to prepare the image data for machine learning</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-a-machine-learning-model">How to create a machine learning model</a></li>
<li><a class="post-section-overview" href="#heading-how-to-train-the-model">How to train the model</a></li>
<li><a class="post-section-overview" href="#heading-how-to-evaluate-the-accuracy-of-the-trained-model">How to evaluate the accuracy of the trained model</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-and-train-the-convolutional-neural-network">How to create and train the convolutional neural network</a></li>
<li><a class="post-section-overview" href="#how-to-export-the-trained-model-to-a-file">How to export the trained model to a file</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-a-frontend">How to create a frontend</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-a-backend">How to create a backend</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ol>
<h2 id="what-should-you-know-in-advance">What should you know in advance</h2>

<p>This tutorial assumes that you have basic Julia knowledge, that possible to get by reading my <a target="_blank" href="https://www.freecodecamp.org/news/machine-learning-using-julia">previous article</a>. That article also includes instructions on how to install Julia and integrate it with Jupyter notebook, which will be used to write most of the code.</p>
<p>The "Handwritten digit recognition using deep learning" problem and the theory that stands behind it is well known. That is why I will cover it only briefly. There are many good resources that explain how neural networks are used to solve the image classification tasks. Personally, I recommend watching <a target="_blank" href="https://www.youtube.com/watch?v=aircAruvnKk">this video</a> and read the first chapter of this great <a target="_blank" href="http://neuralnetworksanddeeplearning.com/chap1.html">online book</a>. </p>
<p>The goal of this tutorial is only to show you how to implement the theory, explained in those resources, using Julia.</p>
<h2 id="handwritten-numbers-recognition-workflow">Handwritten digits recognition workflow</h2>

<p>To build a machine learning model we will use the <a target="_blank" href="https://fluxml.ai/">Flux.jl</a> framework which is a pure Julia implementation of most well-known neural network types including <a target="_blank" href="https://deepai.org/machine-learning-glossary-and-terms/feed-forward-neural-network">feed forward</a>, <a target="_blank" href="https://deepai.org/machine-learning-glossary-and-terms/convolutional-neural-network">convolutional</a> and <a target="_blank" href="https://deepai.org/machine-learning-glossary-and-terms/recurrent-neural-network">recurrent</a> networks.</p>
<p>Recognizing handwritten numbers is a supervised machine learning task of image classification. To implement it, you need to have a labeled dataset of handwritten digits and use it to train the machine learning model. </p>
<p>This is how the ML workflow looks:</p>
<ul>
<li>Collect the images of handwritten digits for recognition.</li>
<li>Prepare a labeled dataset for machine learning by cleaning and labeling the data.</li>
<li>Create a machine learning model to recognize handwritten digits.</li>
<li>Train the model using training dataset.</li>
<li>Evaluate the accuracy of the trained model by feeding it with data from a testing dataset.</li>
<li>After achieving good accuracy, export the model to a file to use in applications.</li>
</ul>
<h2 id="how-to-collect-initial-image-data">How to collect initial image data</h2>

<p>The first step of any machine learning task is to collect the data that will be used for training. Usually this is the bigger part of the whole process.</p>
<p>How do you collect handwritten digits for this? Well, for example, you can ask all your friends in social networks to write down digits from 0 to 9 and save them to images. They also can ask their friends to do the same and finally send all these images to you. </p>
<p>The more data you collect, the better for machine learning.</p>
<p>Then, you could create folders with names from "0" to "9" and arrange these images within them. Also, you need to convert the images to the same format: convert to grayscale and resize them. All images should have the same size and color format. </p>
<p>Finally, you'll have a labeled collection of handwritten digits that are ready to work with. </p>
<p>Fortunately, you do not need to do all this manual work, because it was already done in 1998 by the National Institute of Standards and Technology. The database of handwritten digits, that called MNIST, is available to download from Kaggle or from many other places. For example, you can download and extract the MNIST archive using <a target="_blank" href="https://www.kaggle.com/datasets/jidhumohan/mnist-png">this link</a>. </p>
<p>This database is already split into testing and training data in appropriate folders. Each of these folders contains images of handwritten digits, classified to folders from "0" to "9". There are 60000 images in the <code>training</code> folder and 10000 images in the <code>testing</code> folder:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/minst.png" alt="Image" width="600" height="400" loading="lazy">
<em>MNIST database images</em></p>
<p>Each file is a 28x28 gray scaled image. We will use the content of the <code>training</code> folder to prepare the dataset for training the neural network model. Then we will use the content of the <code>testing</code> folder to validate the accuracy of the trained model. Before doing that, we need to convert this raw data to datasets.</p>
<p>In order to continue, run the Jupyter notebook and create a new notebook in it, selecting "Julia" as a language. Then, copy the <code>training</code> and <code>testing</code> folders with images to the folder in which you created the notebook.</p>
<h2 id="how-to-work-with-images-in-julia">How to work with images in Julia</h2>

<p>An image is not a natural data format for machine learning models. The models understand only numbers. That is why, to prepare the images for machine learning, you need to load them and convert to numbers. </p>
<p>To work with images in Julia, we will use the <a target="_blank" href="https://juliaimages.org/stable/">Julia Images</a> library. Using this library, you can load the image, convert it to matrix of pixels, and apply different transformations that can be required before pushing it to ML. The transformations include resizing, converting from color to black and white, inverting, cropping, and more.</p>
<p>To start working with these functions, you need to install the <code>Images</code> package and import it to your notebook:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> Pkg
Pkg.add(<span class="hljs-string">"Images"</span>)
<span class="hljs-keyword">using</span> Images
</code></pre>
<h3 id="heading-how-to-load-and-view-the-image">How to load and view the image</h3>
<p>You can use the <code>load</code> function to load the image. Let's load the first digit from our training dataset. If this file exists, it should load it to the <code>img</code> variable and display the image itself:</p>
<pre><code class="lang-julia">img = load(<span class="hljs-string">"training/0/1.png"</span>)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/image1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Loaded digit image</em></p>
<p>This is a loaded digit. Let's see the shape of the <code>img</code> variable:</p>
<pre><code class="lang-julia">size(img)
</code></pre>
<p>(28,28)</p>
<p>As you see, the <code>img</code> variable is an 2D array or matrix of image pixels. The first dimension of the array is a number of rows and the second dimension is a number of columns. That is why the height of image is the first value and the width of image is the second value. </p>
<p>Let's see the type of this variable now:</p>
<pre><code class="lang-julia">typeof(img)
</code></pre>
<p>Matrix{Gray{N0f8}} (alias for Array{Gray{Normed{UInt8, 8}}, 2})</p>
<p>It shows that this is a matrix of "Gray" objects. The <code>Gray</code> type defines a gray pixel. It means that the image that we loaded does not have color information. </p>
<p>The <code>Gray</code> data type defines the pixel by a single value – the intensity of gray color in a range between 0 and 1. So, the 0 is completely black and the 1 is completely white. </p>
<p>You can change a color of any pixel using the following code:</p>
<pre><code class="lang-julia">img[<span class="hljs-number">5</span>,<span class="hljs-number">5</span>] = Gray(<span class="hljs-number">0.5</span>)
</code></pre>
<p>This way you set the average gray color to the specified pixel (which was previously black).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/pixel_changed.png" alt="Image" width="600" height="400" loading="lazy">
<em>The image with modified pixel</em></p>
<p>If you load the full color image and request its type, it will show something like this:</p>
<p>Matrix{RGB{N0f8}} (alias for Array{RGB{Normed{UInt8, 8}}, 2})</p>
<p>In this case, each pixel has a type of <code>RGB</code> which defined by 3 values: intensity of <strong>R</strong>ed, intensity of <strong>G</strong>reen and intensity of <strong>B</strong>lue. Also, if you run <code>size(img)</code> for a colored image, you will see that this is a 3D array, like this:</p>
<p>(3,28,28)</p>
<p>where the first dimension is a number of color channels, the second dimension is a height and the third dimension is a width. </p>
<p>In other words, this color image consists of three matrices of 28x28 size. Each of them contains intensities of the appropriate color. </p>
<p>To set the color of any pixel in this image, you need to specify intensities of 3 channels in the <code>RGB</code> type constructor:</p>
<pre><code class="lang-julia">img[<span class="hljs-number">5</span>,<span class="hljs-number">5</span>] = RGB(<span class="hljs-number">1</span>,<span class="hljs-number">0.5</span>,<span class="hljs-number">0</span>)
</code></pre>
<p>This code sets the pixel color to orange.</p>
<h3 id="heading-how-to-implement-basic-image-transformations">How to implement basic image transformations</h3>
<p>Because the image is an array, you can use the array syntax to get access to any part of the image or even to individual pixels. </p>
<p>For example, you can run this to extract the first 10 rows and 20 columns of this image and write them to the new image:</p>
<pre><code class="lang-julia">img2 = img[<span class="hljs-number">1</span>:<span class="hljs-number">10</span>,<span class="hljs-number">1</span>:<span class="hljs-number">20</span>]
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/top_crop_image.png" alt="Image" width="600" height="400" loading="lazy">
<em>Part of image</em></p>
<p>You can crop the image by 5 pixels from all sides:</p>
<pre><code class="lang-julia">img3 = img[<span class="hljs-number">5</span>:<span class="hljs-number">22</span>,<span class="hljs-number">5</span>:<span class="hljs-number">22</span>]
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/cropped_image.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cropped image</em></p>
<p>You can apply different filters to the image by applying the specified function to each element of the matrix, using the <a target="_blank" href="https://docs.julialang.org/en/v1/manual/arrays/#Broadcasting">Julia broadcasting</a> feature via "dot" syntax. </p>
<p>For example, this code applies the <code>Gray</code> function to each pixel of the image. This approach can be used to convert images from colored to grayscale:</p>
<pre><code class="lang-julia">img4 = Gray.(img)
</code></pre>
<p>Similarly, you can convert gray images to colored:</p>
<pre><code class="lang-julia">img5 = RGB.(img)
</code></pre>
<p>You can apply custom functions to each pixel. For example, if you apply the next anonymous function to the gray image this way:</p>
<pre><code class="lang-julia">img6 = (x-&gt; Gray(<span class="hljs-number">1</span>)-x.val).(img)
</code></pre>
<p>it will invert the image colors by subtracting the color value of each pixel from 1. If the <code>img</code> has a white digit on a black background, then the <code>img6</code> will have a black digit on a white background:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/inverted_image.png" alt="Image" width="600" height="400" loading="lazy">
<em>Inverted image</em></p>
<p>Finally, to resize the image, you can use the <code>imresize</code> function. For example, to resize the <code>img</code> to 50x50 pixels, you can use the following code:</p>
<pre><code class="lang-julia">img6 = imresize(img,(<span class="hljs-number">50</span>,<span class="hljs-number">50</span>))
</code></pre>
<p>We will use only the features described above to prepare the images for handwritten digit recognition. But the <code>Images</code> module has many more interesting and fun things. Watch <a target="_blank" href="https://www.youtube.com/watch?v=DGojI9xcCfg">this video</a> to see some of them. Also, you can find a lot of interesting information in <a target="_blank" href="https://www.packtpub.com/product/hands-on-computer-vision-with-julia/9781788998796">this book</a>.</p>
<h3 id="heading-how-to-convert-the-image-to-numeric-matrix">How to convert the image to numeric matrix</h3>
<p>The last image preprocessing step is converting the pixels to numbers, because objects of type <code>Gray()</code> or <code>RGB()</code> are not suitable as an input for the machine learning model. </p>
<p>You can do this in two steps. First, you need to apply the <code>channelview</code> function to the image to get the matrix view of the image object, and then, convert the result to float numbers. So, if you run this command:</p>
<pre><code class="lang-julia">data = <span class="hljs-built_in">Float32</span>.(channelview(img))
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/channelview2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Image matrix</em></p>
<p>you will get the matrix, where each value is a float number that represents an intensity of the corresponding pixel. This data is ready to go to the neural network.</p>
<h2 id="how-to-prepare-the-image-data-for-machine-learning">How to prepare the image data for machine learning</h2>

<p>As I wrote in a <a target="_blank" href="https://www.freecodecamp.org/news/machine-learning-using-julia/#how-to-prepare-the-training-data-for-machine-learning">previous article</a>, the training dataset should consist of data from the feature matrix and from the labels vector. Both should contain only numbers. </p>
<p>Let's go back to our image collections in the <code>training</code> and <code>testing</code> folders. The labels are subfolder names where images located. They are already numbers. The features of an image are the pixels. Each pixel is defined by its color intensity. </p>
<p>So, to create a dataset that is ready for training from the images folder, you need to read all files from all subfolders, convert them to matrices of float numbers, and put them in the array. </p>
<pre><code class="lang-julia">path = <span class="hljs-string">"training"</span>
X = []
y = []
<span class="hljs-keyword">for</span> label <span class="hljs-keyword">in</span> readdir(path)
    <span class="hljs-keyword">for</span> file <span class="hljs-keyword">in</span> readdir(<span class="hljs-string">"<span class="hljs-variable">$path</span>/<span class="hljs-variable">$label</span>"</span>)
        img = load(<span class="hljs-string">"<span class="hljs-variable">$path</span>/<span class="hljs-variable">$label</span>/<span class="hljs-variable">$file</span>"</span>)
        data = reshape(<span class="hljs-built_in">Float32</span>.(channelview(img)),<span class="hljs-number">28</span>,<span class="hljs-number">28</span>,<span class="hljs-number">1</span>)
        <span class="hljs-keyword">if</span> length(X) == <span class="hljs-number">0</span>
            X = data
        <span class="hljs-keyword">else</span>
            X = cat(X,data,dims=<span class="hljs-number">3</span>)
        <span class="hljs-keyword">end</span>
        push!(y,parse(<span class="hljs-built_in">Float32</span>,label))
    <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>Ensure that the "training" and the "testing" folders with the MNIST images exist in the current folder before running this program. It will take a while to execute this code, because it will load 60000 images and will convert them to matrices. </p>
<p>In the outer loop, it reads the contents of the "training" folder. There are subfolders with names from 0 to 9 that will be used as labels. </p>
<p>Then, in the inner loop, it reads all image files of each of these subfolders using the <code>load</code> function from the <code>Images</code> package. </p>
<p>Next, it converts each image to the matrix of color intensities and places it in the <code>data</code> variable. After that, it appends this matrix to <code>X</code>. </p>
<p>Finally, it appends the name of the subfolder (which is an actual digit) to the labels vector <code>y</code>. </p>
<p>This way, you will have a dataset with feature matrix in <code>X</code> and labels vector in <code>y</code>. Let's refactor this code to a function to be able to reuse it to convert any folder with images, classified this way, to the dataset.</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> Images
<span class="hljs-keyword">function</span> createDataset(path)
    X = []
    y = []
    <span class="hljs-keyword">for</span> label <span class="hljs-keyword">in</span> readdir(path)
        <span class="hljs-keyword">for</span> file <span class="hljs-keyword">in</span> readdir(<span class="hljs-string">"<span class="hljs-variable">$path</span>/<span class="hljs-variable">$label</span>"</span>)
            img = load(<span class="hljs-string">"<span class="hljs-variable">$path</span>/<span class="hljs-variable">$label</span>/<span class="hljs-variable">$file</span>"</span>)
            data = reshape(<span class="hljs-built_in">Float32</span>.(channelview(img)),<span class="hljs-number">28</span>,<span class="hljs-number">28</span>,<span class="hljs-number">1</span>)
            <span class="hljs-keyword">if</span> length(X) == <span class="hljs-number">0</span>
                X = data
            <span class="hljs-keyword">else</span>
                X = cat(X,data,dims=<span class="hljs-number">3</span>)
            <span class="hljs-keyword">end</span>
            push!(y,parse(<span class="hljs-built_in">Float32</span>,label))
        <span class="hljs-keyword">end</span>
    <span class="hljs-keyword">end</span>
    <span class="hljs-keyword">return</span> X,y
<span class="hljs-keyword">end</span>
</code></pre>
<p>Using this function, you can now easily create both training and testing datasets:</p>
<pre><code class="lang-julia">x_train, y_train = createDataset(<span class="hljs-string">"training"</span>)
x_test, y_test = createDataset(<span class="hljs-string">"testing"</span>)
</code></pre>
<h2 id="how-to-create-a-machine-learning-model">How to create a machine learning model</h2>

<p>We will use a neural network to create a model and train it using the training data. To work with neural networks we will use the <a target="_blank" href="https://fluxml.ai/">Flux.jl framework</a> which allows you to create and train neural networks of various types, including feed forward, convolutional, and recurrent. </p>
<p>For handwritten image classification, we will implement both the Feed Forward and the Convolutional networks and compare their accuracy. If you need to, you can review the basics of neural networks by <a target="_blank" href="https://www.youtube.com/watch?v=aircAruvnKk&amp;t=313s">watching this video</a>. Now is the best time to watch this before you continue reading.</p>
<h3 id="heading-neural-network-basics">Neural network basics</h3>
<p>A neural network is a chain of layers. Each layer has a defined number of neurons with inputs and outputs. </p>
<p>To convert input to output for each layer, the neurons use the activation function, defined for this layer. Features of the image are the inputs of the first layer, and the classification results are the outputs of the last layer.</p>
<p>The best way to understand all this is to visualize some neural network architecture. Let's see the following basic neural net of 3 layers:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/dense_net.png" alt="Image" width="600" height="400" loading="lazy">
<em>Feed forward neural network for digits recognition. Source: http://neuralnetworksanddeeplearning.com/chap1.html</em></p>
<p>In this picture, the input layer contains 784 neurons that should receive the features of each image. As you remember, the training dataset consists of 28x28 images, which is 784 pixels. This is how this neural network works:</p>
<ul>
<li>The color value of each pixel goes to each neuron of the input layer.</li>
<li>Each neuron of the input layer sends its value to each neuron of the hidden layer. </li>
<li>Each neuron of the hidden layer has a weight coefficient for each input. By default, these coefficients are random numbers. So, each neuron on the hidden layer receives input values from the previous layer and multiplies each input by the appropriate weight, summarizes these products, and applies the activation function to that sum.</li>
<li>Each neuron of the hidden layer sends the resulting sum to each neuron of the output layer, which has 10 neurons.</li>
<li>The output layer does exactly the same for each input value as the previous layer and finally accumulates some sum inside.</li>
<li>This sum is treated as a probability of the appropriate digit, for example the first neuron should contain the probability that the input image is "0", the second neuron should contain the probability that the image is "1", and so on. </li>
</ul>
<p>Then, the application should look at which of these 10 neurons has the highest value and make the appropriate prediction.</p>
<h3 id="heading-how-to-create-the-neural-network-with-flux">How to create the neural network with Flux</h3>
<p>Let's create this neural network using Flux. If you haven't installed and imported it yet, do this in your notebook:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> Pkg
Pkg.add(<span class="hljs-string">"Flux"</span>)
<span class="hljs-keyword">using</span> Flux
</code></pre>
<p>As you have seen, the neural network is a chain of layers with different parameters. So, Flux has a <code>Chain</code> function that you use to construct neural networks. Let's construct that network:</p>
<pre><code class="lang-julia">model = Chain(
    Flux.flatten,
    Dense(<span class="hljs-number">784</span>=&gt;<span class="hljs-number">15</span>,relu),
    Dense(<span class="hljs-number">15</span>=&gt;<span class="hljs-number">10</span>,sigmoid),
    softmax
)
</code></pre>
<p>The <code>Chain</code> receives an array of functions as arguments. Each function defines a layer and it's parameters. Each of these functions receives some inputs, then after the appropriate actions returns the outputs and forwards them as inputs to the next function in the chain. </p>
<p>So, this is how the defined neural network works:</p>
<ul>
<li>The input image, which is a 28x28 array of pixel color intensities, comes to the <code>Flux.flatten</code> function. This function just converts this 28x28 matrix to a vector with 784 elements. This way we constructed the input for the first Dense layer.</li>
<li>Then, the next Dense function receives 784 values by 15 neurons. Then it multiplies these values by weights, summarizes these products, applies the <code>[relu](https://fluxml.ai/Flux.jl/stable/models/activation/#NNlib.relu)</code> activation function to this sum, and forwards these 15 values to 10 neurons of the next layer.</li>
<li>Next, the dense layer also multiplies each 15 inputs by the weight coefficients, summarizes them, and applies the <code>sigmoid</code> activation function to convert these sums to fractions of 1.</li>
<li>The final <code>[softmax](https://en.wikipedia.org/wiki/Softmax_function)</code> function actually doesn't build a new layer, but it just converts values that accumulated in the 10 neurons of the output layer to correct probabilities to properly show the probability distribution. Applying this function ensures that the sum of all 10 probabilities is equal to 1. The array of these probabilities will be returned by the model as a result.</li>
</ul>
<p>You can call the <code>model</code> which you just created as a function by passing an image matrix as an input argument. </p>
<p>You can run the model to predict the digit for the first image from the training dataset using the following code:</p>
<pre><code class="lang-julia">predict = model(Flux.unsqueeze(x_train[:,:,<span class="hljs-number">1</span>],dims=<span class="hljs-number">3</span>))
</code></pre>
<p>We use the <code>[unsqueeze](https://fluxml.ai/Flux.jl/stable/utilities/#Flux.unsqueeze)</code> function here to convert the image without channels of the (28,28) shape to the single channel image of the (28,28,1) shape. </p>
<p>This is an important rule for deep neural network processing – that the image is something that has a width, height, and color channels. So, even if it has only a single channel, it must be specified.</p>
<p>The model function receives the input image matrix, passes it through a chain of layers, and returns the array of probabilities.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/probs1-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>New neural network probabilities</em></p>
<p>As you can see, the highest probability has a neuron number 2 (0.12457416) which means that the model predicted the digit "1". However, if you check the real answer in the labels vector:</p>
<pre><code class="lang-julia">y_train[<span class="hljs-number">1</span>]
</code></pre>
<p>you will see "0", so the prediction is incorrect. This is because this model is untrained and just uses random weights to calculate the output for each layer. You need to train it to adjust these weights and calculate more accurate probability.</p>
<h2 id="how-to-train-the-model">How to train the model</h2>

<p>Flux.jl has different approaches to training a model. The most obvious one is the <code>[Flux.train](https://fluxml.ai/Flux.jl/stable/training/reference/#Flux.Optimise.train!-NTuple{4,%20Any})</code> function. The function runs the following training process:</p>
<ul>
<li>The function receives the training dataset as an argument, including the features matrix and the labels vector.</li>
<li>The function runs the <code>model</code> for each row of the training dataset and receives the resulting probabilities array.</li>
<li>The function compares these probabilities with the true values from the labels vector and calculates the <strong>amount of error</strong> (about this later).</li>
<li>Using information about the error, the function adjusts the weights and bias for each neuron on each layer.</li>
</ul>
<p>Usually you need to run this training process many times in a loop. On each iteration it will adjust the weights for each neuron, decreasing the error value more and more.</p>
<p>This visualization shows how the training process in a loop works for a single neuron on a single layer. For the whole network it works similar.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/1677823812311.gif" alt="Image" width="600" height="400" loading="lazy">
<em>The training process in a loop for a single neuron</em></p>
<p>This is a syntax of the <code>train</code> function:</p>
<pre><code class="lang-julia">Flux.train!(loss_function, model, data, optimizer)
</code></pre>
<p>Let's break this down:</p>
<ul>
<li><code>loss_function</code> – as I described before, during the training process, the <code>train</code> function measures the amount of error. To do this, it uses the <code>loss_function</code>, which you should define and provide here.   </li>
</ul>
<p>This function receives the model, the row of the training data, and the truth label. Based on these arguments, the loss function should make a prediction by passing the row of data through the model, comparing this prediction with the truth label, calculating the difference between them, and returning the amount of error as a float number.  </p>
<p>There are different algorithms exist to calculate the amount of error for different machine learning problem types. For classification problems we will use <strong><a target="_blank" href="https://fluxml.ai/Flux.jl/stable/models/losses/#Flux.Losses.crossentropy">cross entropy</a></strong>.</p>
<ul>
<li><code>model</code> – the neural network model to train.</li>
<li><code>data</code> – the training data that includes both <code>x_train</code> and <code>y_train</code> assembled to a single array of tuples. You can do this simply by using the <code>[Flux.DataLoader](https://fluxml.ai/Flux.jl/v0.10/data/dataloader/)</code> function, which we will use below.</li>
<li><code>optimizer</code> – as described above, after measuring the amount of error, the function adjusts the weights to decrease the error. The weights are not adjusted randomly, but by the <code>optimizer</code> that defines the algorithm. You use it to adjust the weights in the correct direction.   </li>
</ul>
<p>Most of the weight adjustment algorithms are based on <a target="_blank" href="https://builtin.com/data-science/gradient-descent">Gradient Descent</a>. In particular, we will use the <a target="_blank" href="https://fluxml.ai/Flux.jl/stable/training/optimisers/#Flux.Optimise.Adam">ADAM</a> optimizer, which is very common today.</p>
<p>Let's connect all these parts together in the following code:</p>
<pre><code class="lang-julia"><span class="hljs-comment"># Assemble the training data</span>
data = Flux.DataLoader((x_train,y_train), shuffle=<span class="hljs-literal">true</span>)

<span class="hljs-comment"># Initialize the ADAM optimizer with default settings</span>
optimizer = Flux.setup(Adam(), model)

<span class="hljs-comment"># Define the loss function that uses the cross-entropy to </span>
<span class="hljs-comment"># measure the error by comparing model predictions of data </span>
<span class="hljs-comment"># row "x" with true data label in the "y"</span>
<span class="hljs-keyword">function</span> loss(model, x, y)
    <span class="hljs-keyword">return</span> Flux.crossentropy(model(x),Flux.onehotbatch(y,<span class="hljs-number">0</span>:<span class="hljs-number">9</span>))
<span class="hljs-keyword">end</span>

<span class="hljs-comment"># Train the model 10 times in a loop</span>
<span class="hljs-keyword">for</span> epoch <span class="hljs-keyword">in</span> <span class="hljs-number">1</span>:<span class="hljs-number">10</span>
    Flux.train!(loss, model, data, optimizer)
<span class="hljs-keyword">end</span>
</code></pre>
<p>For each row of data, the <code>Flux.train!</code> calls the loss function, then the <code>loss</code> function runs the <code>model</code>. Using cross entropy, it calculates the difference between the predictions with true values of this row. This difference is returned as an error, and then the <code>optimizer</code> is used to adjust the weights of the model neurons based on this error value and the <code>loss</code> function. On each iteration, the error value should go down.</p>
<p>Finally, after running the training process, you can check how it predicts the digit for the first image using the trained model:</p>
<pre><code class="lang-julia">predict = model(Flux.unsqueeze(x_train[:,:,<span class="hljs-number">1</span>],dims=<span class="hljs-number">3</span>))
</code></pre>
<p>When I did that, I received the following probabilities:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/probs2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Trained model probabilities</em></p>
<p>The first one, related to "0" is the highest and this is definitely true. You can try to check other images, like image number 100 or 200. But it doesn't make much sense to measure model quality this way, because this is a training data that the model has already seen. Only the testing data should be used to measure the accuracy of the model.</p>
<h2 id="how-to-evaluate-the-accuracy-of-the-trained-model">How to evaluate the accuracy of the trained model</h2>

<p>We have the testing dataset in the <code>x_test</code> features matrix and in the <code>y_test</code> labels vector. We will run the <code>model</code> for each row of this data and measure the accuracy: the number of correct predictions divided by the number of all predictions.</p>
<p>Let's create a function for this:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">function</span> accuracy()
    correct = <span class="hljs-number">0</span>
    <span class="hljs-keyword">for</span> index <span class="hljs-keyword">in</span> <span class="hljs-number">1</span>:length(y_test)
        probs = model(Flux.unsqueeze(x_test[:,:,index],dims=<span class="hljs-number">3</span>))
        predicted_digit = argmax(probs)[<span class="hljs-number">1</span>]-<span class="hljs-number">1</span>
        <span class="hljs-keyword">if</span> predicted_digit == y_test[index]
            correct +=<span class="hljs-number">1</span>
        <span class="hljs-keyword">end</span>
    <span class="hljs-keyword">end</span>
    <span class="hljs-keyword">return</span> correct/length(y_test)
<span class="hljs-keyword">end</span>
</code></pre>
<p>The function goes over all items of the testing dataset. For each item it runs the model and receives the <code>probs</code> array. Then, it writes an index of the highest probability using the <code>[argmax](https://docs.julialang.org/en/v1/base/collections/#Base.argmax)</code> function to the <code>predicted_digit</code> variable. Next it compares the predicted digit with the truth value from <code>y_test</code> labels vector and increases the number of correct predictions if they match. The function returns the quotient of the number of correct predictions and the total number of rows.</p>
<p>Now you can run this function to see the accuracy. For example, when I ran this, I received the 0.9455, which is about 94.6%. </p>
<p>However, it's better to place this function call inside the training loop, right after the <code>Flux.train!</code> line to see how the accuracy changes after each training iteration.</p>
<pre><code class="lang-julia"><span class="hljs-keyword">for</span> epoch <span class="hljs-keyword">in</span> <span class="hljs-number">1</span>:<span class="hljs-number">10</span>
    Flux.train!(loss, model, data, optimizer)
    println(accuracy())
<span class="hljs-keyword">end</span>
</code></pre>
<p>Then run the training again. You should receive output similar to this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/accuracies.png" alt="Image" width="600" height="400" loading="lazy">
<em>Accuracy of the neural network</em></p>
<p>It shows that accuracy was going up until the 6th iteration. Since then, it started to go down, which could be a sign that the model started to overfit.</p>
<p>To increase the prediction quality, you can either add more data to the training dataset or change the model architecture. </p>
<p>For example, you can add more Dense layers, increase the number of neurons on the hidden layer, or change activation functions from <code>relu</code> to <code>sigmoid</code> or vice versa.</p>
<p>When I increased the number of neurons from 15 to 42 on the hidden layer and then removed the <code>sigmoid</code> activation from the output layer, I've achieved about 97% accuracy. But when I added one more hidden layer before output, the accuracy dropped to 90%. </p>
<p>So, building the neural net architecture is like art – you need to try different options a lot of times and finally select the one that works the best. </p>
<p>Regardless of the options I chose, I could never achieve more than 97%. Also, when I finally tried to use this network architecture in production with real handwritten digits from users, the prediction quality was poor. Very often it could not recognize the 7 digit properly, and it recognized 1 as 4 and 6 as 5.</p>
<p>This is because using the feed forward neural network, in which we just put all 784 pixels of the image as an input without any filters, is not the best approach.</p>
<p>For most machine learning tasks with images, the <strong>Convolutional</strong> neural networks is the better option. We will create and try this one in the next section.</p>
<h2 id="how-to-create-and-train-the-convolutional-neural-network">How to create and train the convolutional neural network</h2>

<p>The most important step during the machine learning process is data preprocessing. If input features are processed properly, then the prediction accuracy will be better. </p>
<p>To increase the model quality, you need to remove noise from data, or features that are not relevant for the value that you need to predict. </p>
<p>Also, oftentimes you need to create new features from existing ones that could be more relevant to the result. </p>
<p>For example, for the Titanic machine learning problem, you can remove such features as "Passenger ID" and "Passenger name", because they can't help to predict whether the passenger might survive or not. </p>
<p>Also, if you have a task to predict the price of a flat and have input data with fields of room areas like "Area 1", "Area 2" and so on, you can create a new field "Total Flat Area" and write the sum of all room areas to it. </p>
<p>Perhaps this new feature that you generated is more relevant than others for the model, so you can remove the fields from which you generated that new column.</p>
<p>Using these techniques, you generalize the data by keeping and creating the features that are important and by removing others that can only confuse the machine learning model.</p>
<p>When working with tabular data, you can use your own experience or statistical methods to find which features to generate or remove from input data. But when working with images, things are not as clear as with strings or numbers.</p>
<p>For example, the model for the handwritten digits recognition task receives the 784 pixel colors in a single row as an input. They have an equal value from a human point of view, and it's unknown which of them are more important and which of them are less.</p>
<p>To help you in this, you can use <strong>convolutional neural networks</strong> to preprocess this kind of data. They help you do the feature engineering automatically.</p>
<p>You build a convolutional neural network from two types of layers:</p>
<ul>
<li><strong>Convolution layers</strong> used to generate new features from input image pixels.</li>
<li><strong>Pooling layers</strong> used to generalize features using some rules and this way reduce their quantity.</li>
</ul>
<p>By combining these two types of layers in the chain, you can preprocess the input image matrix to receive a reduced number of the most valuable features. Then, you can train the network using these generated features as input data in the same way as you did before.</p>
<p>I think it's difficult to describe CNNs better than it's done in <a target="_blank" href="https://www.youtube.com/watch?v=JB8T_zN7ZC0">this video</a>, so I highly recommend watching it (or at least the first 15 minutes) before continue. It clearly explains the theoretical aspects of all steps that you will do below.</p>
<p>So, let's review the neural network that you have now:</p>
<pre><code class="lang-julia">model = Chain(
    Flux.flatten,
    Dense(<span class="hljs-number">784</span>=&gt;<span class="hljs-number">15</span>,relu),
    Dense(<span class="hljs-number">15</span>=&gt;<span class="hljs-number">10</span>,sigmoid),
    softmax
)
</code></pre>
<p>The only data preprocessing step here is the <code>Flux.flatten</code>, that receives the image of 28x28 pixels and returns it joined to a single row of 784 numbers. We need to add some convolution layers before the <code>Flux.flatten</code> to give to our network the ability to generate better features than just raw pixels.</p>
<p>To create the convolution layer, the Flux.jl has the <code>[Conv](https://fluxml.ai/Flux.jl/stable/models/layers/#Flux.Conv)</code> function with the following main parameters:</p>
<pre><code class="lang-julia">Conv(filter,<span class="hljs-keyword">in</span>=&gt;out,activation_function)
</code></pre>
<ul>
<li><strong>filter</strong> defines dimensions of the kernel matrix that will be applied to each pixel of the input matrix to create a feature from it. For example, the value (3,3) defines the 3x3 kernel matrix. This is how the convolution using this kernel matrix works to generate the features for an image of 6x6 size:</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/2D_Convolution_Animation.gif" alt="Image" width="600" height="400" loading="lazy">
<em>How convolution layer works</em></p>
<ul>
<li><strong>in</strong> is the number of input image channels. For our input data, gray images have a single channel. For other layers, the number of <strong>in</strong> channels of current layer must be equal to the <strong>out</strong> channels of previous layer.</li>
<li><strong>out</strong> is the number of output channels after apply the convolution. In other words, it's a number of features that will be generated for each pixel.</li>
<li><strong>activation_function</strong> is the function that will be applied to each feature after convolution and before sending to the next layer of the network, the same as we did before for <code>Dense</code> layers.</li>
</ul>
<p>For example, if you add the following <code>Conv</code> layer on top of the others to the Chain:</p>
<pre><code class="lang-julia">model = Chain(
    Conv((<span class="hljs-number">5</span>,<span class="hljs-number">5</span>),<span class="hljs-number">1</span>=&gt;<span class="hljs-number">6</span>,relu),
    Flux.flatten,
    Dense(<span class="hljs-number">4704</span>=&gt;<span class="hljs-number">15</span>,relu),
    Dense(<span class="hljs-number">15</span>=&gt;<span class="hljs-number">10</span>,sigmoid),
    softmax
)
</code></pre>
<p>this network will get a single channel image of the following shape: (28,28,1). It will produce 6 matrices from this image by applying different convolution kernels of 5x5 to the input data. </p>
<p>The output of this layer will be the image of the following shape: (28,28,6). In other words, this convolution layer will generate 28<em>28</em>6 =  4704 features from 784 input pixels for our network.</p>
<p>But if you have more features, it does not mean that they are all good. Perhaps you need to generalize them and leave only the most valuable ones. This is why the pooling layers are created. </p>
<p>In Flux.jl, the pooling layer can be defined using the <code>[MaxPool](https://fluxml.ai/Flux.jl/stable/models/layers/#Flux.MaxPool)</code> function. It receives the pooling window dimensions as an argument.</p>
<p>For example, if you create the following MaxPool layer:</p>
<pre><code class="lang-julia">MaxPool((<span class="hljs-number">2</span>,<span class="hljs-number">2</span>))
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/maxpool_animation.gif" alt="Image" width="600" height="400" loading="lazy">
<em>How Max pool layer works</em></p>
<p>it will apply the 2x2 window to the input image. As you can see, for each window it selects the maximum value and adds it to the output. This way it reduces the input data by leaving only maximums in it. That is why it's called the MAX pool layer.</p>
<p>Let's add the MaxPool layer to the chain:</p>
<pre><code class="lang-julia">model = Chain(
    Conv((<span class="hljs-number">5</span>,<span class="hljs-number">5</span>),<span class="hljs-number">1</span>=&gt;<span class="hljs-number">6</span>,relu),
    MaxPool((<span class="hljs-number">2</span>,<span class="hljs-number">2</span>)),
    Flux.flatten,
    Dense(<span class="hljs-number">1176</span>=&gt;<span class="hljs-number">15</span>,relu),
    Dense(<span class="hljs-number">15</span>=&gt;<span class="hljs-number">10</span>,sigmoid),
    softmax
)
</code></pre>
<p>So, the MaxPool receives the (28,28,6) sized image from the convolution layer, applies the 2x2 max pool window to it, and outputs (14,14,6) image. After this, the 14<em>14</em>6=1176 generalized features are forwarded to the network layers below.</p>
<p>The main question is how to know which number of convolution and max pool layers to add, and which parameters to set for each of them to achieve good prediction accuracy. </p>
<p>Well, the first way is to try different options. But to build a good neural network architecture this way could take days, months, or even years.</p>
<p>Fortunately, for many machine learning tasks, it has already been done by other people. You can find suitable architectures for most of your problems, including the model for the handwritten digit recognition.</p>
<p>The most known architecture for this task was created by Yann LeCun, and it's named LeNet. You can find a full description and implementations of this model for different ML platforms <a target="_blank" href="https://d2l.ai/chapter_convolutional-neural-networks/lenet.html">here</a>. It was created exactly for the digit images from MNIST dataset. It's relatively old, but still used in many ATMs to recognize digits for processing deposits.</p>
<p>This is how this architecture looks: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/LeNet-5.png" alt="Image" width="600" height="400" loading="lazy">
<em>LeNet architecture</em></p>
<p>Just like the network we created, this one consists of a convolutional part and a feed forward part. The convolutional net part consists of 2 Conv and 2 MaxPool layers. The feed forward neural network part consists of 3 dense layers.</p>
<p>You can create this network using Flux.jl this way:</p>
<pre><code class="lang-julia">model = Chain(
    Conv((<span class="hljs-number">5</span>,<span class="hljs-number">5</span>),<span class="hljs-number">1</span> =&gt; <span class="hljs-number">6</span>, relu),
    MaxPool((<span class="hljs-number">2</span>,<span class="hljs-number">2</span>)),
    Conv((<span class="hljs-number">5</span>,<span class="hljs-number">5</span>),<span class="hljs-number">6</span> =&gt; <span class="hljs-number">16</span>, relu),
    MaxPool((<span class="hljs-number">2</span>,<span class="hljs-number">2</span>)),
    Flux.flatten,
    Dense(<span class="hljs-number">256</span>=&gt;<span class="hljs-number">120</span>,relu),
    Dense(<span class="hljs-number">120</span>=&gt;<span class="hljs-number">84</span>, relu),
    Dense(<span class="hljs-number">84</span>=&gt;<span class="hljs-number">10</span>, sigmoid),
    softmax
)
</code></pre>
<p>After applying 2 convolutions and pooling to the input image matrix, the <code>Flux.flatten</code> layer receives the 4x4x16 image and converts it to 4<em>4</em>16=256 generalized features. Then they go through 3 dense layers to finally calculate probabilities for 10 digits.</p>
<p>Before training this model using the data from <code>x_train</code>, you need to reshape it a little bit. The convolution layer expects to get the data in the following 4-dimensional shape (width,height,channels,length), but the x_train has the following shape: (28,28,60000) which is 60000 images of 28x28. </p>
<p>To make it compatible, you need to reshape it to (28, 28, 1, 60000). You can do this using the following code:</p>
<pre><code class="lang-julia">x_train = reshape(x_train, <span class="hljs-number">28</span>, <span class="hljs-number">28</span>, <span class="hljs-number">1</span>, :)
</code></pre>
<p>You'll need to do the same with <code>x_test</code>:</p>
<pre><code class="lang-julia">x_test = reshape(x_test, <span class="hljs-number">28</span>, <span class="hljs-number">28</span>, <span class="hljs-number">1</span>, :)
</code></pre>
<p>To run this model, you also need to pass a 4 dimensional image structure to the <code>model</code> function. For example, to make a prediction for the first image, you can run this:</p>
<pre><code class="lang-julia">model(Flux.unsqueeze(x_test[:,:,:,<span class="hljs-number">1</span>],dims=<span class="hljs-number">4</span>))
</code></pre>
<p>Then you can train the model the same way as you did before. </p>
<p>This is the whole code to define and train the convolutional network:</p>
<pre><code class="lang-julia"><span class="hljs-comment"># Create a LeNet model</span>
model = Chain(
    Conv((<span class="hljs-number">5</span>,<span class="hljs-number">5</span>),<span class="hljs-number">1</span> =&gt; <span class="hljs-number">6</span>, relu),
    MaxPool((<span class="hljs-number">2</span>,<span class="hljs-number">2</span>)),
    Conv((<span class="hljs-number">5</span>,<span class="hljs-number">5</span>),<span class="hljs-number">6</span> =&gt; <span class="hljs-number">16</span>, relu),
    MaxPool((<span class="hljs-number">2</span>,<span class="hljs-number">2</span>)),
    Flux.flatten,
    Dense(<span class="hljs-number">256</span>=&gt;<span class="hljs-number">120</span>,relu),
    Dense(<span class="hljs-number">120</span>=&gt;<span class="hljs-number">84</span>, relu),
    Dense(<span class="hljs-number">84</span>=&gt;<span class="hljs-number">10</span>, sigmoid),
    softmax
)

<span class="hljs-comment"># Function to measure the model accuracy</span>
<span class="hljs-keyword">function</span> accuracy()
    correct = <span class="hljs-number">0</span>
    <span class="hljs-keyword">for</span> index <span class="hljs-keyword">in</span> <span class="hljs-number">1</span>:length(y_test)
        probs = model(Flux.unsqueeze(x_test[:,:,:,index],dims=<span class="hljs-number">4</span>))
        predicted_digit = argmax(probs)[<span class="hljs-number">1</span>]-<span class="hljs-number">1</span>
        <span class="hljs-keyword">if</span> predicted_digit == y_test[index]
            correct +=<span class="hljs-number">1</span>
        <span class="hljs-keyword">end</span>
    <span class="hljs-keyword">end</span>
    <span class="hljs-keyword">return</span> correct/length(y_test)
<span class="hljs-keyword">end</span>

<span class="hljs-comment"># Reshape the data</span>
x_train = reshape(x_train, <span class="hljs-number">28</span>, <span class="hljs-number">28</span>, <span class="hljs-number">1</span>, :)
x_test = reshape(x_test, <span class="hljs-number">28</span>, <span class="hljs-number">28</span>, <span class="hljs-number">1</span>, :)

<span class="hljs-comment"># Assemble the training data</span>
train_data = Flux.DataLoader((x_train,y_train), shuffle=<span class="hljs-literal">true</span>)

<span class="hljs-comment"># Initialize the ADAM optimizer with default settings</span>
optimizer = Flux.setup(Adam(), model)

<span class="hljs-comment"># Define the loss function that uses the cross-entropy to </span>
<span class="hljs-comment"># measure the error by comparing model predictions of </span>
<span class="hljs-comment"># data row "x" with true data from label "y"</span>
<span class="hljs-keyword">function</span> loss(model, x, y)
    <span class="hljs-keyword">return</span> Flux.crossentropy(model(x),Flux.onehotbatch(y,<span class="hljs-number">0</span>:<span class="hljs-number">9</span>))
<span class="hljs-keyword">end</span>

<span class="hljs-comment"># Train model 10 times in a loop</span>
<span class="hljs-keyword">for</span> epoch <span class="hljs-keyword">in</span> <span class="hljs-number">1</span>:<span class="hljs-number">10</span>
    Flux.train!(loss, model, train_data, optimizer)
    println(accuracy())
<span class="hljs-keyword">end</span>
</code></pre>
<p>After running this code, I received about 99% accuracy, which is close to ideal:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/conv_accuracy-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Accuracy of the convolutional network</em></p>
<p>Now it's time to save this model to a file and move it to production.</p>
<h2 id="how-to-export-trained-model-to-a-file">How to export trained model to a file</h2>

<p>Flux.jl models can be saved to BSON files. You need to import the <code>BSON</code> package and use the <code>@save</code> macro command to export the <code>model</code> object:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> BSON
BSON.<span class="hljs-meta">@save</span> <span class="hljs-string">"digits.bson"</span> model
</code></pre>
<p>This will save the model to the <code>digits.bson</code> file into the current folder.</p>
<p>This is the end of your work in the Jupyter notebook. We'll implement the following code as a new application.</p>
<h2 id="how-to-create-a-frontend">How to create a frontend</h2>

<p>The application which you are going to create will allow a user to write their phone number and recognize it using the model that you created and trained before. The frontend page will look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/frontend.png" alt="Image" width="600" height="400" loading="lazy">
<em>Frontend</em></p>
<p>Using this interface, the user can draw digits of a phone number in the boxes using the mouse, then press the "Recognise" button and display the recognised digits in the "Result" input field. </p>
<p>Also, there is a "Switch to eraser" button. When the user presses it, the drawing mode changes to the eraser mode and the user can erase any number in any box.</p>
<p>Let's start building the web application. Create a new folder with any name that you like. Then create an <code>index.html</code> file in it and copy the following code to this file:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Phones reader<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Draw phone number and recognise it<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"digits"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>+<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">canvas</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"50"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"50"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">canvas</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>(<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">canvas</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"50"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"50"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">canvas</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">canvas</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"50"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"50"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">canvas</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">canvas</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"50"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"50"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">canvas</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>)<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">canvas</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"50"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"50"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">canvas</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">canvas</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"50"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"50"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">canvas</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">canvas</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"50"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"50"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">canvas</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>-<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">canvas</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"50"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"50"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">canvas</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">canvas</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"50"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"50"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">canvas</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">canvas</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"50"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"50"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">canvas</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">canvas</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"50"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"50"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">canvas</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"buttons"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"mode"</span>&gt;</span>Switch to eraser<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"result"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"recognise"</span>&gt;</span>Recognise<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Result:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"result"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-keyword">let</span> mode = <span class="hljs-string">"brush"</span>;
    <span class="hljs-comment">// "Switch" button handler. Switches mode from </span>
    <span class="hljs-comment">// brush to eraser and back</span>
    <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#mode"</span>).addEventListener(<span class="hljs-string">"click"</span>,<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-keyword">if</span> (mode === <span class="hljs-string">"brush"</span>) {
            mode = <span class="hljs-string">"eraser"</span>;
            event.target.innerHTML = <span class="hljs-string">"Switch to brush"</span>;
        } <span class="hljs-keyword">else</span> {
            mode = <span class="hljs-string">"brush"</span>;
            event.target.innerHTML = <span class="hljs-string">"Switch to eraser"</span>;
        }
    });
    <span class="hljs-comment">// Digits canvases mouse move handler.</span>
    <span class="hljs-comment">// If mouse button pressed while user moves the mouse</span>
    <span class="hljs-comment">// on canvas, it draws circles in cursor position.</span>
    <span class="hljs-comment">// If mode="brush" then circles are black, otherwise</span>
    <span class="hljs-comment">// they are white</span>
    <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">"canvas"</span>).forEach(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> {
        ctx = item.getContext(<span class="hljs-string">"2d"</span>);  
        ctx.fillStyle=<span class="hljs-string">"#FFFFFF"</span>;
        ctx.fillRect(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">50</span>,<span class="hljs-number">50</span>);
        item.addEventListener(<span class="hljs-string">"mousemove"</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
            <span class="hljs-keyword">if</span> (event.buttons) {
                ctx = event.target.getContext(<span class="hljs-string">"2d"</span>);  
                <span class="hljs-keyword">if</span> (mode === <span class="hljs-string">"brush"</span>) {
                    ctx.fillStyle = <span class="hljs-string">"#000000"</span>;         
                } <span class="hljs-keyword">else</span> {
                    ctx.fillStyle = <span class="hljs-string">"#FFFFFF"</span>;         
                }
                ctx.beginPath();               
                ctx.arc(event.offsetX<span class="hljs-number">-1</span>,event.offsetY<span class="hljs-number">-1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">0</span>, <span class="hljs-number">2</span> * <span class="hljs-built_in">Math</span>.PI);
                ctx.fill();   
            }
        })
    })
    <span class="hljs-comment">// "Recognise" button handler. Captures</span>
    <span class="hljs-comment">// content of all digit canvases as BLOB.</span>
    <span class="hljs-comment">// Construct files from these blobs and</span>
    <span class="hljs-comment">// posts them to backend as a files as a</span>
    <span class="hljs-comment">// multipart form</span>
    <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#recognise"</span>).addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-keyword">async</span>() =&gt; {
        data = <span class="hljs-keyword">new</span> FormData();
        canvases = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">"canvas"</span>);
        <span class="hljs-keyword">const</span> getPng = <span class="hljs-function">(<span class="hljs-params">canvas</span>) =&gt;</span> {
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-params">resolve</span> =&gt;</span> {
                canvas.toBlob(<span class="hljs-function"><span class="hljs-params">png</span> =&gt;</span> {
                    resolve(png)
                })
            })
        }
        index = <span class="hljs-number">0</span>
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> canvas <span class="hljs-keyword">of</span> canvases) {
            <span class="hljs-keyword">const</span> png = <span class="hljs-keyword">await</span> getPng(canvas);
            data.append((++index)+<span class="hljs-string">".png"</span>,<span class="hljs-keyword">new</span> File([png],index+<span class="hljs-string">".png"</span>));
        }
        <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"http://localhost:8080/api/recognize"</span>, {
            <span class="hljs-attr">body</span>: data,
            <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>
        })
        <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#result"</span>).value = <span class="hljs-keyword">await</span> response.text();
    })

</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
    <span class="hljs-selector-tag">body</span> {
        <span class="hljs-attribute">display</span>:flex;
        <span class="hljs-attribute">flex-direction</span>: column;
        <span class="hljs-attribute">justify-content</span>: flex-start;
        <span class="hljs-attribute">align-items</span>: flex-start;
    }
    <span class="hljs-selector-tag">canvas</span> {
        <span class="hljs-attribute">border-width</span>:<span class="hljs-number">1px</span>;
        <span class="hljs-attribute">border-color</span>:black;
        <span class="hljs-attribute">border-style</span>: solid;
        <span class="hljs-attribute">margin-right</span>:<span class="hljs-number">5px</span>;
        <span class="hljs-attribute">cursor</span>:crosshair;
    }
    <span class="hljs-selector-class">.digits</span> {
        <span class="hljs-attribute">display</span>:flex;
        <span class="hljs-attribute">flex-direction</span>: row;
        <span class="hljs-attribute">align-items</span>: center;
        <span class="hljs-attribute">justify-content</span>: flex-start;
    }
    <span class="hljs-selector-class">.digits</span> <span class="hljs-selector-tag">strong</span> {
        <span class="hljs-attribute">font-size</span>: <span class="hljs-number">72px</span>;
        <span class="hljs-attribute">margin</span>:<span class="hljs-number">10px</span>;
    }
    <span class="hljs-selector-class">.buttons</span> {
        <span class="hljs-attribute">display</span>:flex;
        <span class="hljs-attribute">flex-direction</span>: column;
        <span class="hljs-attribute">justify-content</span>: flex-start;
        <span class="hljs-attribute">align-items</span>: center;
    }
    <span class="hljs-selector-tag">button</span> {
        <span class="hljs-attribute">width</span>:<span class="hljs-number">100px</span>;
        <span class="hljs-attribute">margin-bottom</span>:<span class="hljs-number">5px</span>;
        <span class="hljs-attribute">margin-right</span>:<span class="hljs-number">10px</span>;
    }
    <span class="hljs-selector-class">.result</span> {
        <span class="hljs-attribute">margin-top</span>:<span class="hljs-number">10px</span>;
        <span class="hljs-attribute">display</span>:flex;
        <span class="hljs-attribute">flex-direction</span>: row;
        <span class="hljs-attribute">align-items</span>: flex-start;
        <span class="hljs-attribute">justify-content</span>: flex-start;
    }
    <span class="hljs-selector-tag">input</span> {
        <span class="hljs-attribute">margin-left</span>:<span class="hljs-number">10px</span>;
    }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The HTML part of this code contains 11 <a target="_blank" href="https://www.w3schools.com/html/html5_canvas.asp">HTML5 canvas</a> elements that display the boxes where you can draw. Each box has a size of 50x50 pixels and is filled with a white color. Also, the HTML contains "Switch to ..." and "Recognise" buttons and the "Result" input field.</p>
<p>The JavaScript part defines the "mode" global variable, which is equal to "brush" by default. When the user presses the "Switch to ..." button, it changes the mode to the "eraser". If they press it again, it switches back to the "brush".</p>
<p>Next, the JavaScript code defines "mousemove" event handlers for all canvas boxes. If the user presses the left mouse button in the "brush mode" and moves the mouse in the box, it draws black circles in place of the mouse cursor. This way, the user draws the digits. If the mode is "eraser", then it draws white circles. This way, the user can erase the black marks.</p>
<p>Finally, we defined the "Recognise" button click handler. When the user clicks this button, the handler function collects 11 digit images from the <code>canvas</code> elements and converts them to <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Blob">BLOB</a> objects in a PNG image format. </p>
<p>Then it creates a POST request, puts these 11 digit images in it as files with names 1.png, 2.png and so on, and sends them to the <code>/api/recognize</code> endpoint of the backend service on port 8080 of a local host (which we will create in the next section). </p>
<p>The backend should receive these images, recognise digits in them, and return the recognition result as a string. This string will be displayed in the "Result" input field.</p>
<p>Lastly, I defined some CSS to apply basic styles to this page. You can modify them as you want. Now, let's move to the most interesting part – the digits recognition backend.</p>
<h2 id="how-to-create-a-backend">How to create a backend</h2>

<p>As a modern and mature programming language, Julia has a lot of libraries and frameworks for different tasks. Web frameworks are not an exception. We will use the <a target="_blank" href="https://genieframework.com/">Genie.jl</a> framework, which is similar to the Express in Node.js or Flask in Python.</p>
<p>With Genie.jl you can run a basic web service in two lines of code:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> Genie
up(<span class="hljs-number">8080</span>, async=<span class="hljs-literal">false</span>)
</code></pre>
<p>It will run a web server on port 8080 of a local host.</p>
<p>Using any text editor, for example VSCode with the <a target="_blank" href="https://www.julia-vscode.org/">Julia extension</a>, create a new Julia file like <code>digits.jl</code> in the same folder with the <code>index.html</code>. This is where you'll write the next bit of code.</p>
<p>This web service will have two endpoints:</p>
<ul>
<li><strong><code>/</code></strong> to display the index.html web page that you created before.</li>
<li><strong><code>/api/recognize</code></strong> to receive POST requests with the images of digits, recognize them, and return a string with recognized numbers.</li>
</ul>
<p>As with most other web frameworks, to receive and process HTTP requests Genie.jl uses routes. This application will have two routes: </p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> Genie, Genie.Router, Genie.Requests

route(<span class="hljs-string">"/"</span>) <span class="hljs-keyword">do</span> 
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">String</span>(read(<span class="hljs-string">"index.html"</span>))
<span class="hljs-keyword">end</span>

route(<span class="hljs-string">"/api/recognize"</span>, method=POST) <span class="hljs-keyword">do</span>
    result = <span class="hljs-string">""</span>
    <span class="hljs-comment"># TODO: in a loop, extract each image </span>
    <span class="hljs-comment"># from POST request body, send it to </span>
    <span class="hljs-comment"># the digit recognition function, </span>
    <span class="hljs-comment"># receive recognized digit and add </span>
    <span class="hljs-comment"># it to the result</span>
    <span class="hljs-keyword">return</span> result
<span class="hljs-keyword">end</span>

up(<span class="hljs-number">8080</span>, async=<span class="hljs-literal">false</span>)
</code></pre>
<p>To work with routes and requests, you need to import two additional subpackages – <code>Genie.Router</code> and <code>Genie.Requets</code>. </p>
<p>The first route just returns the content of the <code>index.html</code> file.</p>
<p>The second route processes the POST requests to the <code>/api/recognize</code> endpoint. This is how you can define it:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> Images
route(<span class="hljs-string">"/api/recognize"</span>, method=POST) <span class="hljs-keyword">do</span>
    result = <span class="hljs-string">""</span>
    files = filespayload();   
    <span class="hljs-keyword">for</span> index <span class="hljs-keyword">in</span> <span class="hljs-number">1</span>:<span class="hljs-number">11</span>
        file = files[<span class="hljs-string">"<span class="hljs-variable">$index</span>.png"</span>]
        img = load(<span class="hljs-built_in">IOBuffer</span>(file.data))
        result *= recognizeDigit(img)        
    <span class="hljs-keyword">end</span>    
    <span class="hljs-keyword">return</span> result
<span class="hljs-keyword">end</span>
</code></pre>
<p>To load the received file as an image, we will use the Julia Images library that we imported on the first line.</p>
<p>Then, the <code>[filespayload](https://github.com/GenieFramework/Genie.jl/blob/7eb45c9ec32f0e4659abb08559b0b2729451421a/src/Requests.jl#L50)()</code> function extracts all files from the received request. </p>
<p>Then, we assume that the request has 11 files and we process them in a loop. Each file data is extracted as an array of bytes, but the <code>[load](https://juliaimages.org/stable/function_reference/#FileIO.load)</code> function requires the object that implements an IO buffer. That is why the <code>[IOBuffer](https://docs.julialang.org/en/v1/base/io-network/#Base.IOBuffer)</code> converts the array of bytes to a suitable format. </p>
<p>Then, the loaded image gets passed to the <code>recognizeDigit</code> function. This function will be written below. It should receive the image, then recognize it using the trained model and return the recognized digit as a string. This digit will be appended to the <code>result</code> string. Finally, the result with 11 recognized digits will be sent to the web page.</p>
<p>Before writing the <code>recognizeDigit</code> function, ensure that the saved model file <code>digits.bson</code> was copied to the folder with your backend code.</p>
<p>Also, it's important to understand that we can't process the input image as is because it has a size of 50x50, and it is a black digit on a white background.</p>
<p>If the model trained on images with size 28x28, then it can't be used to recognize images of other sizes. </p>
<p>Also, the model that trained on images that had white text written on black background will work poorly for colored images and for images with black text on a white background. </p>
<p>So, before you send the image to the model for recognition, you need to preprocess them using the following steps:</p>
<ul>
<li>Convert the images to gray</li>
<li>Invert the colors</li>
<li>Resize them to 28x28</li>
</ul>
<p>Now you are ready to implement the digits recognition function:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> Flux, MLUtils, BSON
<span class="hljs-keyword">function</span> recognizeDigit(img)
    <span class="hljs-comment"># load the model</span>
    BSON.<span class="hljs-meta">@load</span> <span class="hljs-string">"digits.bson"</span> model
    <span class="hljs-comment"># Convert image to grayscale</span>
    img = Gray.(img)
    <span class="hljs-comment"># Invert each pixel color</span>
    img = (x-&gt;Gray(<span class="hljs-number">1</span>)-x.val).(img)
    <span class="hljs-comment"># resize image to 28x28 pixels</span>
    img = imresize(img,(<span class="hljs-number">28</span>,<span class="hljs-number">28</span>))
    <span class="hljs-comment"># Get matrix of image</span>
    digit_data = <span class="hljs-built_in">Float32</span>.(channelview(img))
    <span class="hljs-comment"># predict the digit (get probabilities)</span>
    probs = model(cat(digit_data,dims=<span class="hljs-number">4</span>))
    <span class="hljs-comment"># return the digit with the largest </span>
    <span class="hljs-comment"># probability, converted to a string</span>
    <span class="hljs-keyword">return</span> <span class="hljs-string">"<span class="hljs-subst">$(argmax(probs)</span>[1]-1)"</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>When all this is done, you are almost ready to run the app. Before doing that, ensure that all required packages are installed. Run the <code>julia</code> REPL in a project folder. Then run the following code line by line, to install all packages mentioned in the <code>using</code> lines:</p>
<pre><code class="lang-bash">using Pkg
Pkg.add(<span class="hljs-string">"Genie"</span>)
Pkg.add(<span class="hljs-string">"Images"</span>)
Pkg.add(<span class="hljs-string">"Flux"</span>)
Pkg.add(<span class="hljs-string">"MLUtils"</span>)
</code></pre>
<p>Then exit the repl using the <code>exit()</code> command.</p>
<p>Now you can run the app. To do that, either execute the <code>julia digits.jl</code> command from the terminal or press Ctrl+F5 in VSCode. </p>
<p>Then, go to <code>http://localhost:8080</code> in a web browser, draw the digits, press the "Recognise" button, and in a few moments you will see the recognised number as a text in the "Result" field.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/e5ScpCggVbs" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="conclusion">Conclusion</h2>

<p>In this tutorial, I demonstrated how to create and train both feed forward and convolutional neural networks using Julia. You also learned how to export and use them in a web application.</p>
<p>In addition, I tried to show that you should not reinvent the wheel when creating neural networks.</p>
<p>When solving real life problems, you should not build neural network architectures from scratch. Most of them have already been created by data scientists and enthusiasts around the world. In practice, you will just reuse them. </p>
<p>You'll just need to find the suitable architecture and either use it as is or change the last few layers to adjust the outputs according to your needs.</p>
<p>For example, you can search <a target="_blank" href="https://huggingface.co/models">this collection</a> where you'll find different models classified by problem types. Even if many of them were not created with Julia, you can create them using Flux.jl after reading their descriptions.</p>
<p>The way we created and trained our neural network is not the best or the only possible one. Perhaps in some points I oversimplified things, because I wanted to explain all this as simply as possible. </p>
<p>But if you've understood the examples here, you can learn and reuse the following more advanced Julia solutions of the handwritten digits recognition task:</p>
<ul>
<li><a target="_blank" href="https://fluxml.ai/Flux.jl/stable/tutorials/2021-01-26-mlp/">Tutorial: Simple Multi-Layer Perceptron</a> </li>
<li><a target="_blank" href="https://github.com/FluxML/model-zoo/tree/master/vision/conv_mnist">MNIST example in the Julia model-zoo</a></li>
</ul>
<p>You can see the source code of this article including the Jupyter Notebook and the web service in <a target="_blank" href="https://github.com/AndreyGermanov/phones_reader">this repository</a>.</p>
<p>Have a fun coding and never stop learning!</p>
<p>You can find me on <a target="_blank" href="https://www.linkedin.com/in/andrey-germanov-dev/">LinkedIn</a>, <a target="_blank" href="https://twitter.com/GermanovDev">Twitter</a>, and <a target="_blank" href="https://www.facebook.com/AndreyGermanovDev">Facebook</a> to know first about new articles like this one and other software development news.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Machine learning with Julia – How to Build and Deploy a Trained AI Model as a Web Service ]]>
                </title>
                <description>
                    <![CDATA[ By Andrey Germanov Julia is a general purpose programming language well suited for numerical analysis and computational science. Some consider it the future of machine learning and the most natural replacement for Python in this field. This article i... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/machine-learning-using-julia/</link>
                <guid isPermaLink="false">66d45eea51f567b42d9f8459</guid>
                
                    <category>
                        <![CDATA[ Julia ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Machine Learning ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 17 Feb 2023 22:33:02 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/02/cover-3.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Andrey Germanov</p>
<p><a target="_blank" href="https://julialang.org/">Julia</a> is a general purpose programming language well suited for numerical analysis and computational science. Some consider it the future of machine learning and the most natural replacement for Python in this field.</p>
<p>This article introduces the Julia language and its ecosystem. You'll learn how to use it to solve a <a target="_blank" href="https://www.kaggle.com/competitions/titanic">Titanic machine learning competition</a> and submit it to the Kaggle. </p>
<p>You'll also learn how to deploy your machine learning model to production as a web service and create a web interface to send prediction requests to this service from a web browser.</p>
<p>By the end of the article, you will create a simple AI-powered web application that you can use as a template for creating more complex Julia ML solutions.</p>
<p>Here's what we'll cover:</p>
<ol>
<li><a class="post-section-overview" href="#heading-what-you-should-know-in-advance">What You Should Know in Advance</a></li>
<li><a class="post-section-overview" href="#heading-why-use-julia-for-machine-learning">Why Use Julia for Machine Learning?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-install-julia-and-jupyter-notebook-support">How to Install Julia and Jupyter Notebook Support</a></li>
<li><a class="post-section-overview" href="#heading-julia-language-basics">Julia Language Basics</a></li>
<li><a class="post-section-overview" href="#heading-how-to-visualize-data-in-julia">How to Visualize Data in Julia</a></li>
<li><a class="post-section-overview" href="#heading-overview-of-the-titanic-machine-learning-problem-on-kaggle">Overview of the Titanic Machine Learning Problem on Kaggle</a></li>
<li><a class="post-section-overview" href="#heading-how-to-prepare-the-training-data-for-machine-learning">How to Prepare the Training Data for Machine Learning</a></li>
<li><a class="post-section-overview" href="#heading-how-to-train-our-machine-learning-model">How to Train Our Machine Learning Model</a></li>
<li><a class="post-section-overview" href="#heading-how-to-make-predictions-and-submit-them-to-kaggle">How to Make Predictions and Submit Them to Kaggle</a></li>
<li><a class="post-section-overview" href="#heading-how-to-deploy-the-model-to-production">How to Deploy the Model to Production</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ol>
<h2 id="heading-what-you-should-know-in-advance">What You Should Know in Advance</h2>
<p>This is not a book, but only an article. I won't cover everything and assume that you already have some base knowledge so you can get the most from reading it. </p>
<p>It is essential that you are familiar with Python machine learning and understand how to train machine learning models using <a target="_blank" href="https://numpy.org/">Numpy</a>, <a target="_blank" href="https://pandas.pydata.org/">Pandas</a>, <a target="_blank" href="https://scikit-learn.org/">SciKit-Learn</a> and <a target="_blank" href="https://matplotlib.org/">Matplotlib</a> Python libraries. </p>
<p>Also, I assume that you are familiar with machine learning theory: <a target="_blank" href="https://www.practicalai.io/categorizing-machine-learning-problems/">types of machine learning problems</a> like regression and classification, the concept and process of <a target="_blank" href="https://en.wikipedia.org/wiki/Supervised_learning">Supervised machine learning</a> (fit/predict and evaluate quality using metrics) and common models used for it, including <a target="_blank" href="https://scikit-learn.org/stable/modules/ensemble.html#forest">Random Forest Classifier</a>, and it's implementation in SciKit-Learn Python library. </p>
<p>Additionally, it would be great if you've previously participated in Kaggle competitions, because to understand and run all code of this article you need to have an account on <a target="_blank" href="https://kaggle.com">https://kaggle.com</a>. </p>
<p>There are a <a target="_blank" href="https://www.google.com/search?q=machine+learning+with+sklearn+books">lot of books</a> already written, and <a target="_blank" href="https://www.freecodecamp.org/news/machine-learning-for-everybody/">many courses already released</a> about the topics described above. In this article, my goal is to show you how to create, train, and deploy basic machine learning model using Julia, without diving to theoretical aspects of ML and AI.</p>
<h2 id="heading-why-use-julia-for-machine-learning">Why Use Julia for Machine Learning?</h2>
<p>For a long time, Python has been a standard for data science and machine learning because of it simplicity and great set of libraries and tools. </p>
<p>Among others there are great libraries like Numpy to help you do linear algebra with vectors and matrices, Pandas to manipulate datasets, Matplotlib for data visualizations, and Scikit-Learn that provides a uniform interface to work with well-known machine learning models. </p>
<p>Also, Jupyter Notebooks allow you to write and run Python code online right in a web browser. This creates a comfortable environment for data researchers to design and implement the whole machine learning cycle even if they are not very experienced in programming.</p>
<p>All this is good for research in laboratories, but at some point, you need to go to production. At this moment things change dramatically. </p>
<p>Python was created in the early nineties and was never supposed to be fast. It's kernel was never assumed to be used for new modern technologies like distributed computing. </p>
<p>That is why, to make complex ML tasks production-ready, you need to install a lot of third party dependencies. You'll also have to employ some tricks to speed Python code up. You can even rewrite or convert Python machine learning models before deploying them to production in faster languages like C++.</p>
<p>Well, Julia aimed to resolve these problems. This is what the authors wrote about why they created Julia:</p>
<blockquote>
<p>We are greedy: we want more. We want a language that’s open source, with a liberal license. We want the speed of C with the dynamism of Ruby. We want a language that’s homoiconic, with true macros like Lisp, but with obvious, familiar mathematical notation like Matlab. We want something as usable for general programming as Python, as easy for statistics as R, as natural for string processing as Perl, as powerful for linear algebra as Matlab, as good at gluing programs together as the shell. Something that is dirt simple to learn, yet keeps the most serious hackers happy. We want it interactive and we want it compiled. Source: <a target="_blank" href="https://julialang.org/blog/2012/02/why-we-created-julia/">The Julia blog</a>.</p>
</blockquote>
<p>So, from an ML perspective, Julia got the best of both worlds. It was built to be as fast as C and as simple as Python. In addition, it has similar libraries that Python data scientists are used to incorporating into their work:</p>
<table>
    <tbody>
    <tr>
        <th>Purpose</th>
        <th>Python</th>
        <th>Julia</th>
    </tr>
    <tr>
        <td>Linear algebra</td>
        <td><a href="https://numpy.org/">Numpy</a></td>
        <td>Built in arrays, <a href="https://docs.julialang.org/en/v1/stdlib/LinearAlgebra/">LinearAlgebra</a> package</td>
    </tr>
    <tr>
        <td>Work with datasets</td>
        <td><a href="https://pandas.pydata.org/">Pandas</a></td>
        <td><a href="https://dataframes.juliadata.org/stable/">DataFrames.jl</a></td>
    </tr>
    <tr>
        <td>Data visualization</td>
        <td><a href="https://matplotlib.org/">Matplotlib</a></td>
        <td><a href="https://docs.juliaplots.org/stable/">Plots.jl</a></td>
    </tr>
    <tr>
        <td>Classic Machine learning</td>
        <td><a href="https://scikit-learn.org/">SciKit-Learn</a></td>
        <td><a href="https://alan-turing-institute.github.io/MLJ.jl/dev/about_mlj/">MLJ.jl</a> or <a href="https://scikitlearnjl.readthedocs.io/en/latest/">ScikitLearn.jl</a></td>
    </tr>
    <tr>
        <td>Neural Networks</td>
        <td><a href="https://www.tensorflow.org/">TensorFlow</a> or <a href="https://pytorch.org/">Pytorch</a></td>
        <td><a href="https://fluxml.ai/Flux.jl/stable/">Flux.jl</a></td>
    </tr>
    </tbody>
</table>

<p>You can read more about why Julia is a great choice for machine learning <a target="_blank" href="https://towardsdatascience.com/the-future-of-machine-learning-and-why-it-looks-a-lot-like-julia-a0e26b51f6a6">here</a>. </p>
<p>Furthermore, Julia has a module to support Jupyter Notebooks, so you can write Julia code there the same as with Python. </p>
<p>All this makes the Julia ready to do machine learning tasks, including Kaggle competitions, in the same environment as when using Python. </p>
<p>Now that you know why Julia is a great choice for ML, let's install this environment and introduce some Julia ML basics.</p>
<h2 id="heading-how-to-install-julia-and-jupyter-notebook-support">How to Install Julia and Jupyter Notebook Support</h2>
<p>To install Julia, follow this link: <a target="_blank" href="https://julialang.org/downloads/">https://julialang.org/downloads/</a>. There, download the Julia package for your operating system and run it. </p>
<p>After successful installation, you will be able to run the <code>julia</code>  command to enter the Julia REPL environment. Here, you can write and run Julia code. To exit from REPL, type the <code>exit()</code> command. </p>
<p>Also, you can write your code in any text editor and save to files with the <code>.jl</code> extension. Then you can run your Julia programs by this command:</p>
<pre><code class="lang-bash">julia &lt;filename&gt;.jl
</code></pre>
<p>In addition, you can use VSCode to develop in Julia. It has a great extension for this: <a target="_blank" href="https://www.julia-vscode.org/">https://www.julia-vscode.org/</a>.</p>
<p>However, the best option to develop machine learning and data science solutions is using a <a target="_blank" href="https://jupyter.org/">Jupyter Notebook</a>. So make sure that it's <a target="_blank" href="https://jupyter.org/install">installed</a> before continuing. Then, install the Jupyter support for Julia package using REPL:</p>
<ul>
<li>Enter REPL using the <code>julia</code> command</li>
<li>Import <code>Pkg</code> module  like this:</li>
</ul>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> Pkg
</code></pre>
<ul>
<li>Then install the <code>IJulia</code> package:</li>
</ul>
<pre><code class="lang-julia">Pkg.add(<span class="hljs-string">"IJulia"</span>)

* Exit REPL by <span class="hljs-keyword">using</span> the <span class="hljs-string">`exit()`</span> command

Then you can run Jupyter and create notebooks with Julia support. For your convenience, the next video shows how to install Julia and integrate it to Jupyter on macOS (assuming that Jupyter itself already installed).

%[https://youtu.be/rnJkT4G3-sE]

<span class="hljs-comment">## Julia Language Basics</span>

Julia has a simple syntax. If you're familiar with Python, then it will be easy to start writing <span class="hljs-keyword">in</span> Julia. You can read more about basic Julia syntax <span class="hljs-keyword">in</span> this [article](https://www.freecodecamp.org/news/learn-julia-programming-language/). 

In this tutorial, <span class="hljs-literal">I</span> will only cover features that are required <span class="hljs-keyword">for</span> machine learning and only the features which we'll use to solve the Titanic Kaggle competition. To learn more about each of these libraries and modules, <span class="hljs-literal">I</span> will provide useful links.

Create a new Jupyter Notebook to enter and run all the code samples below.

<span class="hljs-comment">### Linear Algebra Features</span>

Basic linear algebra features are already integrated into the Julia standard library. Each <span class="hljs-number">1</span>D array is a vector, and each <span class="hljs-number">2</span>D array works as a Numpy array by default. You <span class="hljs-keyword">do</span> not need to include any additional packages <span class="hljs-keyword">for</span> it. 

For example, <span class="hljs-keyword">if</span> you write and run this code:

<span class="hljs-string">``</span><span class="hljs-string">`julia
A = [
    [1 2 3]
    [4 5 6]
    [7 8 9]
]
B = [
    [7 8 9]
    [4 5 6]
    [1 2 3]
]

A*B</span>
</code></pre>
<p>It will do a matrix multiplication and will output the following result:</p>
<pre><code><span class="hljs-number">3</span>×<span class="hljs-number">3</span> Matrix{Int64}:
 <span class="hljs-number">18</span>   <span class="hljs-number">24</span>   <span class="hljs-number">30</span>
 <span class="hljs-number">54</span>   <span class="hljs-number">69</span>   <span class="hljs-number">84</span>
 <span class="hljs-number">90</span>  <span class="hljs-number">114</span>  <span class="hljs-number">138</span>
</code></pre><p>For additional features, you can import the LinearAlgebra module.</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> LinearAlgebra
</code></pre>
<p>Then, you can use such functions as <code>det</code>, <code>tr</code> or <code>inv</code> with matrices to get their determinants, traces, or inverse matrices, respectively:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> LinearAlgebra

A = [
    [<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>]
    [<span class="hljs-number">4</span> <span class="hljs-number">5</span> <span class="hljs-number">6</span>]
    [<span class="hljs-number">7</span> <span class="hljs-number">8</span> <span class="hljs-number">9</span>]
]
println(<span class="hljs-string">"Determinant: "</span>,det(A))
println(<span class="hljs-string">"Trace: "</span>,tr(A))
println(<span class="hljs-string">"Inverse: "</span>)
inv(A)
</code></pre>
<p>You can learn more about the linear algebra features in the <a target="_blank" href="https://docs.julialang.org/en/v1/stdlib/LinearAlgebra/">LinearAlgebra module documentation</a>.</p>
<h3 id="heading-how-to-work-with-datasets-in-julia">How to Work with Datasets in Julia</h3>
<p>To work with datasets, you have to install an external <code>Dataframes.jl</code> module. In addition, to load and save datasets to CSV files, you have to add the <code>CSV.jl</code> module.</p>
<p>The Julia package manager is implemented as a <code>Pkg</code> module, so, you have to import it and then use the <code>add</code> method to install any required packages. </p>
<p>Run this in your Jupyter notebook to install these packages:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> Pkg
Pkg.add(<span class="hljs-string">"DataFrames"</span>)
Pkg.add(<span class="hljs-string">"CSV"</span>)
</code></pre>
<p>Then, you can import the installed modules to your program:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> DataFrames, CSV
</code></pre>
<p>The DataFrames module imports the <code>DataFrame</code> data type that you will use to construct datasets and manipulate data frame objects. </p>
<h4 id="heading-how-to-create-a-data-frame">How to create a data frame</h4>
<p>This is how you can create a data frame with two columns:</p>
<pre><code class="lang-julia">df = DataFrame(name=[<span class="hljs-string">"Julia"</span>, <span class="hljs-string">"Robert"</span>, <span class="hljs-string">"Bob"</span>,<span class="hljs-string">"Mary"</span>], age=[<span class="hljs-number">12</span>,<span class="hljs-number">15</span>,<span class="hljs-number">45</span>,<span class="hljs-number">32</span>])
</code></pre>
<p>This code will create and output the following dataset:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/basic-df.png" alt="Image" width="600" height="400" loading="lazy">
<em>Persons data frame</em></p>
<h4 id="heading-how-to-select-data-from-a-data-frame">How to select data from a data frame</h4>
<p>To select data from a data frame, you can use the array syntax:</p>
<pre><code class="lang-julia">df[&lt;rows&gt;,&lt;columns&gt;]
</code></pre>
<p>You should specify the range of rows to select in <code>&lt;rows&gt;</code> and the range of columns to select in <code>&lt;columns&gt;</code>. You can use this to select first three rows and only the "age" column:</p>
<pre><code class="lang-julia">subs = df[<span class="hljs-number">1</span>:<span class="hljs-number">3</span>,<span class="hljs-string">"age"</span>]
</code></pre>
<p>It's important to note that array numbering in Julia starts with 1, not with 0 as in most other languages. To select the first three rows and all columns, you can run this:</p>
<pre><code class="lang-julia">subs = df[<span class="hljs-number">1</span>:<span class="hljs-number">3</span>,:]
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/subset2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Select subset of rows from data frame</em></p>
<p>Also, to select a single column, you can use dot syntax:</p>
<pre><code class="lang-julia">names = df.name
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/names-column.png" alt="Image" width="600" height="400" loading="lazy">
<em>Names column</em></p>
<p>As you see, each column is a native Julia array (vector).</p>
<p>You can use conditions to specify row ranges. For example, you can use this code to select all persons from a dataset that are older than 15 years:</p>
<pre><code class="lang-julia">older = df[df.age .&gt;<span class="hljs-number">15</span>,:]
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/older.png" alt="Image" width="600" height="400" loading="lazy">
<em>"older" data frame</em></p>
<p>This code will put all persons who are older than 15 years into the <code>older</code> data frame.</p>
<h4 id="heading-how-to-sort-data-in-a-data-frame">How to sort data in a data frame</h4>
<p>To sort data in a data frame, you can use the <code>sort</code> function. This will sort the dataset by age in ascending order:</p>
<pre><code class="lang-julia">sort(df,<span class="hljs-string">"age"</span>)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/sort_ascending.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sort data frame by age in ascending order</em></p>
<p>And this code will sort it in descending order:</p>
<pre><code class="lang-julia">sort(df,<span class="hljs-string">"age"</span>,rev=<span class="hljs-literal">true</span>)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/sort_descending.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sort data frame by age in descending order</em></p>
<h4 id="heading-how-to-add-columns-to-a-data-frame">How to add columns to a data frame</h4>
<p>To add a new column, just use dot syntax:</p>
<pre><code class="lang-julia">df.sex = [<span class="hljs-string">"female"</span>,<span class="hljs-string">"male"</span>,<span class="hljs-string">"male"</span>,<span class="hljs-string">"female"</span>]
</code></pre>
<p>This added the <code>sex</code> column for persons to the data frame.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/frame_with_sex.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h4 id="heading-how-to-remove-columns-from-a-data-frame">How to remove columns from a data frame</h4>
<p>You can use the <code>select</code> function for more complex data extraction from frames. In particular, you can use it to extract all columns except the one(s) specified, which is equal to removing these columns:</p>
<pre><code class="lang-julia">new_df = select(df,Not(<span class="hljs-string">"sex"</span>))
</code></pre>
<p>This code returns a new data frame by selecting all columns from the original except <code>sex</code>.</p>
<h4 id="heading-how-to-group-and-summarize-data-in-a-data-frame">How to group and summarize data in a data frame</h4>
<p>You can use the <code>groupby</code> and <code>combine</code> functions to group data and show summary information for each group. The former groups data by specified field or fields and the latter adds summary columns to it, like number of rows in each group or average value of some column in the group. </p>
<p>The following code groups data by sex, calculates the number of rows in each group, and adds it as a "count" column:</p>
<pre><code class="lang-julia">group_df = groupby(df,<span class="hljs-string">"sex"</span>)
combine(group_df,nrow =&gt; <span class="hljs-string">"count"</span>)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/group_count.png" alt="Image" width="600" height="400" loading="lazy">
<em>There are two females and two males in this dataset.</em></p>
<p>So, the first line of this code creates a GroupDataFrame object with rows, grouped by "sex". The second line creates the "count" column with count of items in each group. There are 2 females and 2 males in this dataset.</p>
<p>Also, you can use a custom function to calculate summary data. For example, you can use this code to add both row counts and average ages for each group:</p>
<pre><code class="lang-julia">combine(group_df, 
    nrow =&gt; <span class="hljs-string">"count"</span>, 
    <span class="hljs-string">"age"</span> =&gt; ((rows) -&gt; sum(rows)/length(rows)) =&gt; <span class="hljs-string">"Average Age"</span>
)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/group_count_average-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This code adds the "Average Age" column that is produced from the values of the "age" column by applying to it a custom anonymous function that calculates the average of values in this group.</p>
<p>This is just a small sample of all the possible manipulations that you can do with data using the DataFrames.jl library. You can read more about it in the <a target="_blank" href="https://dataframes.juliadata.org/stable/">documentation</a>.</p>
<h3 id="heading-how-to-visualize-data-in-julia">How to Visualize Data in Julia</h3>
<p>Using <a target="_blank" href="https://docs.juliaplots.org/stable/">Plots.jl</a>, you can create a lot of different graphs to analyze your data, similar to <a target="_blank" href="https://matplotlib.org/">Matplotlib</a> or <a target="_blank" href="https://seaborn.pydata.org/">Seaborn</a> in Python. To use it, you have to install the <code>Plots</code> package to your notebook and import it:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> Pkg
Pkg.add(<span class="hljs-string">"Plots"</span>)
<span class="hljs-keyword">using</span> Plots
</code></pre>
<p>Let me provide a few examples of graphs.</p>
<p><strong>Line chart:</strong></p>
<pre><code class="lang-julia">plot([<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>],[<span class="hljs-number">3</span>,<span class="hljs-number">6</span>,<span class="hljs-number">9</span>,<span class="hljs-number">15</span>,<span class="hljs-number">16</span>],title=<span class="hljs-string">"Basic line chart"</span>,label=<span class="hljs-string">"Line"</span>)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/basic_line_chart.png" alt="Image" width="600" height="400" loading="lazy">
<em>Basic line chart</em></p>
<p><strong>Scatter plot:</strong></p>
<pre><code class="lang-julia">plot([<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>],[<span class="hljs-number">3</span>,<span class="hljs-number">6</span>,<span class="hljs-number">9</span>,<span class="hljs-number">15</span>,<span class="hljs-number">16</span>],title=<span class="hljs-string">"Basic scatter plot"</span>,label=<span class="hljs-string">"Data"</span>,seriestype=<span class="hljs-string">"scatter"</span>)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/scatter_plot-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Basic scatter plot</em></p>
<p><strong>Bar chart:</strong></p>
<p>The next code generates a bar chart from the <code>df</code> dataset that we created earlier.</p>
<pre><code class="lang-julia">plot(df.name,df.age,title=<span class="hljs-string">"Ages"</span>,label=<span class="hljs-literal">nothing</span>,seriestype=<span class="hljs-string">"bar"</span>)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/bar_chart.png" alt="Image" width="600" height="400" loading="lazy">
<em>Bar chart</em></p>
<p>There's much more you can do using Plots.js. Read more about its features in the <a target="_blank" href="https://docs.juliaplots.org/stable/">documentation</a>.</p>
<p>After this short overview of basic data science features of Julia, it's time to create and train our first machine learning model and evaluate its quality in the competition.</p>
<h2 id="heading-overview-of-the-titanic-machine-learning-problem-on-kaggle">Overview of the Titanic Machine Learning Problem on Kaggle</h2>
<p>"Titanic - Machine Learning from Disaster" is one of the first educational machine learning problems that you might see in many books, articles, or courses. </p>
<p>In this task you are provided with a dataset of data about Titanic passengers. Each passenger data includes an ID, name, sex, ticket cost, ticket class, cabin number, port of embarkation and number of family members. </p>
<p>For passengers in this dataset, it's known whether they survived or not and the result is recorded in the "Survived" column. If the passenger survived, the value is 1, if not then 0. </p>
<p>Formally, this is called a labeled or <strong>training dataset</strong>. All data columns except one called the "feature matrix", and the "Survived" column called the "labels vector".</p>
<p>There is also the second dataset with the same data about other passengers but without the "Survived" column. In other words, this dataset contains only the features matrix, but does not have the labels vector. This is called the <strong>testing dataset</strong>. </p>
<p>The task is to train a machine learning model on the training dataset and use this model to predict the "Survived" column values in the testing dataset. In other words, its task is to predict the "labels vector" of the testing dataset based on its "features matrix".</p>
<p>The <a target="_blank" href="https://www.kaggle.com/competitions/titanic">Kaggle competition is available here</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/titanic1.png" alt="Image" width="600" height="400" loading="lazy">
<em>The Titanic competition</em></p>
<p>Briefly read through the description, then open the "Evaluation" section to discover how Kaggle will evaluate the predictions that you submit.</p>
<h2 id="heading-how-to-prepare-the-training-data-for-machine-learning">How to Prepare the Training Data for Machine Learning</h2>
<p>The "Data" tab on the Kaggle competition page contains training and testing datasets in <code>train.csv</code> and <code>test.csv</code> files, along with descriptions for each data column.</p>
<p>Create a new Jupyter notebook with a Julia back end and download these files to the same folder with your notebook.</p>
<p>Load <code>train.csv</code> to <code>DataFrames</code> using the CSV module:</p>
<pre><code class="lang-julia"><span class="hljs-comment"># Add packages</span>
<span class="hljs-keyword">using</span> Pkg
Pkg.add(<span class="hljs-string">"DataFrames"</span>)
Pkg.add(<span class="hljs-string">"CSV"</span>)

<span class="hljs-comment"># Import modules</span>
<span class="hljs-keyword">using</span> DataFrames, CSV

<span class="hljs-comment"># Load training data to data frame</span>
train_df = CSV.read(<span class="hljs-string">"train.csv"</span>, DataFrame)
</code></pre>
<p>In case of errors, just make sure to check that the <code>train.csv</code> file exists in the folder where you run your notebook.</p>
<p>If there are no errors, it will show the first rows of the data:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/Train-dataset.png" alt="Image" width="600" height="400" loading="lazy">
<em>Training dataset</em></p>
<p>As you can see, this dataset has 891 rows and 12 columns. This is the basic data about passengers like "Name", "Sex" and "Age". In addition, we see the "Survived" column, with 0 if the passenger did not survive and 1 if they survived.</p>
<p>Let's see the summary information about this data using the <code>describe</code> function:</p>
<pre><code class="lang-julia">describe(train_df)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/data-summarty.png" alt="Image" width="600" height="400" loading="lazy">
<em>Training data summary</em></p>
<p>This summary table shows info about each column. It shows the min, max, mean and median of the data in each of them. The basic goal of the data preparation is to transform these columns to features matrice and labels vector. </p>
<p>The labels vector is ready – this is the "Survived" column with numeric values. All other columns form the features matrix, and not everything is ok with them.</p>
<p>Let's look at the <code>nmissing</code> and <code>eltype</code> for each column. The <code>nmissing</code> shows the number of missing values in the appropriate column, and the <code>eltype</code> shows the type of data values in them. </p>
<p>The matrix should contain only numbers, but there are many columns of "string" data type. Also, the matrix should not have missing values, but we have some missing values in <code>Age</code>, <code>Cabin</code> and <code>Embarked</code> columns. Let's fix all this.</p>
<h3 id="heading-how-to-fix-the-missing-values">How to Fix the Missing Values</h3>
<p>As the previous table shows, the <code>Age</code>, <code>Embarked</code> and <code>Cabin</code> columns contain missing values. The <code>Embarked</code> has blanks in only 2 rows, so we will not lose too much data if just remove these rows.The  DataFrames module has a handy <code>dropmissing</code> function you can use for this:</p>
<pre><code class="lang-julia">train_df = dropmissing(train_df,<span class="hljs-string">"Embarked"</span>)
</code></pre>
<p>This will remove all rows with missing values in the <code>Embarked</code> column.</p>
<p>The <code>Age</code> contains 177 missing values. It's not a good idea to remove these rows, because we will lose about 20% of data in the dataset. So, let's just fill it with something, for example with median value. </p>
<p>The median age is 28 as displayed in the description table. Let's use the <code>replace</code> function of DataFrames to replace the missing ages with a value of 28:</p>
<pre><code class="lang-julia">train_df.Age = replace(train_df.Age,missing=&gt;<span class="hljs-number">28</span>)
</code></pre>
<p>The <code>Cabin</code> column contains 687 missing values, which is more than 50% of the dataset. There are too few data in this column to be useful for predictions. Also, it's difficult to predict which data should be in these rows if more data is missing than exists. So, let's just drop this column using the <code>select</code> function:</p>
<pre><code class="lang-julia">train_df = select(train_df, Not(<span class="hljs-string">"Cabin"</span>))
</code></pre>
<p>Finally, all missing data in the dataset is fixed.</p>
<h3 id="heading-how-to-fix-non-numeric-data">How to Fix Non-Numeric Data</h3>
<p>As I explained before, all data should be encoded to numbers. But we have <code>Name</code>, <code>PassengerId</code>, <code>Sex</code>, <code>Ticket</code> and <code>Embarked</code> as strings. </p>
<p>The <code>Name</code> and the <code>PassengerId</code> values are unique for each passenger, so the ML model can't use them to split the data into categories or classify it. So, you can just remove these columns:</p>
<pre><code class="lang-julia">train_df = select(train_df,Not([<span class="hljs-string">"PassengerId"</span>,<span class="hljs-string">"Name"</span>]));
</code></pre>
<p>For other string columns, we need to encode all text values to numbers. To do that, need to discover all unique values of these columns. Let's start from the <code>Embarked</code>:</p>
<pre><code class="lang-julia">combine(groupby(train_df,<span class="hljs-string">"Embarked"</span>),nrow=&gt;<span class="hljs-string">"count"</span>)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/embarked_group.png" alt="Image" width="600" height="400" loading="lazy">
<em>Embarked categories</em></p>
<p>This code grouped the dataset by the <code>Embarked</code> column and showed all possible values and their counts. So, here there are "S", "C" and "Q" values only. It's easy to encode them as S=1, C=2, and Q=3. You can do this simply with the following <code>replace</code> function:</p>
<pre><code class="lang-julia">train_df.Embarked = <span class="hljs-built_in">Int64</span>.(replace(train_df.Embarked, <span class="hljs-string">"S"</span> =&gt; <span class="hljs-number">1</span>, <span class="hljs-string">"C"</span> =&gt; <span class="hljs-number">2</span>, <span class="hljs-string">"Q"</span> =&gt; <span class="hljs-number">3</span>))
</code></pre>
<p>Also, this code converted the column from "String" to "Int64" data type.</p>
<p>Then, repeat the same for the <code>Sex</code> column:</p>
<pre><code class="lang-julia">combine(groupby(train_df,<span class="hljs-string">"Sex"</span>),nrow=&gt;<span class="hljs-string">"count"</span>)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/sex_group.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sex categories</em></p>
<p>And replace female with 1 and male with 2.</p>
<pre><code class="lang-julia">train_df.Sex = <span class="hljs-built_in">Int64</span>.(replace(train_df.Sex, <span class="hljs-string">"female"</span> =&gt; <span class="hljs-number">1</span>, <span class="hljs-string">"male"</span> =&gt; <span class="hljs-number">2</span>))
</code></pre>
<p>Now it's time to see the summary info for the <code>Ticket</code> column:</p>
<pre><code class="lang-julia">combine(groupby(train_df,<span class="hljs-string">"Ticket"</span>),nrow=&gt;<span class="hljs-string">"count"</span>)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/ticket_group.png" alt="Image" width="600" height="400" loading="lazy">
<em>Ticket categories</em></p>
<p>Here we see that it has 680 different categories of tickets, which is more than 50% of the data. But we need to predict just two categories, either survived or not survived. We're not sure that this data can help the model make good predictions without additional processing to reduce the number of categories in this column. </p>
<p>Although this goes beyond our current basic model, as some additional practice, you can play around some more with the data in this column to improve prediction results. For example, you can try to find out how to group tickets to more general categories and encode these categories by unique numbers. </p>
<p>For now, let's just remove this column:</p>
<pre><code class="lang-julia">train_df = select(train_df,Not(<span class="hljs-string">"Ticket"</span>))
</code></pre>
<p>Now all the string data is categorized, and all values replaced with numbers. Let's describe the dataset again to ensure that all problems with the data have been resolved:</p>
<pre><code class="lang-julia">describe(train_df)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/fixed_train_data.png" alt="Image" width="600" height="400" loading="lazy">
<em>Fixed training dataset</em></p>
<p>You can see that all columns contain only numeric data and there are no missing values in them. </p>
<h3 id="heading-visual-data-analysis">Visual Data Analysis</h3>
<p>Now, we're ready to train a machine learning model on our dataset. Let's visualize this data to find some relationships in it.</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> Plots

<span class="hljs-comment"># Group dataset by "Survived" column</span>
survived = combine(groupby(train_df,<span class="hljs-string">"Survived"</span>), nrow =&gt; <span class="hljs-string">"Count"</span>)

<span class="hljs-comment"># Display the data on bar chart</span>
plot(survived.Survived, survived.Count, title=<span class="hljs-string">"Survived Passengers"</span>, label=<span class="hljs-literal">nothing</span>, seriestype=<span class="hljs-string">"bar"</span>, texts=survived.Count)

<span class="hljs-comment"># Modify X axis to display text labels instead of numbers</span>
xticks!([<span class="hljs-number">0</span>:<span class="hljs-number">1</span>:<span class="hljs-number">1</span>;],[<span class="hljs-string">"Not Survived"</span>,<span class="hljs-string">"Survived"</span>])
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/survived.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Here we see that 340 passengers survived. Now let's see how these passengers are distributed by sex.</p>
<pre><code class="lang-julia"><span class="hljs-comment"># Group dataset by Sex column and show only rows where Survived=1</span>
survived_by_sex = combine(groupby(train_df[train_df.Survived .== <span class="hljs-number">1</span>,:],<span class="hljs-string">"Sex"</span>), nrow =&gt; <span class="hljs-string">"Count"</span>)

<span class="hljs-comment"># Display the data on bar chart </span>
plot(survived_by_sex.Sex, survived_by_sex.Count, title=<span class="hljs-string">"Survived Passengers by Sex"</span>, label=<span class="hljs-literal">nothing</span>, seriestype=<span class="hljs-string">"bar"</span>, texts=survived_by_sex.Count)

<span class="hljs-comment"># Modify X axis to display text labels instead of numbers</span>
xticks!([<span class="hljs-number">1</span>:<span class="hljs-number">1</span>:<span class="hljs-number">2</span>;],[<span class="hljs-string">"Female"</span>,<span class="hljs-string">"Male"</span>])
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/survived_by_sex.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Interesting, there are two times as many females who survived than males in the training dataset. Now let's see the distribution of not survived passengers by ticket class.</p>
<pre><code class="lang-julia"><span class="hljs-comment"># Group dataset by PClass column and show only rows where Survived=0</span>
death_by_pclass = combine(groupby(train_df[train_df.Survived .== <span class="hljs-number">0</span>,:],<span class="hljs-string">"Pclass"</span>), nrow =&gt; <span class="hljs-string">"Count"</span>)

<span class="hljs-comment"># Display the data on bar chart </span>
plot(death_by_pclass.Pclass, death_by_pclass.Count, title=<span class="hljs-string">"Dead Passengers by Ticket class"</span>, label=<span class="hljs-literal">nothing</span>, 
    seriestype=<span class="hljs-string">"bar"</span>, texts=death_by_pclass.Count)

<span class="hljs-comment"># Modify X axis to display text labels instead of numbers</span>
xticks!([<span class="hljs-number">1</span>:<span class="hljs-number">1</span>:<span class="hljs-number">3</span>;],[<span class="hljs-string">"First"</span>,<span class="hljs-string">"Second"</span>,<span class="hljs-string">"Third"</span>])
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/survived_by_pclass.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This clearly shows that first and second class passengers had more chance of survival than third class passangers.</p>
<p>Assuming that data in the training and the testing datasets are distributed randomly, it's highly likely that a machine learning model trained on this data should predict that women in first or second class had a much higher chance of survival than others. </p>
<p>Let's remember this finding to check this hypothesis at the end of the article, after we train and deploy the ML model.</p>
<p>Finally, let's see the cleaned training dataset again:</p>
<pre><code class="lang-julia">train_df
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/data_matrix.png" alt="Image" width="600" height="400" loading="lazy">
<em>The cleaned training set</em></p>
<p>Now it really looks like a matrix – or, to be more precise, like a system of algebraic linear equations written in matrix form. Data in matrix format is exactly what most machine learning algorithms expect to get as an input. Let's get started.</p>
<h2 id="heading-how-to-train-our-machine-learning-model">How to Train Our Machine Learning Model</h2>
<p>For machine learning, we will use the <a target="_blank" href="https://github.com/cstjean/ScikitLearn.jl">SciKitLearn.jl</a> library, which replicates the <a target="_blank" href="https://scikit-learn.org/stable/">SciKit-Learn</a> library for Python. It provides an interface for commonly used machine learning models like Logistic Regression, Decision Tree, or Random Forest. </p>
<p>SciKitLearn.jl is not a single package but a rich ecosystem with many packages, and you need to select which of them to install and import. You can find a list of supported models <a target="_blank" href="https://cstjean.github.io/ScikitLearn.jl/dev/man/models/">here</a>. Some of them are built-in Julia models, others are imported from Python. Also, SciKitLearn.jl has a lot of tools to tune the learning process and evaluate results. </p>
<p>For this "Titanic" task, we will use the <code>RandomForestClassifier</code> model from the <a target="_blank" href="https://juliapackages.com/p/decisiontree">DecisionTree.jl</a> package. Usually it works well for classification problems. Also, we will use the <a target="_blank" href="https://scikit-learn.org/stable/modules/cross_validation.html">Cross Validation</a> module to calculate accuracy of model predictions from the <a target="_blank" href="https://scikitlearnjl.readthedocs.io/en/latest/cross_validation/">SciKitLearn.CrossValidation</a> package. </p>
<p>You have to install and import these packages before using them:</p>
<pre><code class="lang-julia">Pkg.add(<span class="hljs-string">"DecisionTree"</span>)
Pkg.add(<span class="hljs-string">"SciKitLearn"</span>)
<span class="hljs-keyword">using</span> DecisionTree, SciKitLearn.CrossValidation
</code></pre>
<p>Then we will implement the training process. First we need to split the training dataset into <strong>features matrix</strong> and <strong>labels vector</strong>. Then we need to create the <code>RandomForestClassifier</code> model and train it using this data. Finally, we will evaluate a prediction accuracy of this model using the <code>cross_val_score</code> function.</p>
<pre><code class="lang-julia"><span class="hljs-comment"># Put "Survived" column to labels vector</span>
y = train_df[:,<span class="hljs-string">"Survived"</span>]
<span class="hljs-comment"># Put all other columns to features matrix (important to convert to "Matrix" data type)</span>
X = <span class="hljs-built_in">Matrix</span>(train_df[:,Not([<span class="hljs-string">"Survived"</span>])])

<span class="hljs-comment"># Create Random Forest Classifier with 100 trees</span>
model = RandomForestClassifier(n_trees=<span class="hljs-number">100</span>)

<span class="hljs-comment"># Train the model, using features matrix and labels vector</span>
fit!(model,X,y)

<span class="hljs-comment"># Evaluate the accuracy of predictions using Cross Validation</span>
accuracy = minimum(cross_val_score(model, X, y, cv=<span class="hljs-number">5</span>))
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/cross_validation.png" alt="Image" width="600" height="400" loading="lazy">
<em>The accuracy of trained ML model</em></p>
<p>The cross validation splits X and y arrays into 5 parts (folds) and returns the array of accuracies for each of these parts. Then the <code>minimum</code> function selects the worst accuracy from this array, which means that all others are better than the selected one. </p>
<p>Finally, the achieved accuracy is more than 0.78, which is 78% for our training data. It's not bad, but does not guarantee that on the testing dataset the result will be the same.</p>
<p> You can try to improve this value by selecting different models, or by tuning their hyperparameters. </p>
<p>For example, you can increase the number of trees (n_trees) from 100 to 1000 or reduce to 10 and see how it changes the accuracy. After achieving the best result, it's time to use it for predictions.</p>
<h2 id="heading-how-to-make-predictions-and-submit-them-to-kaggle">How to Make Predictions and Submit Them to Kaggle</h2>
<p>Now, when the model is ready, it's time to apply it to data from the <code>test.csv</code> file which does not have the "survived" labels. First we need to load it and look at the summary table as we did for the training dataset:</p>
<pre><code class="lang-julia">test_df = CSV.read(<span class="hljs-string">"test.csv"</span>,DataFrame)
describe(test_df)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/tesing_description.png" alt="Image" width="600" height="400" loading="lazy">
<em>Testing dataset description</em></p>
<p>Here you can see the same problems with the data: missing values and string columns. You need to apply exactly the same transformations to this data as you did in the training dataset – except for removing rows, because the Kaggle requires that you do predictions for each row, so you can only fill in the missing values. </p>
<p>Fortunately, the <code>Embarked</code> column does not have missing values, so there is no need to fix it. This dataset has a single missing value in the <code>Fare</code> column, but we did not have any missing values there in the training set. It's not a big problem, as you can just replace this missing value by the median 14.4542.</p>
<p>But the first thing that we need to do is save the <code>PassengerId</code> column to a separate variable. It will be required later for the Kaggle submission.</p>
<pre><code class="lang-julia">PassengerId = test_df[:,<span class="hljs-string">"PassengerId"</span>]
</code></pre>
<p>Then, apply all the required data fixing techniques:</p>
<pre><code class="lang-julia"><span class="hljs-comment"># Repeat the same transformations as we did for training dataset</span>
test_df = select(test_df,Not([<span class="hljs-string">"PassengerId"</span>,<span class="hljs-string">"Name"</span>,<span class="hljs-string">"Ticket"</span>,<span class="hljs-string">"Cabin"</span>]))
test_df.Age = replace(test_df.Age,missing=&gt;<span class="hljs-number">28</span>)
test_df.Embarked = replace(test_df.Embarked,<span class="hljs-string">"S"</span> =&gt; <span class="hljs-number">1</span>, <span class="hljs-string">"C"</span> =&gt; <span class="hljs-number">2</span>, <span class="hljs-string">"Q"</span> =&gt; <span class="hljs-number">3</span>)
test_df.Embarked = convert.(<span class="hljs-built_in">Int64</span>,test_df.Embarked)
test_df.Sex = replace(test_df.Sex,<span class="hljs-string">"female"</span> =&gt; <span class="hljs-number">1</span>,<span class="hljs-string">"male"</span> =&gt; <span class="hljs-number">2</span>)
test_df.Sex = convert.(<span class="hljs-built_in">Int64</span>,test_df.Sex)

<span class="hljs-comment"># In addition, replace missing value in 'Fare' field with median</span>
test_df.Fare = replace(test_df.Fare,missing=&gt;<span class="hljs-number">14.4542</span>)
</code></pre>
<p>After the testing dataset is clean, you can use the trained model to make predictions:</p>
<pre><code class="lang-julia">Survived = predict(model, <span class="hljs-built_in">Matrix</span>(test_df))
</code></pre>
<p>This code returns an array of predictions for each row of the testing dataset matrix and saves it to the <code>Survived</code> variable.</p>
<p>Now it's time to submit it to Kaggle. Before doing this, look again at the "Evaluation" tab on the Kaggle Titanic competition page to see the required submission format:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/evaluation.png" alt="Image" width="600" height="400" loading="lazy">
<em>Kaggle submission rules description</em></p>
<p>The competition requires a CSV file with two columns: "PassengerId" and "Survived". You already have all this data. Let's create the data frame with these two columns and save it to a CSV file:</p>
<pre><code class="lang-julia">submit_df = DataFrame(PassengerId=PassengerId,Survived=Survived)
CSV.write(<span class="hljs-string">"submission.csv"</span>,submit_df)
</code></pre>
<p>The first line of this code constructs the <code>submit_df</code> data frame with the <code>PassengerId</code> column that was saved previously and the <code>Survived</code> column with predictions for each passenger ID. The second line saves this <code>submit_df</code> to the <code>submission.csv</code> file. This is how the content of this file looks:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/submit_dataframe.png" alt="Image" width="600" height="400" loading="lazy">
<em>Data frame for Kaggle submission</em></p>
<p>Finally, go to the Kaggle competition page, press the "Submit Predictions" button, upload the <code>submission.csv</code> file, and see your result. When I did this, I received the following:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/SUBMIT.png" alt="Image" width="600" height="400" loading="lazy">
<em>Kaggle submission result</em></p>
<p>The prediction accuracy is 0.76555 which is more than 76% and is close to the accuracy that we got on the training dataset. </p>
<p>Not bad for the first time, but you can keep going: play with data, try different models, change their hyperparameters, surf the Internet for articles and Jupyter notebooks of other people who solved the Titanic competition before. I know that it's possible to achieve up to 98% accuracy using various tricks with models and data.</p>
<h2 id="heading-how-to-deploy-the-model-to-production">How to Deploy the Model to Production</h2>
<p>It's fun to play around with machine learning on your computer, but it does not have much impact on real-world problems. </p>
<p>Usually, customers do not have Jupyter Notebooks and they do not train the models. They need to have a simple tool that will help them make decisions based on predictions from data that they have. </p>
<p>That is why the only really important thing is how your models work in production. </p>
<p>In this section, I will explain how to use Julia to create a web application that will load the machine learning model you trained to make predictions online in a web browser.</p>
<h3 id="heading-how-to-export-the-model-to-a-file">How to Export the Model to a File</h3>
<p>First, you need to save the <code>model</code> from the notebook to a file. For this you can use the <a target="_blank" href="https://github.com/JuliaIO/JLD2.jl">JLD2.jl</a> module. This module used to serialize Julia objects to HDF5-compatible format (which is well known by Python data scientists) and save it to a file. </p>
<p>Install and load the package to the notebook:</p>
<pre><code class="lang-julia">Pkg.add(<span class="hljs-string">"JLD2"</span>)
<span class="hljs-keyword">using</span> JLD2
</code></pre>
<p>and then save the <code>model</code> variable to the <code>titanic.jld2</code> file:</p>
<pre><code class="lang-julia">save_object(<span class="hljs-string">"titanic.jld2"</span>, model)
</code></pre>
<p>We're done with our work with Jupyter Notebook now. You should write all the following code as a separate application. </p>
<p>Create a folder for a new application, like <code>titanic</code> for example, and copy the <code>titanic.jld2</code> file to it.</p>
<p>Now you can create a text file <code>titanic.jl</code> which will contain the code of the web application that you will write soon. Use any text editor for this – VS Code with the <a target="_blank" href="https://www.julia-vscode.org/">Julia extension</a> is a good choice. Enter the following code into <code>titanic.jl</code>:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> JLD2, DecisionTree
model = load_object(<span class="hljs-string">"titanic2.jld2"</span>)
survived = predict(model,[<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">35</span> <span class="hljs-number">0</span> <span class="hljs-number">2</span> <span class="hljs-number">144.5</span> <span class="hljs-number">1</span>])
println(survived)
</code></pre>
<p>This code imports the required modules first. As you can see, just two modules are required to run the prediction process: <code>JLD2</code> to load the model object, and <code>DecisionTree</code> to run the <code>predict</code> function for the RandomForestClassifier. </p>
<p>Then, the code loads the model from the file and it makes predictions for a single row of data. The columns in this row should go in the same order as passed from the dataset when we trained the model: <code>Pclass</code>, <code>Sex</code>, <code>Age</code>, <code>SibSp</code>, <code>Parch</code>, <code>Fare</code> and <code>Embarked</code>. </p>
<p>Finally, it prints the array of predictions. In this case, it will print the array with a single item, because only a single row of data was passed to the model for predictions.</p>
<p>You can run this code using the <code>julia</code> command:</p>
<pre><code>julia titanic.jl
</code></pre><p>If everything worked ok, it should print <code>[0]</code> or <code>[1]</code> to the console depending on the prediction result. If you receive errors, then you might need to install the <code>JLD2</code> and <code>DecisionTree</code> packages using the Julia REPL environment, as you did it in the Jupyter notebook.</p>
<p>Now, let's refactor this code to a function that will receive the row of data and return a survival prediction (either 0 or 1):</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> JLD2, DecisionTree

<span class="hljs-comment"># Returns 1 if a passenger with</span>
<span class="hljs-comment"># specified 'data' survived or 0 if not</span>
<span class="hljs-keyword">function</span> isSurvived(data)
    model = load_object(<span class="hljs-string">"titanic2.jld2"</span>)
    survived = predict(model,data)
    <span class="hljs-keyword">return</span> survived[<span class="hljs-number">1</span>]
<span class="hljs-keyword">end</span>
</code></pre>
<h3 id="heading-how-to-create-the-front-end">How to Create the Front End</h3>
<p>The next step is to create a web interface that will be used to collect the <code>data</code> for this function. This will look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/02/ui.png" alt="Image" width="600" height="400" loading="lazy">
<em>Web application user interface</em></p>
<p>With this interface, the user can enter the data about a passenger, then press the "PREDICT" button and discover whether the passenger with this data could survive on the Titanic or not. This is the HTML code for this web page:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Titanic<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">table</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">tbody</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>Ticket class<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"pclass"</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"1"</span>&gt;</span>1<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"2"</span>&gt;</span>2<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"3"</span>&gt;</span>3<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
                    <span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>Sex<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"sex"</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"1"</span>&gt;</span>Female<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>                        
                        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"2"</span>&gt;</span>Male<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
                    <span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>Age<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"age"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span>/&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span># of Siblings/Spouces<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"sibsp"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span>/&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span># of Parents/children<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"parch"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span>/&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>Fare<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"fare"</span>/&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>Embarked<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"embarked"</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"1"</span>&gt;</span>S<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"2"</span>&gt;</span>C<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"3"</span>&gt;</span>Q<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
                    <span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>Survived<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">td</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"survived"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">td</span> <span class="hljs-attr">colspan</span>=<span class="hljs-string">"2"</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span>&gt;</span>PREDICT<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
                    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tbody</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"survived"</span>).innerHTML = <span class="hljs-string">""</span>;
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"submit"</span>).addEventListener(<span class="hljs-string">"click"</span>,<span class="hljs-keyword">async</span>() =&gt; {
            response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"http://localhost:8080"</span>,{
                <span class="hljs-attr">method</span>:<span class="hljs-string">"POST"</span>,
                <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
                    <span class="hljs-string">"pclass"</span>:<span class="hljs-built_in">parseInt</span>(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"pclass"</span>).value),
                    <span class="hljs-string">"sex"</span>:<span class="hljs-built_in">parseInt</span>(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"sex"</span>).value),
                    <span class="hljs-string">"age"</span>:<span class="hljs-built_in">parseFloat</span>(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"age"</span>).value),
                    <span class="hljs-string">"sibsp"</span>:<span class="hljs-built_in">parseInt</span>(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"sibsp"</span>).value),
                    <span class="hljs-string">"parch"</span>:<span class="hljs-built_in">parseInt</span>(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"parch"</span>).value),
                    <span class="hljs-string">"fare"</span>:<span class="hljs-built_in">parseFloat</span>(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"fare"</span>).value),
                    <span class="hljs-string">"embarked"</span>:<span class="hljs-built_in">parseInt</span>(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"embarked"</span>).value),
                })
            });
            <span class="hljs-keyword">const</span> survivedCode =  <span class="hljs-built_in">parseInt</span>(<span class="hljs-keyword">await</span> response.text());
            <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"survived"</span>).innerHTML = survivedCode ? <span class="hljs-string">"YES"</span> : <span class="hljs-string">"NO"</span>
        })
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
        <span class="hljs-selector-tag">input</span>,<span class="hljs-selector-tag">select</span> {
            <span class="hljs-attribute">width</span>:<span class="hljs-number">100%</span>;
        }
        <span class="hljs-selector-tag">td</span> {
            <span class="hljs-attribute">padding</span>:<span class="hljs-number">5px</span>;
        }
        <span class="hljs-selector-tag">td</span> &gt; <span class="hljs-selector-tag">div</span> {
            <span class="hljs-attribute">text-align</span>: center;
        }
        <span class="hljs-selector-id">#survived</span> {
            <span class="hljs-attribute">font-weight</span>: bold;
            <span class="hljs-attribute">color</span>:green;
        }
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Create an <code>index.html</code> file in the same folder and copy this code to it. The HTML part of the file contains a simple form with all data fields. As you can see, all values are encoded to the same numbers as we did with data in training and test datasets. </p>
<p>Then, the JavaScript part of this code defines the handler of the "PREDICT" button. When the user clicks on it, the script collects all entered data and saves it as a JSON string. Then it makes an AJAX request to the web service running on port 8080 of the localhost (which we have not created yet) and sends this JSON to the web service.</p>
<p>So, the web service should be able to receive HTTP POST requests with JSON body in the following format:</p>
<pre><code class="lang-json">{
     <span class="hljs-attr">"pclass"</span>: <span class="hljs-number">1</span>,
        <span class="hljs-attr">"sex"</span>: <span class="hljs-number">1</span>,
        <span class="hljs-attr">"age"</span>: <span class="hljs-number">32</span>,
      <span class="hljs-attr">"sibsp"</span>: <span class="hljs-number">5</span>,
      <span class="hljs-attr">"parch"</span>: <span class="hljs-number">6</span>,
       <span class="hljs-attr">"fare"</span>: <span class="hljs-number">123.44</span>,
   <span class="hljs-attr">"embarked"</span>: <span class="hljs-number">1</span>
}
</code></pre>
<h3 id="heading-how-to-create-the-back-end">How to Create the Back End</h3>
<p>Now it's time to modify the <code>julia.jl</code> file to make it work as a web server that can display the <code>index.html</code> page, receive POST requests from it, parse the body of this request to JSON, make predictions based on this JSON data, and return this prediction to the web page.</p>
<p>Creating a web server on Julia is the same as on Python, Go, or Node.js. By using the HTTP.jl package, you can create and run a web server with a single line of code:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> HTTP

HTTP.serve(handler,<span class="hljs-number">8080</span>)

<span class="hljs-keyword">function</span> handler(req)
    <span class="hljs-comment"># handle HTTP request</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>The <code>HTTP.serve</code> function runs the web server on the specified port. Each time when the web server receives a client request, it calls the specified <code>handler</code> function and sends an HTTP request object to it as a <code>req</code> argument. </p>
<p>The function should read this request, process it, and write a response to the calling client.</p>
<p>The <code>req.url</code> field contains the URL of the received request. The <code>req.method</code> field contains the request method, like GET or POST. The <code>req.body</code> field contains the POST body of the request in binary format. The HTTP request object contains a lot of other information. All this you can find in the HTTP.jl <a target="_blank" href="https://github.com/JuliaWeb/HTTP.jl">documentation</a>. </p>
<p>Our web application will only check the request method. If the received request is a POST request, it will parse <code>req.body</code> to the JSON object and send the data from this object to the <code>isSurvived</code> function to make a prediction and return it to the client browser. </p>
<p>For all other request types, it will just return the content of the <code>index.html</code> file, to display the web interface. </p>
<p>This is how the whole source code of the <code>titanic.jl</code> web service looks:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> JLD2, DecisionTree

<span class="hljs-comment"># Returns 1 if a passenger with</span>
<span class="hljs-comment"># specified 'data' survived or 0 if not</span>
<span class="hljs-keyword">function</span> isSurvived(data)
    model = load_object(<span class="hljs-string">"titanic.jld2"</span>)
    survived = predict(model,data)
    <span class="hljs-keyword">return</span> survived[<span class="hljs-number">1</span>]
<span class="hljs-keyword">end</span>

<span class="hljs-keyword">using</span> HTTP,JSON3

<span class="hljs-keyword">function</span> handle(req)
    <span class="hljs-keyword">if</span> req.method == <span class="hljs-string">"POST"</span>
        form = JSON3.read(<span class="hljs-built_in">String</span>(req.body))
        survived = isSurvived([
            form.pclass
            form.sex
            form.age
            form.sibsp
            form.parch
            form.fare
            form.embarked
        ])
        <span class="hljs-keyword">return</span> HTTP.Response(<span class="hljs-number">200</span>,<span class="hljs-string">"<span class="hljs-variable">$survived</span>"</span>)
    <span class="hljs-keyword">end</span>
    <span class="hljs-keyword">return</span> HTTP.Response(<span class="hljs-number">200</span>,read(<span class="hljs-string">"./index.html"</span>))
<span class="hljs-keyword">end</span>

HTTP.serve(handle, <span class="hljs-number">8080</span>)
</code></pre>
<p>Before running it, you need to install the HTTP.jl package by running <code>Pkg.add("HTTP")</code> in the julia REPL environment.</p>
<p>The web service code goes right after the <code>isSurvived</code> function. First, the required modules are imported: <code>HTTP</code> to create a web server and <code>JSON3</code> to parse JSON from request body. </p>
<p>Then, the <code>handler</code> function gets defined. The function checks the request method of the received requests and if it's equal to POST, it converts the stringified JSON body of this request to the <code>form</code> object. Then, using fields of this object, the <code>isSurvived</code> function gets called. </p>
<p>It's important to put array items in the correct order here. </p>
<p>Finally, the prediction result is returned to the client using the <code>HTTP.Response</code> function.</p>
<p>For all other request types, the function returns the body of the <code>index.html</code> file in the <code>HTTP.Response(200,read("./index.html"))</code> line.</p>
<p>Finally, the <code>HTTP.serve</code> function starts a web server on port 8080 that waits for the HTTP requests and handles them using the <code>handle</code> function, as defined above. </p>
<p>Now you can run this by typing <code>julia titanic.jl</code> in the terminal or by pressing Ctrl+F5 in VSCode. Then you can access the web interface from a web browser on <code>http://localhost:8080</code> and play with the service by entering data in the form, pressing the <code>PREDICT</code> button, and seeing either <code>YES</code> or <code>NO</code> on the <code>Survived</code> line depending on the prediction result. </p>
<p>You can check the hypothesis which we made from bar charts: <em>the women in 1st or 2nd class have more chance of survival than others</em>.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, I introduced you to the Julia programming language along with its ecosystem and explained why it's so great for machine learning. </p>
<p>I showed you how to set up a comfortable development environment and gave a brief overview of the common Julia modules used for data science. </p>
<p>Then I guided you through the process of training the machine learning model for the Titanic competition and showed you how to make predictions and submit them to the Kaggle platform for scoring. </p>
<p>Finally, I showed how to export this model to an external application, create the web service with this model and the web interface to enter data to the form, and predict whether the human with this data could survive on the Titanic or not.</p>
<p>For all topics that explained briefly, I provided the links with more thorough documentation. In addition, I would highly recommend reading this <a target="_blank" href="https://juliadatascience.io/">Julia Data Science online book</a> and studying the great set of machine learning examples in <a target="_blank" href="https://github.com/JuliaAcademy/DataScience">Julia Academy Data Science GitHub repository</a>.</p>
<p>See the source code of this article including the Jupyter Notebook and the web service <a target="_blank" href="https://github.com/AndreyGermanov/julia_titanic_model">in this repository</a>.</p>
<p>Have a fun coding and never stop learning! </p>
<p>You can find me on <a target="_blank" href="https://www.linkedin.com/in/andrey-germanov-dev/">LinkedIn</a>, <a target="_blank" href="https://twitter.com/GermanovDev">Twitter</a>, and <a target="_blank" href="https://www.facebook.com/AndreyGermanovDev">Facebook</a> to know first about new articles like this one and other software development news. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Julia Programming Applications – What is Julia Used For? ]]>
                </title>
                <description>
                    <![CDATA[ By Ifihanagbara Olusheye Julia is a high-level, high-performance dynamic programming language. It combines the ease of use of scripting languages like Python with the speed and efficiency of compiled languages like C/C++.  Julia has been gaining trac... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/applications-of-julia/</link>
                <guid isPermaLink="false">66d45f31230dff016690580b</guid>
                
                    <category>
                        <![CDATA[ Julia ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 18 Jan 2023 21:50:42 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/01/Ifihan-article-cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ifihanagbara Olusheye</p>
<p><a target="_blank" href="https://julialang.org/">Julia</a> is a high-level, high-performance dynamic programming language. It combines the ease of use of scripting languages like Python with the speed and efficiency of compiled languages like C/C++. </p>
<p>Julia has been gaining traction due to its speed, intuitive syntax, and ability to quickly and efficiently solve complex problems.</p>
<p>Being a general-purpose language, you can use Julia in many areas and it can perform various tasks. </p>
<p>In this article, we will be going through various areas where Julia can be applied. I'll also discuss the various packages you can use to get the most out of the language.</p>
<h2 id="heading-julia-programming-use-cases">Julia Programming Use Cases</h2>
<h3 id="heading-machine-learningai">Machine Learning/AI</h3>
<p>This is undoubtedly one of the widest applications of Julia. It is an excellent choice for Machine Learning, as it is highly performant and offers an extensive library of packages for Machine Learning Applications. </p>
<p>The <a target="_blank" href="https://github.com/alan-turing-institute/MLJ.jl">MLJ.jl</a> is a set of tools that provides a centralized interface to standard machine learning algorithms like <a target="_blank" href="https://github.com/JuliaStats/Clustering.jl">clustering</a>, <a target="_blank" href="https://github.com/dmlc/XGBoost.jl">decision trees</a>, and <a target="_blank" href="https://github.com/JuliaStats/GLM.jl">generalized linear models</a>. </p>
<p>Julia also provides deep learning frameworks like <a target="_blank" href="https://github.com/FluxML/Flux.jl">Flux</a> and <a target="_blank" href="https://github.com/denizyuret/Knet.jl">Knet</a>, which makes it easier to work with neural networks.</p>
<h3 id="heading-data-science-and-visualization">Data Science and Visualization</h3>
<p>Another strong application of Julia is in the Data Science field. Julia is well-suited for data science applications, as it is designed to be fast and efficient. It has a wide range of visualization packages you can use to create complex charts and diagrams and perform data analysis. </p>
<p>Examples of libraries include <a target="_blank" href="https://github.com/JuliaPlots/Plots.jl">Plots.jl</a>, <a target="_blank" href="https://github.com/JuliaPlots/Makie.jl">Makie.jl</a> for visualizations, <a target="_blank" href="https://github.com/Evizero/UnicodePlots.jl">UnicodePlots.jl</a> for plotting in the terminal, and <a target="_blank" href="https://github.com/JuliaData/CSV.jl">CSV</a> to read CSV files. </p>
<p>The <a target="_blank" href="https://github.com/JuliaPlots">JuliaPlots</a> GitHub organization contains several packages for Data Visualization in Julia.</p>
<h3 id="heading-web-development">Web Development</h3>
<p>Julia is not left out of the web development space as it has support to create web applications and APIs. </p>
<p>The <a target="_blank" href="https://github.com/GenieFramework/Genie.jl">Genie.jl</a> framework is a notable example that includes all you need to build full-stack applications and APIs (Genie). It also helps you build interactive data applications (Stipple), No-code UI plugins (Genie Builder), and offers an ORM (Searchlight). </p>
<p><a target="_blank" href="https://github.com/tlienart/Franklin.jl">Franklin.jl</a> is another example, and it is used to generate static sites. It is customizable. Examples of other packages include <a target="_blank" href="https://github.com/JuliaWeb/HTTP.jl">HTTP.jl</a>, <a target="_blank" href="https://github.com/plotly/Dash.jl">Dash.jl</a>, <a target="_blank" href="https://github.com/JuliaWeb/WebSockets.jl">WebSockets.jl</a>, <a target="_blank" href="https://github.com/JuliaWeb/Mux.jl">Mux.jl</a>.</p>
<h3 id="heading-graphics">Graphics</h3>
<p>Julia offers powerful graphics libraries with a wide variety of visualization capabilities and interactive features. </p>
<p>Examples of graphic packages are <a target="_blank" href="https://github.com/JuliaGraphics/Luxor.jl">Luxor.jl</a> for drawing vector graphics, <a target="_blank" href="https://github.com/JuliaAnimators/Javis.jl">Javis.jl</a> for making animations, <a target="_blank" href="https://github.com/FluxML/Flux3D.jl">Flux3D.jl</a>, and <a target="_blank" href="https://github.com/JuliaGPU/Vulkan.jl">Vulkan.jl</a>.</p>
<h3 id="heading-parallel-computing">Parallel Computing</h3>
<p>With built-in components for parallel programming at every level, Julia was created with parallelism in mind. Julia provides in-built <a target="_blank" href="https://docs.julialang.org/en/v1/manual/multi-threading/">multi-threading</a> to enable multiple tasks to be executed in parallel within a single process or program, <a target="_blank" href="https://docs.julialang.org/en/v1/manual/distributed-computing/">multi-processing, and distributed computing</a> to enable computers to take on larger tasks. </p>
<p>Packages you can use in this scope include <a target="_blank" href="https://github.com/chriselrod/LoopVectorization.jl">LoopVectorization.jl</a>, <a target="_blank" href="https://github.com/JuliaParallel/Dagger.jl">Dagger.jl</a>, and <a target="_blank" href="https://github.com/JuliaParallel/DistributedArrays.jl">DistributedArrays.jl</a>.</p>
<h3 id="heading-robotics">Robotics</h3>
<p>Julia is suitable for robotics applications since it enables speedy algorithm testing and development. </p>
<p>For instance, the <a target="_blank" href="https://github.com/JuliaRobotics">JuliaRobotics</a> GitHub Organization offers a selection of tools for Julia robotics development. It contains 3D visualization, motion planning, robot control, and simulation libraries. The <a target="_blank" href="https://juliarobotics.org/">JuliaRobotics</a> project also offers lessons and starter projects for those new to robotics in Julia. </p>
<p>You can also use Julia with a wide variety of current robotics libraries and frameworks, including Robot Operating System (ROS). Examples of packages you can use are <a target="_blank" href="https://github.com/JuliaRobotics/RigidBodyDynamics.jl">RigidBodyDynamics.jl</a>, <a target="_blank" href="https://github.com/JuliaRobotics/Caesar.jl">Caesar.jl</a>, and <a target="_blank" href="https://github.com/JuliaRobotics/MeshCatMechanisms.jl">MeshCatMechanisms.jl</a>.</p>
<h3 id="heading-scientific-computing">Scientific Computing</h3>
<p>Julia has a robust ecosystem of libraries focused on scientific computing and an effective inbuilt package manager to install and manage dependencies. </p>
<p>And bcause of its threading, distributed memory parallelization, and GPU computing capabilities, it is also making progress in high-performance scientific computing. </p>
<p>Packages like <a target="_blank" href="https://github.com/SciML/DifferentialEquations.jl">DifferentialEquations.jl</a> for the differential equations ecosystem, <a target="_blank" href="https://github.com/jump-dev/JuMP.jl">JuMP.jl</a> for Optimization and Operations Research, <a target="_blank" href="https://github.com/JuliaLinearAlgebra/IterativeSolvers.jl">IterativeSolvers.jl</a> for iterative algorithms in solving linear systems, and <a target="_blank" href="https://github.com/JuliaMath/AbstractFFTs.jl">AbstractFFTs.jl</a> for implementing Fast Fourier Transforms (FFTs) are available to use.</p>
<h3 id="heading-audio-development">Audio Development</h3>
<p>You can do audio processing, recording, development, manipulating, controlling, and other related tasks in Julia. </p>
<p>Some of the packages that support these abilities are <a target="_blank" href="https://github.com/dancasimiro/WAV.jl">WAV.jl</a>, <a target="_blank" href="https://github.com/JuliaAudio/PortAudio.jl">PortAudio.jl</a>, and <a target="_blank" href="https://github.com/JuliaMusic/MIDI.jl">MIDI.jl</a>. You can find other packages in the <a target="_blank" href="https://github.com/JuliaAudio">JuliaAudio</a> GitHub repo. For Music libraries, there are several packages in the <a target="_blank" href="https://github.com/JuliaMusic">JuliaMusic</a> GitHub repo.</p>
<h3 id="heading-game-development">Game Development</h3>
<p>From creation to designing, programming, and producing games, Julia can be a go-to for game development. </p>
<p>Popular packages include <a target="_blank" href="https://github.com/jhigginbotham64/Starlight.jl">Starlight.jl</a>, a “greedy application framework for greedy developers” for building mainly video games, along with <a target="_blank" href="https://github.com/aviks/GameZero.jl">GameZero.jl</a>, and <a target="_blank" href="https://github.com/AliceRoselia/Nebula.jl">Nebula.jl</a>.</p>
<p>There are other areas that show potential for Julia but that are still being developed. For instance, in the App/Mobile development area, it is still underdeveloped and immature. An example of an existing library in this field is <a target="_blank" href="https://github.com/JuliaGraphics/Gtk.jl">GTK.jl</a>, the Julia interface to Gtk windowing toolkit.</p>
<h2 id="heading-industries-where-julia-excels">Industries Where Julia Excels</h2>
<p>After looking at the several areas where Julia can be applied, let's learn about the industries and institutions where Julia can be practically used. Some of them include:</p>
<h3 id="heading-banking-and-finance">Banking and Finance</h3>
<p>Julia can be used to create highly-developed financial models. Its libraries, like Plot.jl along with several others for data analysis and visualization, let you analyze and visualize market data and make decisions from the results.</p>
<h3 id="heading-biology-and-biotechnology">Biology and Biotechnology</h3>
<p>You can use Julia in the field of Biotechnology in several ways. For example, Julia can help you develop models that help predict the effects of specific treatments on biological systems. </p>
<p>You can also use Julia analyze big datasets obtained from biological experiments, create visualizations to help understand the datasets, and even develop algorithms. And you can use it to simulate biological processes and develop Artificial Intelligence applications. </p>
<p><a target="_blank" href="https://biojulia.net/">BioJulia</a> is an example of an organization that is in the Biology industry.</p>
<h3 id="heading-economics">Economics</h3>
<p>In addition to the languages used for Economic analysis like R and Python, you can use Julia in the Economics sector. </p>
<p>You can also use Julia for quantitative economics, to analyze data, and optimize problems. <a target="_blank" href="https://julia.quantecon.org/">QuantEcon</a> is a great place to begin the journey of Economics with Julia.</p>
<h3 id="heading-mathematics">Mathematics</h3>
<p>Julia is particularly suited for mathematical and scientific computing. It offers an extensive set of libraries to perform mathematical operations, including linear algebra, numerical analysis, Fourier transforms, and optimization.</p>
<h3 id="heading-natural-sciences">Natural Sciences</h3>
<p>Every computational second counts when it comes to climate modeling. Scientists can use Julia to quickly and easily develop data analysis and visualization tools, numerical solutions, and scientific computing applications. </p>
<p>Julia's numerical computing capabilities enable scientists to solve complex mathematical problems easily.</p>
<h3 id="heading-medicine-and-pharmacy">Medicine and Pharmacy</h3>
<p>Julia is widely used in the fields of medicine and pharmacy research. Researchers use Julia to analyze large datasets to determine the effectiveness of drugs, understand the long-term effects of treatments, and simulate and develop new treatments. </p>
<p>You can also use Julia to create predictive models and to identify patterns in data. In medicine, you can use Julia to develop medical-grade simulations for medical imaging to study and analyze medical conditions. It can also be used to analyze medical data.</p>
<h3 id="heading-technological-industries">Technological Industries</h3>
<p>In view of the fact that Julia is very fast and easy to use, technological companies are staring to use the language more and more. </p>
<p>Companies and institutions like MIT, NASA, BlackRock, Pumas-AI, Pfizer, Microsoft, Google, IBM, and many more have adopted Julia for various tasks and projects.</p>
<h3 id="heading-energy">Energy</h3>
<p>In the energy sector, Julia can be used to analyze large datasets, develop models and simulations, and create applications for energy management and conservation. </p>
<p>It can also be used to develop energy forecasting models, simulate energy production and consumption, and create energy management applications. Additionally, machine learning algorithms can be developed with Julia for predicting energy usage and cost.</p>
<p>There are several other sectors where Julia can be used, like Sports and 3D printing. More including real life cases where Julia is used can be found in the <a target="_blank" href="https://juliahub.com/case-studies/">JuliaHub case studies</a>. </p>
<p>A variety of Julia GitHub repos provide libraries for different applications. You can find them in the <a target="_blank" href="https://julialang.org/community/organizations/">Community Section</a> of the Julia Language’s official website.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Overall, Julia is an excellent choice for those who want to maximize the results of their machine learning and data science projects. </p>
<p>It is a language for a range of applications because of its robust libraries, simple syntax, and fast speeds. Julia is a great option for completing tasks quickly and effectively, whether it's data visualization, data analysis, or machine learning.</p>
<p>Julia is versatile and resourceful and has applications in many fields. Julia is relatively easy to learn, and its scalability and ability to handle large data sets make it an attractive choice for many applications. </p>
<p>With its growing popularity, Julia is sure to become one of the more widely used languages for various applications in the future.</p>
<h2 id="heading-references">References</h2>
<p>Special thanks to the people of the <a target="_blank" href="https://discord.gg/C5h9D4j">Humans of Julia Discord serve</a>r for sharing resources in different channels and answering questions. Also attached are vital references for the article.</p>
<ul>
<li><a target="_blank" href="https://julialang.org/">Julia Language’s official website</a>.</li>
<li><a target="_blank" href="https://julialang.org/learning/tutorials/">Julia Tutorials</a>.</li>
<li><a target="_blank" href="https://juliapackages.com/">Julia Packages</a>.</li>
<li><a target="_blank" href="https://enccs.github.io/Julia-for-HPC/">Julia for high-performance scientific computing</a>.</li>
<li><a target="_blank" href="https://discourse.julialang.org/">Julia Discourse Channel</a>.</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Julia by Coding 7 Projects – Hands-On Programming Tutorial ]]>
                </title>
                <description>
                    <![CDATA[ By Logan Kilpatrick The Julia programming language is used for a lot of really impactful and interesting challenges like Machine Learning and Data Science.  But before you can get to the complex stuff, it is worth exploring the basics to develop a so... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-julia-by-coding-7-projects/</link>
                <guid isPermaLink="false">66d46015f855545810e93497</guid>
                
                    <category>
                        <![CDATA[ Julia ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Julialang ]]>
                    </category>
                
                    <category>
                        <![CDATA[ projects ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 28 Oct 2022 23:54:26 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/10/7-projects-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Logan Kilpatrick</p>
<p>The Julia programming language is used for a lot of really impactful and interesting challenges like Machine Learning and Data Science. </p>
<p>But before you can get to the complex stuff, it is worth exploring the basics to develop a solid foundation. </p>
<p>In this tutorial, we will go over some of the basics of Julia by building 7 small Julia projects:</p>
<ul>
<li>Mad Libs ✍️</li>
<li>Guess the Number Game 💯</li>
<li>Computer Number Guesser 🤖</li>
<li>Rock 🗿, Paper 📃, Scissors ✂️</li>
<li>Password Generator 🎫</li>
<li>Dice Rolling Simulator 🎲</li>
<li>Countdown Timer ⏱️</li>
</ul>
<p>If you have not downloaded Julia yet, head to: <a target="_blank" href="https://julialang.org/downloads/">https://julialang.org/downloads/</a> or watch this video:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/t67TGcf4SmM" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>It's also worth noting that if you are totally new to Julia and want a comprehensive introduction to the language, you can <a target="_blank" href="https://www.freecodecamp.org/news/learn-julia-programming-language/">check out this freeCodeCamp article</a>.</p>
<h2 id="heading-beginner-friendly-julia-projects">Beginner-Friendly Julia Projects</h2>
<h3 id="heading-how-to-build-mad-libs-in-julia">How to Build Mad Libs in Julia ✍️</h3>
<p>In Mad Libs, the user is prompted to enter different types of words. The random words the user enters are then inserted into a sentence. This leads to some pretty wacky and funny outcomes. Let's try to program a simple version of this using Julia.</p>
<p>At the core of this problem, we want to concatenate (or add together) multiple strings so that we go from a sentence with some placeholders, to a sentence with the user input. </p>
<p>The simplest way to achieve this in Julia is with String Interpolation:</p>
<pre><code class="lang-julia">julia&gt; name = <span class="hljs-string">"Logan"</span>
<span class="hljs-string">"Logan"</span>

julia&gt; new_string = <span class="hljs-string">"Hello, my name is <span class="hljs-variable">$name</span>"</span>
<span class="hljs-string">"Hello, my name is Logan"</span>
</code></pre>
<p>Here we can see that we can insert the name variable we defined into the string by using the <code>$name</code> syntax.</p>
<p>There are a bunch of other ways to do this, like using the <code>string</code> function:</p>
<pre><code class="lang-julia">julia&gt; new_string = string(<span class="hljs-string">"Hello, my name is "</span>, name)
<span class="hljs-string">"Hello, my name is Logan"</span>
</code></pre>
<p>but string interpolation seems the most straightforward and readable in this case.</p>
<p>Now that we know how we are going to set up the strings, we need to prompt the user for their input. </p>
<p>To do this, we can use the <code>readline</code> function as follows:</p>
<pre><code class="lang-julia">julia&gt; my_name = readline()
Logan
<span class="hljs-string">"Logan"</span>
</code></pre>
<p>The <code>readline</code> function takes a single line of input from the user. This is exactly what we will want to use. Let’s put it all together into a simple example:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">function</span> play_mad_libs()

    print(<span class="hljs-string">"Enter a verb (action): "</span>)
    verb1 = readline()

    print(<span class="hljs-string">"Enter an adjective (descriptive word): "</span>)
    adj1 = readline()

    print(<span class="hljs-string">"Enter a noun (person place or thing): "</span>)
    noun1 = readline()

    print(<span class="hljs-string">"Enter another noun (person place or thing): "</span>)
    noun2 = readline()

    print(<span class="hljs-string">"Enter a catchphrase (something like 'hands up!'): "</span>)
    phrase1 = readline()

    base_sentence = <span class="hljs-string">"John <span class="hljs-variable">$verb1</span> down the street one night, playing with his <span class="hljs-variable">$adj1</span> <span class="hljs-variable">$noun1</span>. When all of a / sudden, a <span class="hljs-variable">$noun2</span> jumped out at him and said <span class="hljs-variable">$phrase1</span>"</span>

    print(<span class="hljs-string">"\n\n"</span>, base_sentence)
<span class="hljs-keyword">end</span>

<span class="hljs-comment"># Link to source code: https://github.com/logankilpatrick/Julia-Projects-for-Beginners/blob/main/madlibs.jl</span>
</code></pre>
<p>In this example, we learned how to work with strings, define a function, use print statements, and more! </p>
<p>As noted before, there are lots of other ways to do the same things we did above. So if you want to find out more about working with strings, <a target="_blank" href="https://docs.julialang.org/en/v1/manual/strings/">check out the Julia docs here</a>.</p>
<h3 id="heading-how-to-build-a-guess-the-number-game-in-julia">How to Build a Guess the Number Game in Julia 💯</h3>
<p>In this game, we will have to generate a random number and then try to guess what it is. </p>
<p>To begin, we will need to generate a random number. As always, there are many ways to do something like this but the most straightforward approach is to do the following:</p>
<pre><code class="lang-julia">julia&gt; rand(<span class="hljs-number">1</span>:<span class="hljs-number">10</span>)
<span class="hljs-number">4</span>
</code></pre>
<p>The <code>rand</code> function takes as input the range of numbers you want to use as the bounds for the number you will generate. In this case, we set the range as <code>1-10</code>, inclusive of both numbers.</p>
<p>The other new topic we need to cover for this example to work is while loops. The basic structure of a while loop is:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">while</span> some_condition is <span class="hljs-literal">true</span>
   <span class="hljs-keyword">do</span> something
<span class="hljs-keyword">end</span>
</code></pre>
<p>This loop will continue to iterate until the condition for the while loop is no longer met. You will see how we use this soon to keep prompting the user to enter a number until they guess it right.</p>
<p>Lastly, to make it a little easier for us, we are going to add an if statement which tells us if we guess a number that is close to the target number. The structure of an if statement in Julia is:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">if</span> some_condition is <span class="hljs-literal">true</span>
   <span class="hljs-keyword">do</span> something
<span class="hljs-keyword">end</span>
</code></pre>
<p>The big difference is that the if statement is checked once and then it is done. The initial condition is not re-checked unless the if statement is in a loop.</p>
<p>Now that we have the basic ideas down, let's see the actual code to build the number guesser. Make sure you try this on your own before checking the solution below. Happy coding! 🎉</p>
<pre><code class="lang-julia"><span class="hljs-comment"># Number Guessing Game in Julia</span>
<span class="hljs-comment"># Source: https://github.com/logankilpatrick/10-Julia-Projects-for-Beginners</span>

<span class="hljs-keyword">function</span> play_number_guess_human()

    total_numbers = <span class="hljs-number">25</span> <span class="hljs-comment"># </span>

    <span class="hljs-comment"># Generate a random number within a certain range</span>
    target_number = rand(<span class="hljs-number">1</span>:total_numbers)
    guess = <span class="hljs-number">0</span>

    <span class="hljs-comment"># While the number has not been guessed, keep prompting for guesses</span>
    <span class="hljs-keyword">while</span> guess != target_number
        print(<span class="hljs-string">"Please guess a number between 1 and <span class="hljs-variable">$total_numbers</span>: "</span>)
        guess = parse(<span class="hljs-built_in">Int64</span>, readline())
        <span class="hljs-comment"># Convert the string value input to a number</span>

        <span class="hljs-comment"># If we are within +/-2 of the target, give a hint</span>
        <span class="hljs-keyword">if</span> abs(target_number - guess) &lt;= <span class="hljs-number">2</span> &amp;&amp; target_number != guess
            print(<span class="hljs-string">"\nYou are getting closer!\n"</span>)
        <span class="hljs-keyword">end</span>
    <span class="hljs-keyword">end</span>

    print(<span class="hljs-string">"Nice job, you got it!"</span>)
<span class="hljs-keyword">end</span>
</code></pre>
<h3 id="heading-how-to-build-a-computer-number-guesser-in-julia">How to Build a Computer Number Guesser in Julia 🤖</h3>
<p>Now that we have seen what it looks like for us to try and guess what the computer randomly generated, let's see if the computer can do any better. </p>
<p>In this game, we will select a number and then see how long it takes the computer to guess that number. To do this, we will introduce some new concepts like the Random module and for loops.</p>
<p>We'll begin by thinking about how we can have the computer guess random numbers without repeating any. </p>
<p>One simple solution is to use the <code>rand</code> function, but the issue is that there’s no built-in way to make sure the computer doesn’t guess the same number more than once – since, after all, it is random!</p>
<p>We can solve this issue by combining the <code>collect</code> function and the <code>shuffle</code> function. We begin by defining a random seed:</p>
<pre><code class="lang-julia">julia&gt; rng = <span class="hljs-built_in">MersenneTwister</span>(<span class="hljs-number">1234</span>);
</code></pre>
<p>Random seeds make it so that random number generators make reproducible results. Next, we need to define all possible guesses:</p>
<pre><code class="lang-julia">julia&gt; a = collect(<span class="hljs-number">1</span>:<span class="hljs-number">50</span>)
<span class="hljs-number">50</span>-element <span class="hljs-built_in">Vector</span>{<span class="hljs-built_in">Int64</span>}:
<span class="hljs-number">1</span>
<span class="hljs-number">2</span>
<span class="hljs-number">3</span>
⋮
</code></pre>
<p>We now need to use the <code>shuffle</code> function to make the guesses random:</p>
<pre><code class="lang-julia">julia&gt; <span class="hljs-keyword">using</span> Random
julia&gt; shuffle(rng, a)
<span class="hljs-number">50</span>-element <span class="hljs-built_in">Vector</span>{<span class="hljs-built_in">Int64</span>}:
<span class="hljs-number">41</span>
<span class="hljs-number">23</span>
<span class="hljs-number">13</span>
<span class="hljs-number">49</span>
⋮
</code></pre>
<p>Now that we have the random guesses set up, it's time to loop through them one at a time and see if the number is equal to the target the user inputted. </p>
<p>Again, give this a try before you check out the solution below:</p>
<pre><code class="lang-julia"><span class="hljs-comment"># Computer Number Guessing Game in Julia</span>
<span class="hljs-comment"># Source: https://github.com/logankilpatrick/10-Julia-Projects-for-Beginners</span>

<span class="hljs-keyword">using</span> Random

<span class="hljs-keyword">function</span> play_number_guess_computer()

    print(<span class="hljs-string">"Please enter a number between 1 and 50 for the computer to try and guess: "</span>)

    <span class="hljs-comment"># Take in the user input and convert it to a number</span>
    target_number = parse(<span class="hljs-built_in">Int64</span>, readline())

    <span class="hljs-comment"># Create an array of 50 numbers</span>
    guess_order = collect(<span class="hljs-number">1</span>:<span class="hljs-number">50</span>)

    <span class="hljs-comment"># Define our random seed</span>
    rng = <span class="hljs-built_in">MersenneTwister</span>(<span class="hljs-number">1234</span>)

    <span class="hljs-comment"># Shuffle the array randomly given our seed</span>
    shuffled_guess = shuffle(rng, guess_order)

    <span class="hljs-comment"># Loop through each guess and see if it's right</span>
    <span class="hljs-keyword">for</span> guess <span class="hljs-keyword">in</span> shuffled_guess

        <span class="hljs-keyword">if</span> guess == target_number
            print(<span class="hljs-string">"\nThe computer cracked the code and guessed it right!"</span>)
            <span class="hljs-keyword">break</span> <span class="hljs-comment"># Stop the for loop if we get it right</span>
        <span class="hljs-keyword">end</span>

        print(<span class="hljs-string">"\nComputer guessed: <span class="hljs-variable">$guess</span>"</span>)
    <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<h3 id="heading-how-to-build-rock-paper-scissors-in-julia">How to Build Rock 🗿, Paper 📃, Scissors ✂️ in Julia</h3>
<p>If you have never played rock, paper, scissors, you are missing out! The basic gist is you try to beat your opponent with either rock, paper, or scissors. </p>
<p>In this game, rock beats scissors, scissors beat paper, and paper beats rock. If two people do the same one, you go again.</p>
<p>In this example, we will be playing rock, paper, scissors against the computer. We will also use the <code>sleep</code> function to introduce a short delay as if someone was saying the words out loud (which you would do if you played in person).</p>
<p>The sleep function takes in a number that represents how long you want (in seconds) to sleep. We can use this with a function or a loop to slow things down as you will see in this game.</p>
<pre><code class="lang-julia">sleep(<span class="hljs-number">1</span>) <span class="hljs-comment"># Sleep for 1 second</span>
</code></pre>
<p>Let's also explore a function I found while writing this tutorial, <code>Base.prompt</code> , which helps us do what we were previously using <code>readline</code> for. </p>
<p>In this case, however, <code>prompt</code> auto-appends a <code>:</code> to the end of the line and allows us to avoid having two separate lines for the print and user input:</p>
<pre><code class="lang-julia">human_move = Base.prompt(<span class="hljs-string">"Please enter 🗿, 📃, or ✂️"</span>)
</code></pre>
<p>We will also need to use an <code>elseif</code> to make this example game work. We can chain <code>if</code> , <code>elseif</code> , and <code>else</code> together for completeness. Try putting together the if conditionals, prompts, and sleeps to get the desired behavior, and then check out the code below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/10/1-406j3f0e3nN-VxRJUUtK7A.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Gif of playing Rock Paper Scissors in the Julia REPL</em></p>
<pre><code class="lang-julia"><span class="hljs-comment"># Rock 🗿, Paper 📃, Scissors ✂️ Game in Julia</span>

<span class="hljs-keyword">function</span> play_rock_paper_scissors()
    moves = [<span class="hljs-string">"🗿"</span>, <span class="hljs-string">"📃"</span>, <span class="hljs-string">"✂️"</span>]
    computer_move = moves[rand(<span class="hljs-number">1</span>:<span class="hljs-number">3</span>)]

    <span class="hljs-comment"># Base.prompt is similar to readline which we used before</span>
    human_move = Base.prompt(<span class="hljs-string">"Please enter 🗿, 📃, or ✂️"</span>)
    <span class="hljs-comment"># Appends a ": " to the end of the line by default</span>

    print(<span class="hljs-string">"Rock..."</span>)
    sleep(<span class="hljs-number">0.8</span>)

    print(<span class="hljs-string">"Paper..."</span>)
    sleep(<span class="hljs-number">0.8</span>)

    print(<span class="hljs-string">"Scissors..."</span>)
    sleep(<span class="hljs-number">0.8</span>)

    print(<span class="hljs-string">"Shoot!\n"</span>)

    <span class="hljs-keyword">if</span> computer_move == human_move
        print(<span class="hljs-string">"You tied, please try again"</span>)
    <span class="hljs-keyword">elseif</span> computer_move == <span class="hljs-string">"🗿"</span> &amp;&amp; human_move == <span class="hljs-string">"✂️"</span>
        print(<span class="hljs-string">"You lose, the computer won with 🗿, please try again"</span>)
    <span class="hljs-keyword">elseif</span> computer_move == <span class="hljs-string">"📃"</span> &amp;&amp; human_move == <span class="hljs-string">"🗿"</span>
        print(<span class="hljs-string">"You lose, the computer won with 📃, please try again"</span>)
    <span class="hljs-keyword">elseif</span> computer_move == <span class="hljs-string">"✂️"</span> &amp;&amp; human_move == <span class="hljs-string">"📃"</span>
        print(<span class="hljs-string">"You lose, the computer won with ✂️, please try again"</span>)
    <span class="hljs-keyword">else</span>
        print(<span class="hljs-string">"You won, the computer lost with <span class="hljs-variable">$computer_move</span>, nice work!"</span>)
    <span class="hljs-keyword">end</span>

<span class="hljs-keyword">end</span>
</code></pre>
<h3 id="heading-how-to-build-a-password-generator-in-julia">How to Build a Password Generator in Julia 🎫</h3>
<p><strong>WARNING: Do not use this code to generate real passwords!</strong></p>
<p>In the age of endless data breaches and people using the same password for every website, having a secure password is important. In this example, we will generate an arbitrary number of passwords with a variable length. </p>
<p>Given that this could take a long time, we will also add an external package, <a target="_blank" href="https://github.com/cloud-oak/ProgressBars.jl">ProgressBars.jl</a>, to visually show the progress of our for loop. If you have never added an external package before, consider <a target="_blank" href="https://blog.devgenius.io/the-most-underrated-feature-of-the-julia-programming-language-the-package-manager-652065f45a3a">checking out this robust tutorial</a> on why the package manager is the most underrated feature of the Julia programming language.</p>
<p>To add a Julia package, open the REPL and type <code>]</code> followed by <code>add ProgressBars</code>. After that, as we did with the Random module (note we did not need to add it since it is part of base Julia), we can say <code>using ProgressBars</code> to load it in.</p>
<p>The main new idea we will introduce here is vectors / arrays. In Julia, we can put any type into an array. To create an empty array, we do:</p>
<pre><code class="lang-julia">password_holder = []
</code></pre>
<p>and then to add something, we use the <code>push!</code> function as you will see in the below example. </p>
<p>As mentioned before, we will use the ProgressBars package to show progress on the screen. Note that Julia is so quick that it likely won’t show you the loading screen unless you manually slow things down with a sleep function call or a high number of passwords. Check out the README for an example of using this in practice. </p>
<p>As with the other example, try to put some code together before you dissect the example below:</p>
<pre><code class="lang-julia"><span class="hljs-comment"># Generate Passwords in Julia</span>
<span class="hljs-comment"># Source: https://github.com/logankilpatrick/10-Julia-Projects-for-Beginners</span>
<span class="hljs-keyword">using</span> ProgressBars
<span class="hljs-keyword">using</span> Random

<span class="hljs-comment"># WARNING: Do not use this code to generate actual passwords!</span>
<span class="hljs-keyword">function</span> generate_passwords()
    num_passwords = parse(<span class="hljs-built_in">Int64</span>, Base.prompt(<span class="hljs-string">"How many passwords do you want to generate?"</span>))
    password_length = parse(<span class="hljs-built_in">Int64</span>, Base.prompt(<span class="hljs-string">"How long should each password be?"</span>))

    <span class="hljs-comment"># Create an empty vector / array</span>
    password_holder = []

    <span class="hljs-comment"># Generate a progress bar to show how close we are to being done</span>
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> ProgressBar(<span class="hljs-number">1</span>:num_passwords)
        <span class="hljs-comment"># Add the new password into the password holder</span>
        push!(password_holder, randstring(password_length))
        sleep(<span class="hljs-number">0.2</span>) <span class="hljs-comment"># Manually slowdown the generation of passwords</span>
    <span class="hljs-keyword">end</span>

    <span class="hljs-comment"># Only show the passwords if there are less than 100</span>
    <span class="hljs-keyword">if</span> length(password_holder) &lt;= <span class="hljs-number">100</span>
        <span class="hljs-comment"># Loop through each password one by one</span>
        <span class="hljs-keyword">for</span> password <span class="hljs-keyword">in</span> password_holder
            print(<span class="hljs-string">"\n"</span>, password)
        <span class="hljs-keyword">end</span>
    <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<h3 id="heading-how-to-build-a-dice-rolling-simulator-in-julia">How to Build a Dice Rolling Simulator in Julia 🎲</h3>
<p>Dice are a fun way to explore and play around with randomness along with unicode characters. </p>
<p>Julia has amazing support for unicode, and if you want to see all the characters it supports, <a target="_blank" href="https://docs.julialang.org/en/v1/manual/unicode-input/">head to the Julia docs</a>. </p>
<p>Let's begin by defining an array of dice faces. To access unicode characters, we can use the Julia REPL to do tab completion by typing the following:</p>
<pre><code class="lang-julia">julia&gt; \dicei
</code></pre>
<p>followed by the tab button. This will create <code>⚀</code> which is "Die Face-1". If we do this for all 6 sides of a 6 sided die, we end up with:</p>
<pre><code class="lang-julia">dice_faces = [<span class="hljs-string">"⚀"</span>, <span class="hljs-string">"⚁"</span>, <span class="hljs-string">"⚂"</span>, <span class="hljs-string">"⚃"</span>, <span class="hljs-string">"⚄"</span>, <span class="hljs-string">"⚅"</span>]
</code></pre>
<p>For this game, we want to continually ask the user if they want to roll the dice. If they do, we generate a random number between 1 and 6 and then display the dice face from the array we created above. </p>
<p>Just like we did in previous projects, we will want to use the <code>rand</code> function as follows:</p>
<pre><code class="lang-julia">rand(<span class="hljs-number">1</span>:num_sides_dice)
</code></pre>
<p>Give this a try before you check out one possible solution that is highlighted below and keep in mind how we could extend this or use this code to program a much larger game like Monopoly. </p>
<pre><code class="lang-julia"><span class="hljs-comment"># Code from https://github.com/logankilpatrick/Julia-Projects-for-Beginners</span>

<span class="hljs-keyword">function</span> rolling_dice()

    <span class="hljs-comment"># Number of sides for dice</span>
    num_sides_dice = <span class="hljs-number">6</span>

    <span class="hljs-comment"># While the user wants to roll a die, continue to generate a number between 1 and the number of sides</span>
    dice_faces = [<span class="hljs-string">"⚀"</span>, <span class="hljs-string">"⚁"</span>, <span class="hljs-string">"⚂"</span>, <span class="hljs-string">"⚃"</span>, <span class="hljs-string">"⚄"</span>, <span class="hljs-string">"⚅"</span>]

    <span class="hljs-keyword">while</span> <span class="hljs-literal">true</span>
        print(<span class="hljs-string">"Do you want to roll a dice? (1=Yes/0=No): "</span>)
        guess = parse(<span class="hljs-built_in">Int64</span>, readline())
        <span class="hljs-comment"># Convert the string value input to a number</span>

        <span class="hljs-keyword">if</span> guess == <span class="hljs-number">1</span>
            println(<span class="hljs-string">"Rolling dice"</span>)
            current_side = rand(<span class="hljs-number">1</span>:num_sides_dice)
            println(<span class="hljs-string">"Dice has number <span class="hljs-subst">$(dice_faces[current_side])</span>"</span>)
        <span class="hljs-keyword">elseif</span> guess == <span class="hljs-number">0</span>
            println(<span class="hljs-string">"Exiting"</span>)
            <span class="hljs-keyword">break</span> <span class="hljs-comment"># Stop the while loop if the user decides to do so</span>
        <span class="hljs-keyword">else</span>
            println(<span class="hljs-string">"Invalid input, please try again"</span>)
        <span class="hljs-keyword">end</span> 
    <span class="hljs-keyword">end</span>

<span class="hljs-keyword">end</span>
</code></pre>
<h3 id="heading-how-to-build-a-countdown-timer-in-julia">How to Build a Countdown Timer in Julia⏱️</h3>
<p>Countdowns, for better or worse, are a huge part of life. From New Years Eve to a parent frustratingly trying to convince a child to obey some rule, we see and participate in countdown timers regularly. </p>
<p>Now, we are going to get a chance to program one (yay). At the core, we will again be using the <code>sleep</code> function which we had a chance to play around with in the rock paper scissors example.</p>
<p>As a quick reminder, <code>sleep</code> takes in as an argument the number of seconds we want the program to pause for. </p>
<p>For this example, we are going to try to do some while loop nesting by using functions. We want to have a loop that continues to prompt the user if they want to set a timer, and then if they do, we call a function called <code>run_timer</code>. The <code>run_timer</code> function should prompt the user to enter how long they want the timer to run for. </p>
<p>The caveat here is that we also want to print our how long is left for the timer on each iterations. So if the user enters 5, we can't just do <code>sleep(5)</code> since the user won't be able to see anything happen for those 5 seconds. </p>
<p>Below is the main function which is given to you to start. Feel free to modify this as you see fit. Use this starter code and then define the <code>run_timer</code> function per the specification above. </p>
<p>Remember, there's a lot of possible ways to approach this and the solution we include at the bottom is just one possible approach.</p>
<pre><code class="lang-julia"><span class="hljs-comment"># Code from: https://github.com/logankilpatrick/Julia-Projects-for-Beginners</span>

<span class="hljs-keyword">function</span> run_timer()
    <span class="hljs-comment"># TODO</span>
<span class="hljs-keyword">end</span>

<span class="hljs-comment"># Call the run_timer function in a loop until the user quits it</span>
<span class="hljs-keyword">function</span> countdown_timer()

    <span class="hljs-comment"># While the user chooses to run the countdown timer</span>
    <span class="hljs-keyword">while</span> <span class="hljs-literal">true</span>
        print(<span class="hljs-string">"Do you want set a countdown timer? (1=Yes/0=No): "</span>)
        answer = parse(<span class="hljs-built_in">Int64</span>, readline())
        <span class="hljs-comment"># Convert the string value input to a number</span>

        <span class="hljs-keyword">if</span> answer == <span class="hljs-number">1</span>
            <span class="hljs-comment"># Run the timer</span>
            run_timer()
        <span class="hljs-keyword">elseif</span> answer == <span class="hljs-number">0</span>
            println(<span class="hljs-string">"Exiting..."</span>)
            <span class="hljs-keyword">break</span> <span class="hljs-comment"># Stop the countdown timer</span>
        <span class="hljs-keyword">else</span>
            println(<span class="hljs-string">"Invalid input, please try again"</span>)
        <span class="hljs-keyword">end</span> 
    <span class="hljs-keyword">end</span>

<span class="hljs-keyword">end</span>
countdown_timer()
</code></pre>
<p>Give it a shot and remember you will need to make use of the <code>parse</code>, <code>readline</code>, <code>sleep</code>, and <code>println</code> functions to make this function work. </p>
<pre><code class="lang-julia"><span class="hljs-comment"># Code from: https://github.com/logankilpatrick/Julia-Projects-for-Beginners</span>

<span class="hljs-keyword">function</span> run_timer()
    print(<span class="hljs-string">"Enter the amount of seconds: "</span>)
    seconds = parse(<span class="hljs-built_in">Int64</span>, readline())

    println(<span class="hljs-string">"Countdown starts now with <span class="hljs-variable">$seconds</span> seconds remaining."</span>)
    current_seconds = seconds

    <span class="hljs-comment"># While the countdown timer is not finished</span>
    <span class="hljs-keyword">while</span> current_seconds != <span class="hljs-number">0</span>

        <span class="hljs-comment"># Print the current countdown</span>
        <span class="hljs-keyword">if</span> current_seconds != seconds
            println(<span class="hljs-string">"Seconds left: <span class="hljs-variable">$current_seconds</span>"</span>)
        <span class="hljs-keyword">end</span>

        <span class="hljs-comment"># Wait for one second</span>
        sleep(<span class="hljs-number">1</span>)
        current_seconds = current_seconds - <span class="hljs-number">1</span>
    <span class="hljs-keyword">end</span>
    println(<span class="hljs-string">"The countdown is over!"</span>)
<span class="hljs-keyword">end</span>

<span class="hljs-comment"># Call the run_timer function in a loop until the user quits it</span>
<span class="hljs-keyword">function</span> countdown_timer()

    <span class="hljs-comment"># While the user chooses to run the countdown timer</span>
    <span class="hljs-keyword">while</span> <span class="hljs-literal">true</span>
        print(<span class="hljs-string">"Do you want set a countdown timer? (1=Yes/0=No): "</span>)
        answer = parse(<span class="hljs-built_in">Int64</span>, readline())
        <span class="hljs-comment"># Convert the string value input to a number</span>

        <span class="hljs-keyword">if</span> answer == <span class="hljs-number">1</span>
            <span class="hljs-comment"># Run the timer</span>
            run_timer()
        <span class="hljs-keyword">elseif</span> answer == <span class="hljs-number">0</span>
            println(<span class="hljs-string">"Exiting..."</span>)
            <span class="hljs-keyword">break</span> <span class="hljs-comment"># Stop the countdown timer</span>
        <span class="hljs-keyword">else</span>
            println(<span class="hljs-string">"Invalid input, please try again"</span>)
        <span class="hljs-keyword">end</span> 
    <span class="hljs-keyword">end</span>

<span class="hljs-keyword">end</span>

countdown_timer()
</code></pre>
<h2 id="heading-wrapping-up">Wrapping up 🎁</h2>
<p>I hope you had as much fun working with and reading about these projects as I did creating them. </p>
<p>If you want to make your own version of this post and make some small Julia projects and share them with the world, please do so and open a PR here: <a target="_blank" href="https://github.com/logankilpatrick/10-Julia-Projects-for-Beginners">https://github.com/logankilpatrick/10-Julia-Projects-for-Beginners</a>. </p>
<p>I can easily change the repo name to accommodate an influx of small projects.</p>
<p>I will also note that an exercise like this is also a great way to potentially contribute to Julia. While I was working on this post, I was able to open 2 PR’s to base Julia which I think will help improve the developer experience:</p>
<ul>
<li><a target="_blank" href="https://github.com/JuliaLang/julia/pull/43635">https://github.com/JuliaLang/julia/pull/43635</a> and</li>
<li><a target="_blank" href="https://github.com/JuliaLang/julia/pull/43640">https://github.com/JuliaLang/julia/pull/43640</a>.</li>
</ul>
<p>If you enjoyed this tutorial, <a target="_blank" href="https://twitter.com/OfficialLoganK">let’s connect on Twitter</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Linear Models and Decision Trees in Julia ]]>
                </title>
                <description>
                    <![CDATA[ By Logan Kilpatrick As a machine learning engineer or data scientist, one of the most critical decisions you can make is what type of model to use to solve a specific problem. Do you really need to use Deep Learning to model this specific problem? Wi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/linear-models-vs-decision-trees-in-julia/</link>
                <guid isPermaLink="false">66d4601947a8245f78752a8d</guid>
                
                    <category>
                        <![CDATA[ data analysis ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Data Science ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Julia ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Julialang ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Machine Learning ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 29 Aug 2022 13:46:21 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/08/LinearModels-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Logan Kilpatrick</p>
<p>As a machine learning engineer or data scientist, one of the most critical decisions you can make is what type of model to use to solve a specific problem.</p>
<p>Do you really need to use Deep Learning to model this specific problem? Will something like a Random Forest model or Decision Tree be more effective? </p>
<p>While sometimes the best thing to do is try things out and see for yourself, there is some context that you should be aware of as you specifically evaluate a Linear Model vs a Decision Tree. </p>
<p><strong>🚨 TL;DR</strong> – Linear models are good when the data itself has a linear relationship. Decision trees, on the other hand, are helpful since they can model more complex classification or regression problems with non-linear relationships in an explainable way.</p>
<p>Let's dive deeper into why this is the case.</p>
<h2 id="heading-what-is-a-linear-model">What is a Linear model? 🤔</h2>
<p>The term linear model has many different meanings since it is used across multiple domains including, in our case, machine learning (ML). </p>
<p>In the world of ML, Linear Models refer to a specific class of models where the goal is to map the relationship between the input value(s) and some outcome, usually where there is a linear relationship present (more on this later). </p>
<p>A classic example of this is predicting the price of a house based on different attributes (often called "features" in ML) such as square footage, the number of bedrooms, the year it was built, and so on. </p>
<p>The most commonly used Linear model is Linear Regression (LR) where the model essentially becomes a line of best fit for the data that you can plot as shown below. </p>
<p>In LR, the main goal is to predict some numerical value, which is different than the goal of a classification model. In classification, we want to predict the class that some input data maps to which can often times be a more straightforward problem to model.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/linear.png" alt="Graph showing a linear relationship " width="600" height="400" loading="lazy">
<em>Example of linear regression. Image by Author</em></p>
<p>Just like in other forms of ML, we train the Linear model by giving it training input and output data which is used to set the models weights. Since this method requires the use of labeled data, it is a supervised learning problem.</p>
<p>So when would I use an LR model? The general rule of thumb is that LR models only work when we are modeling some type of relationship that is itself linear. </p>
<h2 id="heading-understanding-linear-relationships">Understanding Linear Relationships</h2>
<p>So the next logical question is, "How do I know if the data I am working with has a linear relationship". </p>
<p>Before we answer this, it is worth pointing out that intimate knowledge of the data you are working with in any particular ML problem is likely what will make you most successful at solving the problem. </p>
<p>In the "real world", engineers and scientists spend close to 80% of their time working with data, and only 20% of their time actually solving problems (which is an issue in and of itself, but this is the reality at the moment). </p>
<p>Okay, so back to linear relationships in data and how we know if that exists for our dataset. The most straightforward way to test this is by simply plotting the data and looking at it. </p>
<p>If you see a plot like the one depicted above, you are all set since the relationship appears to be linear. </p>
<p>If you see a plot like the one below, you might not be able to use LR.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/non-linear-2.png" alt="Graph showing a non-linear relationship" width="600" height="400" loading="lazy">
<em>Non-linear data. Image by Author</em></p>
<p>Next, let's look at a Linear Regression model in Julia. If you are not familiar with Julia, you might want to check out my "<strong><a target="_blank" href="https://www.freecodecamp.org/news/learn-julia-programming-language/">Learn Julia For Beginners</a>"</strong> right here on freeCodeCamp.</p>
<h2 id="heading-linear-regression-in-action">Linear Regression in Action 📣</h2>
<p>Let's use the basic housing example I mentioned before. You can download the data from <a target="_blank" href="https://raw.githubusercontent.com/julia4ta/tutorials/master/Series%2005/Files/housingdata.csv">this link</a>. We can create a new Julia file and add the following imports:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> GLM, Plots, TypedTables, CSV
</code></pre>
<p>The key package here is <a target="_blank" href="https://github.com/JuliaStats/GLM.jl">GLM.jl</a> which stands for Generalized linear models in Julia. It will help us make the initial LR model! Plots.jl, TypedTables.jl, and CSV.jl all play a supporting role in helping us with this example. </p>
<p>The next step is to use CSV.jl to load in the dataset and then set up our X and Y values:</p>
<pre><code class="lang-julia">housing_data = CSV.File(<span class="hljs-string">"housingdata.csv"</span>)

X = housing_data.size

Y = housing_data.price

<span class="hljs-comment"># Setup a Typed Table</span>
t = Table(X = X, Y = Y)
</code></pre>
<p>Next, we will plot the data to make sure that it looks like there is a linear relationship present: </p>
<pre><code class="lang-julia"><span class="hljs-comment"># Use Plots package to generate scatter plot of data</span>
gr(size = (<span class="hljs-number">600</span>, <span class="hljs-number">600</span>))

<span class="hljs-comment"># Create scatter plot</span>
p_scatter = scatter(X, Y,
    xlims = (<span class="hljs-number">0</span>, <span class="hljs-number">5000</span>),
    ylims = (<span class="hljs-number">0</span>, <span class="hljs-number">800000</span>),
    xlabel = <span class="hljs-string">"Size in square feet"</span>,
    ylabel = <span class="hljs-string">"Price of the house"</span>,
    title = <span class="hljs-string">"Housing Prices example freeCodeCamp"</span>,
    legend = <span class="hljs-literal">false</span>,
    color = :red
)
</code></pre>
<p>This will generate a plot that looks like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/plot_5.svg" alt="Plot of housing prices showing a linear relationship between size and price" width="600" height="400" loading="lazy">
<em>Image by Author</em></p>
<p>We can see that the relationship appears to be linear in this case which means we can proceed with building a basic model. </p>
<p>GLM provides two basic ways of fitting models, you can <a target="_blank" href="https://juliastats.org/GLM.jl/stable/#Fitting-GLM-models">read about this in the docs</a>. For our example, we will use the first option which looks like this:</p>
<pre><code class="lang-julia">lm(formula, data)
</code></pre>
<p>where formula means the following:</p>
<blockquote>
<p><code>formula</code>: a <a target="_blank" href="https://juliastats.org/StatsModels.jl/stable/formula/">StatsModels.jl <code>Formula</code> object</a> referring to columns in <code>data</code>; for example, if column names are <code>:Y</code>, <code>:X1</code>, and <code>:X2</code>, then a valid formula is <code>@formula(Y ~ X1 + X2)</code></p>
</blockquote>
<p>So in our case, since we only have 1 column (the size of the house), our formula will look like this: </p>
<pre><code class="lang-julia">ols = lm(<span class="hljs-meta">@formula</span>(Y ~ X), t)
</code></pre>
<p>And again we pass in the <code>t</code> variable which is the data we want to fit the model to. </p>
<p>After that, we can try plotting the new fit model onto the initial graph to see what it looks like and if it is modeling the data correctly.</p>
<pre><code class="lang-julia">plot!(X, predict(ols), color = :green, linewidth = <span class="hljs-number">3</span>)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/plot_6.svg" alt="Housing price graph showing the linear regression model is correctly fitting to the data" width="600" height="400" loading="lazy">
<em>Image by Author</em></p>
<p>We can see from the above image that we are correctly fitting the model to the data which means we did it! We have successfully created our Linear Regression model in Julia.</p>
<p>Let's do one more quick test to see if we can use the model on some new data for a house with only 750 square feet:</p>
<pre><code class="lang-julia">small_house = Table(X = [<span class="hljs-number">750</span>])

predict(ols, small_house)
</code></pre>
<p>The model predicts that the house will cost <code>172164.45</code> which looks right when we observe the graph above (despite most data being for houses with more than 1,000 square feet).</p>
<h2 id="heading-wrapping-up-linear-regression">Wrapping up Linear Regression 🎀</h2>
<p>We have just completed our whirlwind tour of linear models in Julia. We talked about why you might want to use them, the constraints (the relationship must be linear), how to check if the relationship is linear, and how to fit an LR in Julia. </p>
<p>I hope this helped frame the context for when you might want to use one of these models as well as how you would do this in practice using Julia.</p>
<p>If you want to learn more about LR models in Julia, check out this video tutorial: </p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/n03pSsA7NtQ" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-time-to-talk-decision-trees">Time to Talk Decision Trees 🌴</h2>
<p>We now know the main constrains of linear models: the relationship must be linear. But what about Decision Trees (DTs)? What is the main use case for them and what are the limitations? </p>
<p>At their core, DTs allow us to model the outcome of different potential events or situations. For example, you can make a DT for the outcome of flipping a coin or some other event. The basic structure looks like the following image:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/tree.png" alt="Basic tree structure" width="600" height="400" loading="lazy">
<em>Decision tree. Image by Author</em></p>
<p>Here we can see we start with some initial condition, and depending on the outcome of that situation, we go into any three possible nodes. The outer nodes have another nested condition associated with them but the inner one is a final state. </p>
<p>One of the best things about DTs is that for our housing data example, we can build a tree that might say something like: "If the square footage is between 1000-2000 feet, then the value is $400,000". This is an oversimplification but you can use DTs for modeling regression examples as well as classification problems. </p>
<p>The reason this if/then structure is so important is that the tree itself actually becomes quite readable by a human. This is contrasted with ML models in the Deep Learning space, for example, where they are black boxes that we cannot usually understand. The explainability of DTs is one of the core reasons people use them in practice.</p>
<h2 id="heading-decision-trees-vs-linear-regression">Decision Tree's Vs Linear Regression</h2>
<p>Another important thing to point out about DTs, which is the key difference from linear models, is that DTs are commonly used to model non-linear relationships. </p>
<p>When dealing with problems where there are a lot of variables in play, decision trees are also very helpful at quickly identifying what the important variables are.</p>
<p>Now that we know the basics of decision trees (and if you still want to learn more about the more specific tree vernacular and such, check out <a target="_blank" href="https://www.mastersindatascience.org/learning/machine-learning-algorithms/decision-tree/">this article</a>), let's dive into some code examples and set up a tree. </p>
<h2 id="heading-decision-trees-in-action">Decision Tree's in Action 🌲🪓</h2>
<p>For this example, we will be using the <a target="_blank" href="https://archive.ics.uci.edu/ml/datasets/iris">Iris dataset</a> with the <a target="_blank" href="https://github.com/JuliaAI/DecisionTree.jl">DecisionTree.jl package</a>. We start off by loading in the dataset as follows:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> DecisionTree

features, labels = load_data(<span class="hljs-string">"iris"</span>)
</code></pre>
<p>By default, the <code>load_data</code> function creates the <code>features</code> and <code>labels</code> variables to be of type <code>any</code> which is very computationally expensive. We can reduce this burden by converting the types explicitly to float and string, respectively:</p>
<pre><code class="lang-julia">features = float.(features)
labels   = string.(labels)
</code></pre>
<p>Next, we can call the <code>build_tree</code> function and pass in our labels and features:</p>
<pre><code class="lang-julia">model = build_tree(labels, features)
</code></pre>
<p>Now that we have our tree, we need to prune it to get some results. </p>
<pre><code class="lang-julia">model = prune_tree(model, <span class="hljs-number">0.9</span>)

<span class="hljs-comment"># print of the tree with a depth of 6 nodes (optional)</span>
print_tree(model, <span class="hljs-number">6</span>)
</code></pre>
<p>When we prune the tree, we can set the purity level to 90% in this case which means that we merge leaves that have 90% purity. </p>
<p>Purity in DTs is the idea that there is some data in each decision that falls into the wrong place. For example, we might only have 70% of the data we would expect to fall into a certain class fall into the class, which would give us 70% purity. </p>
<p>The <code>print_tree</code> function from above is a nice way of seeing what we have made so far:</p>
<pre><code class="lang-julia">Feature <span class="hljs-number">4</span> &lt; <span class="hljs-number">0.8</span> ?
├─ Iris-setosa : <span class="hljs-number">50</span>/<span class="hljs-number">50</span>
└─ Feature <span class="hljs-number">4</span> &lt; <span class="hljs-number">1.75</span> ?
    ├─ Feature <span class="hljs-number">3</span> &lt; <span class="hljs-number">4.95</span> ?
        ├─ Iris-versicolor : <span class="hljs-number">47</span>/<span class="hljs-number">48</span>
        └─ Feature <span class="hljs-number">4</span> &lt; <span class="hljs-number">1.55</span> ?
            ├─ Iris-virginica : <span class="hljs-number">3</span>/<span class="hljs-number">3</span>
            └─ Feature <span class="hljs-number">3</span> &lt; <span class="hljs-number">5.45</span> ?
                ├─ Iris-versicolor : <span class="hljs-number">2</span>/<span class="hljs-number">2</span>
                └─ Iris-virginica : <span class="hljs-number">1</span>/<span class="hljs-number">1</span>
    └─ Feature <span class="hljs-number">3</span> &lt; <span class="hljs-number">4.85</span> ?
        ├─ Feature <span class="hljs-number">1</span> &lt; <span class="hljs-number">5.95</span> ?
            ├─ Iris-versicolor : <span class="hljs-number">1</span>/<span class="hljs-number">1</span>
            └─ Iris-virginica : <span class="hljs-number">2</span>/<span class="hljs-number">2</span>
        └─ Iris-virginica : <span class="hljs-number">43</span>/<span class="hljs-number">43</span>
</code></pre>
<p>This visualization shows us exactly what the tree is doing and how it is making these classification buckets. There are also more visualization tools like D3Trees.jl which would make this more interactive to view. </p>
<p>Now that we have the model, we can test it on a single data point:</p>
<pre><code class="lang-julia">julia&gt; apply_tree(model, [<span class="hljs-number">5.9</span>,<span class="hljs-number">3.0</span>,<span class="hljs-number">5.1</span>,<span class="hljs-number">1.9</span>])
<span class="hljs-string">"Iris-virginica"</span>
</code></pre>
<p>Or, we can make predictions on all of our data and look at the confusion matrix:</p>
<pre><code class="lang-julia">preds = apply_tree(model, features)

DecisionTree.confusion_matrix(labels, preds)

Classes:  [<span class="hljs-string">"Iris-setosa"</span>, <span class="hljs-string">"Iris-versicolor"</span>, <span class="hljs-string">"Iris-virginica"</span>]
<span class="hljs-built_in">Matrix</span>:   <span class="hljs-number">3</span>×<span class="hljs-number">3</span> <span class="hljs-built_in">Matrix</span>{<span class="hljs-built_in">Int64</span>}:
 <span class="hljs-number">50</span>   <span class="hljs-number">0</span>   <span class="hljs-number">0</span>
  <span class="hljs-number">0</span>  <span class="hljs-number">50</span>   <span class="hljs-number">0</span>
  <span class="hljs-number">0</span>   <span class="hljs-number">1</span>  <span class="hljs-number">49</span>

Accuracy: <span class="hljs-number">0.9933333333333333</span>
Kappa:    <span class="hljs-number">0.9899999999999998</span>
<span class="hljs-number">3</span>×<span class="hljs-number">3</span> <span class="hljs-built_in">Matrix</span>{<span class="hljs-built_in">Int64</span>}:
 <span class="hljs-number">50</span>   <span class="hljs-number">0</span>   <span class="hljs-number">0</span>
  <span class="hljs-number">0</span>  <span class="hljs-number">50</span>   <span class="hljs-number">0</span>
  <span class="hljs-number">0</span>   <span class="hljs-number">1</span>  <span class="hljs-number">49</span>
</code></pre>
<p>As you can see, the accuracy of this model is actually quite good given the limited dataset and short training time. </p>
<p>This example should be enough to get you going on your DT journey, but if you need more help, check out this awesome video: </p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/XTApO31m3Xs" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-wrapping-up">Wrapping up 👋</h2>
<p>This post was a lightning-fast tour of some of the differences between Decision Trees and Linear Models as well as how to program them in Julia. </p>
<p>I hope you walk away from this with confidence that you can go and apply these tools in your own workflows! </p>
<p>If you enjoyed the article, please consider sharing it and you are always welcome to reach out to me on Twitter: <a target="_blank" href="https://twitter.com/OfficialLoganK">https://twitter.com/OfficialLoganK</a></p>
<p>Happy programming! </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build Your First Web App in Julia with Genie.jl 🧞‍♂️ ]]>
                </title>
                <description>
                    <![CDATA[ By Logan Kilpatrick Julia is a high-level, dynamic, and open-source programming language. It's designed to be as easy to use as Python while remaining as performant as C or C++.  Many early use cases for Julia were in the scientific domains where mas... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-web-apps-in-julia/</link>
                <guid isPermaLink="false">66d460133bc3ab877dae220a</guid>
                
                    <category>
                        <![CDATA[ Julialang ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Julia ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Applications ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 01 Feb 2022 21:33:45 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/01/Web-applications-in-Julia.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Logan Kilpatrick</p>
<p>Julia is a high-level, dynamic, and open-source programming language. It's designed to be as easy to use as Python while remaining as performant as C or C++. </p>
<p>Many early use cases for Julia were in the scientific domains where massive computational processing was and still is required. But as the language has continued to grow, more and more use cases are gaining steam (hint: web development). </p>
<p>If you are totally new to Julia and want to get a handle on the syntax before you dive into creating your first web application, <a target="_blank" href="https://www.freecodecamp.org/news/learn-julia-programming-language/">check out this article on freeCodeCamp</a>.</p>
<p>It goes over the basics, how to install Julia, steps to install packages, and much more! </p>
<p>We will focus this tutorial on all the necessary steps to build your first web application in Julia from the ground up. So let's begin by checking out the Genie website: <a target="_blank" href="https://genieframework.com">https://genieframework.com</a>.</p>
<h2 id="heading-what-is-geniejl">What is Genie.jl? 🧐</h2>
<p>Genie is a modern and highly productive web framework written in Julia. In the project's own words:</p>
<blockquote>
<p>Genie is a full-stack web framework that provides a streamlined and efficient workflow for developing modern web applications. It builds on Julia's strengths (high-level, high-performance, dynamic, JIT-compiled), exposing a rich API and a powerful toolset for productive web development.</p>
</blockquote>
<p>Genie is very similar to the <a target="_blank" href="https://www.djangoproject.com">Django Project</a> in that Genie is more than a single framework. Instead, it is an entire ecosystem with extensions and the like. </p>
<p>But why do we need Genie? The simple answer is that as Julia continues to grow in popularity, more and more developers are looking to leverage Julia across their entire stack. Genie provides the ability to deploy websites with Julia code running on the server-side so you can do things like deploy machine learning models as part of your Genie app.</p>
<p>Before we dive into getting started with Genie, you might want to check out a live deployed Genie app to get a sense of what is possible: <a target="_blank" href="https://pkgs.genieframework.com">https://pkgs.genieframework.com</a>. </p>
<p>This project is a community resource where you can query the number of package downloads during a certain time frame for a specific package. Type in "genie" to see the number of daily downloads.</p>
<p>You might also be interested in learning more about other GUI and web development frameworks in Julia. To learn more broadly about the ecosystem, <a target="_blank" href="https://towardsdatascience.com/6-julia-frameworks-to-create-desktop-guis-and-web-apps-9ae1a941f115">check out this article</a>.</p>
<h2 id="heading-how-to-install-genie">How to Install Genie ⤵️</h2>
<p>To get Genie installed, all we need to do is open the Julia REPL and type <code>] add Genie</code> . This will take care of everything you need. If everything works, you should be able to do:</p>
<pre><code class="lang-julia">julia&gt; <span class="hljs-keyword">using</span> Genie
</code></pre>
<p>without any issues. You are now all set to begin trying out Genie.</p>
<h2 id="heading-how-to-map-urls-to-julia-functions">How to Map URLs to Julia Functions 🗺</h2>
<p>A core part of the Genie framework is the idea of a router. Routers take the user action of visiting a specific URL and associate it with a Julia function being called.</p>
<p>Let's look at a simple example of this. In the REPL, type the following:</p>
<pre><code class="lang-julia">julia&gt; <span class="hljs-keyword">using</span> Genie, Genie.Router

julia&gt; route(<span class="hljs-string">"/hello"</span>) <span class="hljs-keyword">do</span>
           <span class="hljs-string">"Hello freeCodeCamp"</span>
       <span class="hljs-keyword">end</span>
[GET] /hello =&gt; <span class="hljs-comment">#5 | :get_hello</span>
</code></pre>
<p>In this example, we defined the "/hello" URL to return the text "Hello freeCodeCamp". We can verify that this works by starting the server:</p>
<pre><code class="lang-julia">julia&gt; up() <span class="hljs-comment"># start server</span>
┌ Info: 
└ Web Server starting at http://<span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>:<span class="hljs-number">8000</span> 
Genie.AppServer.ServersCollection(<span class="hljs-built_in">Task</span> (runnable) @<span class="hljs-number">0x000000011c5c5bb0</span>, <span class="hljs-literal">nothing</span>)
</code></pre>
<p>Now that the server is up and running, we can visit <a target="_blank" href="http://127.0.0.1:8000"><code>http://127.0.0.1:8000</code></a> in our browser. You will notice we get a 404 page, which is expected since the only route we defined was "/hello". So let's add that to the URL and see what we get:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/Screen-Shot-2022-01-29-at-8.25.53-AM.png" alt="Browser window showing nothing but the text &quot;Hello freeCodeCamp&quot;" width="600" height="400" loading="lazy"></p>
<p>And there we go! Our first step towards building a fully functional web application is complete. We can also confirm that the page is loading correctly by checking the REPL which shows this:</p>
<pre><code class="lang-julia">julia&gt; ┌ Error: GET / <span class="hljs-number">404</span>
└ @ Genie.Router ~/.julia/packages/Genie/UxbVJ/src/Router.jl:<span class="hljs-number">163</span>
┌ Error: GET /favicon.ico <span class="hljs-number">404</span>
└ @ Genie.Router ~/.julia/packages/Genie/UxbVJ/src/Router.jl:<span class="hljs-number">163</span>
[ Info: GET /hello <span class="hljs-number">200</span>
</code></pre>
<p>We see the first attempt where the result was a 404 and on the 2nd attempt where we successfully got the response (the 200 message means everything is okay).</p>
<p>Now that we have a basic example working, let's now try and build on this with some more depth. </p>
<p>To do this, we will create a new file. I will be using VS Code but you are welcome to use any IDE you find useful. Before we look at the next piece of code, we need to make sure we shut down the server by typing <code>down()</code> into the REPL. </p>
<p>Okay, onto the next example:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> Genie, Genie.Router
<span class="hljs-keyword">using</span> Genie.Renderer, Genie.Renderer.Html, Genie.Renderer.Json

route(<span class="hljs-string">"/"</span>) <span class="hljs-keyword">do</span>
    html(<span class="hljs-string">"Hey freeCodeCamp"</span>)
<span class="hljs-keyword">end</span>

route(<span class="hljs-string">"/hello.html"</span>) <span class="hljs-keyword">do</span>
  html(<span class="hljs-string">"Hello freeCodeCamp (in html)"</span>)
<span class="hljs-keyword">end</span>

route(<span class="hljs-string">"/hello.json"</span>) <span class="hljs-keyword">do</span>
  json(<span class="hljs-string">"Hi freeCodeCamp (in json)"</span>)
<span class="hljs-keyword">end</span>

route(<span class="hljs-string">"/hello.txt"</span>) <span class="hljs-keyword">do</span>
   respond(<span class="hljs-string">"Hiya freeCodeCamp (in txt format)"</span>, :text)
<span class="hljs-keyword">end</span>

<span class="hljs-comment"># Launch the server on a specific port, 8002</span>
<span class="hljs-comment"># Run the task asynchronously</span>
up(<span class="hljs-number">8002</span>, async = <span class="hljs-literal">true</span>)
</code></pre>
<p>A lot is going on in this example, so let's walk through what is taking place. </p>
<p>We start by loading in the packages we want. Then, we define 4 different routes. The first one is the index route. So when the user visits <a target="_blank" href="http://127.0.0.1:8002"><code>http://127.0.0.1:8002</code></a> they will see "Hey freeCodeCamp". The routes after the index highlight that each route can give a custom output. In some cases, it can be HTML, in others, it could be JSON or plain text. </p>
<p>The last line of this example showcases the server launching code. As the comment states, we can set the specific port number and choose if we want the routes to run asynchronously or not. We have now successfully created our first <a target="_blank" href="https://genieframework.com/docs/tutorials/Getting-Started.html#developingasimplegeniescript">Genie Script</a>! </p>
<h2 id="heading-how-to-create-a-basic-web-service">How to Create a Basic Web Service 🕸</h2>
<p>Now that we have gotten our hands dirty with the basics, we will now begin to get closer to building a fully-fledged web application. </p>
<p>Before we go all the way there, we are going to take the first step which is creating a basic web service. To do so, we will go into the REPL and switch our current directory to one which is easily accessible. I will use my desktop in this tutorial:</p>
<pre><code class="lang-julia">shell&gt; cd Desktop
/Users/logankilpatrick/Desktop
</code></pre>
<p>To enter shell mode which is shown above, simply type a ";" into the REPL. Now that we have our active directory set to the desktop in my case, we will use the handy generator function to create the service:</p>
<pre><code class="lang-julia">julia&gt; Genie.newapp_webservice(<span class="hljs-string">"freeCodeCampApp"</span>)

[ Info: Done! New app created at /Users/logankilpatrick/Desktop/freeCodeCampApp
[ Info: Changing active directory to /Users/logankilpatrick/Desktop/freeCodeCampApp
    /var/folders/tc/<span class="hljs-number">519</span>vfm453fj_x5bmd8pwx9480000gn/T/jl_bO1R8h/FreeCodeCampApp/Project.toml
[ Info: Project.toml has been generated
[ Info: Installing app dependencies
...
</code></pre>
<p>The <code>newapp_webservice</code> is a very helpful function that automatically creates all the pieces we need for our first web service. Now that we have a project created, we need to open it up in an IDE (in my case, VS Code). You should see the following if you open up the correct folder:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/Screen-Shot-2022-01-30-at-7.39.23-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>There are a lot of files created for us automatically. The main one we will look at is <code>routes.jl</code> which is used to create routes as we did in the section above. </p>
<p>The function we called to generate these folders automatically starts the server, so let's take a quick look at the existing landing page by visiting <a target="_blank" href="http://127.0.0.1:8000">http://127.0.0.1:8000</a>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/Screen-Shot-2022-01-30-at-7.51.16-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>As you might notice, my page looks a little different than yours might because I went in and edited the <code>welcome.html</code> page found in the public folder. </p>
<p>As you can see in <code>routes.jl</code>, when the user visits the main URL <code>/</code>, we route them to the welcome page. We can add in additional routes as we did in the section above and expand this. You are welcome to pause here and play around. We already have a pretty robust website setup.</p>
<p>If you take a peek into some of the other folders like <code>config/env</code>, you will see details around setting the port, host URL, and other relevant parameters. Again, feel free to play around there but we will not go into all the detail of those files in this tutorial. </p>
<p>Before we dive into the next topic, let's take a look at a few more of the files generated for our basic web service:</p>
<ul>
<li>The public folder has all of the front end files (HTML and CSS)</li>
<li>The <code>src</code> folder has the entry point to the web service (in my case <code>freeCodeCampApp.jl</code>)</li>
<li>bin contains some additional dependencies we will again ignore</li>
<li>Manifest.toml and Project.toml are the key Julia files that allow us to maintain our Julia dependencies. When you created the web service, the script automatically activated your current project environment (which is the app we just created). You can verify this by typing "]" into the REPL which will show the active space in blue:</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/Screen-Shot-2022-01-30-at-7.59.49-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This just means that if we try to add a package, it will add it to the project and manifest file specifically for this project, instead of the globally shared one.</p>
<h2 id="heading-how-to-create-a-fully-functioning-web-app-with-a-database">How to Create a Fully Functioning Web App With a Database 💽</h2>
<p>Now that we have explored the basics, we are going to dive into a full-on web app. Again, Genie provides some nice functions to get us started. Before we create it, we will need to navigate back to the desktop:</p>
<pre><code class="lang-julia">shell&gt; pwd
/Users/logankilpatrick/Desktop/freeCodeCampApp

shell&gt; cd ..
/Users/logankilpatrick/Desktop

shell&gt;
</code></pre>
<p>Remember, you can type <code>;</code> to enter the shell mode and backspace to exit the shell mode. Now, let's create the app:</p>
<pre><code class="lang-julia">julia&gt; Genie.newapp_mvc(Genie.newapp_mvc(<span class="hljs-string">"freeCodeCampMVC"</span>))
   Resolving package versions...
   ...
</code></pre>
<p>You will be prompted to choose a database backend. For this example, we will use SQLite:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/01/Screen-Shot-2022-01-30-at-8.08.31-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you want to use a different database backend, feel free to do so as well. But note that you will need to create the database file automatically. Genie only creates an SQLite file for you. </p>
<p>We now have a MVC app created. But you might be asking yourself, what is an MVC? </p>
<p>The Model-View-Controller paradigm is very common across application development. In the interest of not getting into the weeds on it, I will <a target="_blank" href="https://www.freecodecamp.org/news/mvc-architecture-what-is-a-model-view-controller-framework/">refer you to this post</a> where you can read about the details. From our perspective as developers, there is not much impact. </p>
<p>Just like we did when we created the last project, we need to open it in the IDE again:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/Screen-Shot-2022-02-01-at-6.44.21-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Again, we will see much of the same stuff as before with the new addition of the <code>app</code> folder which will contain a lot of critical code. We can see what the new project looks like by typing:</p>
<pre><code class="lang-julia">julia&gt; loadapp()

julia&gt; up()
</code></pre>
<p>and then navigating too: <a target="_blank" href="http://127.0.0.1:8000">http://127.0.0.1:8000</a>.</p>
<p>Next up, we will need to connect our database to the web app we created. To do this, head to <code>db/connection.yml</code> and edit the following section:</p>
<pre><code class="lang-yml"><span class="hljs-attr">env:</span> <span class="hljs-string">ENV["GENIE_ENV"]</span>

<span class="hljs-attr">dev:</span>
  <span class="hljs-attr">adapter:</span> <span class="hljs-string">SQLite</span>
  <span class="hljs-attr">database:</span> <span class="hljs-string">db/freeCodeCamp_courses.sqlite</span>
</code></pre>
<p>You can leave the rest of the fields blank for now. Then, we need to run:</p>
<pre><code class="lang-julia">julia&gt; include(joinpath(<span class="hljs-string">"config"</span>, <span class="hljs-string">"initializers"</span>, <span class="hljs-string">"searchlight.jl"</span>))
</code></pre>
<p>which will load the database configuration. Next up, we will continue to configure the database such that we can save data from our app into persistent storage.</p>
<p>We begin this process by creating a new resource:</p>
<pre><code class="lang-julia">julia&gt; Genie.newresource(<span class="hljs-string">"course"</span>)
</code></pre>
<p>Once we have defined a resource, the next step is to go and edit the database migrations table which can be found at <code>db/migrations/2022020115190055_create_table_courses.jl</code> in my case. </p>
<p>By default, the table is already populated with some placeholder text based on the last few commands we ran. It should look something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/Screen-Shot-2022-02-01-at-7.22.35-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We will edit the file to match the specific scheme we want. This will be entirely dependent on the application itself. Since I am making courses on this site, I will enter all of the course details as follows:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">module</span> CreateTableCourses

<span class="hljs-keyword">import</span> SearchLight.Migrations: create_table, column, columns, pk, add_index, drop_table, add_indices

<span class="hljs-keyword">function</span> up()
  create_table(:courses) <span class="hljs-keyword">do</span>
    [
      pk()
      column(:title, :string, limit = <span class="hljs-number">200</span>)
      column(:authors, :string, limit = <span class="hljs-number">250</span>)
      column(:year, :integer, limit = <span class="hljs-number">4</span>)
      column(:rating, :string, limit = <span class="hljs-number">10</span>)
      column(:categories, :string, limit = <span class="hljs-number">100</span>)
      column(:description, :string, limit = <span class="hljs-number">1_000</span>)
      column(:cost, :float, limit = <span class="hljs-number">1000</span>)
    ]
  <span class="hljs-keyword">end</span>

  add_index(:courses, :title)
  add_index(:courses, :authors)
  add_index(:courses, :categories)
  add_index(:courses, :description)

<span class="hljs-keyword">end</span>

<span class="hljs-keyword">function</span> down()
  drop_table(:courses)
<span class="hljs-keyword">end</span>

<span class="hljs-keyword">end</span>
</code></pre>
<p>Again, these are arbitrary and can be whatever you want them to be. </p>
<p>It is worth noting that adding the index is optional. The reason you would add it is that it speeds up the queries, but there are other tradeoffs and you can't actually load all the columns as indexes. You can read more about some of these tradeoffs <a target="_blank" href="https://stackoverflow.com/questions/5447987/why-cant-i-simply-add-an-index-that-includes-all-columns/5448055#5448055">here</a> and <a target="_blank" href="https://stackoverflow.com/questions/107132/what-columns-generally-make-good-indexes">here</a>.</p>
<p>Now that we have the database table updated, we need to propagate these updates. To do so, we will use <code>SearchLight.jl</code> which functions as our app's migration system:</p>
<pre><code class="lang-julia">julia&gt; <span class="hljs-keyword">using</span> SearchLight

julia&gt; SearchLight.Migration.create_migrations_table()
┌ Info: <span class="hljs-number">2022</span>-<span class="hljs-number">02</span>-<span class="hljs-number">01</span> <span class="hljs-number">07</span>:<span class="hljs-number">37</span>:<span class="hljs-number">11</span> CREATE TABLE <span class="hljs-string">`schema_migrations`</span> (
│       <span class="hljs-string">`version`</span> varchar(<span class="hljs-number">30</span>) NOT NULL DEFAULT '',
│       PRIMARY KEY (<span class="hljs-string">`version`</span>)
└     )
[ Info: <span class="hljs-number">2022</span>-<span class="hljs-number">02</span>-<span class="hljs-number">01</span> <span class="hljs-number">07</span>:<span class="hljs-number">37</span>:<span class="hljs-number">11</span> Created table schema_migrations

julia&gt; SearchLight.Migration.status()
[ Info: <span class="hljs-number">2022</span>-<span class="hljs-number">02</span>-<span class="hljs-number">01</span> <span class="hljs-number">07</span>:<span class="hljs-number">37</span>:<span class="hljs-number">20</span> SELECT version FROM schema_migrations ORDER BY version DESC
|   | <span class="hljs-built_in">Module</span> name &amp; status                     |
|   | File name                                |
|---|------------------------------------------|
|   |                 CreateTableCourses: DOWN |
| <span class="hljs-number">1</span> | <span class="hljs-number">2022020115190055_</span>create_table_courses.jl |

julia&gt; SearchLight.Migration.last_up()
[ Info: <span class="hljs-number">2022</span>-<span class="hljs-number">02</span>-<span class="hljs-number">01</span> <span class="hljs-number">07</span>:<span class="hljs-number">37</span>:<span class="hljs-number">29</span> SELECT version FROM schema_migrations ORDER BY version DESC
[ Info: <span class="hljs-number">2022</span>-<span class="hljs-number">02</span>-<span class="hljs-number">01</span> <span class="hljs-number">07</span>:<span class="hljs-number">37</span>:<span class="hljs-number">29</span> CREATE TABLE courses (id INTEGER PRIMARY KEY , title TEXT  , authors TEXT  , year INTEGER (<span class="hljs-number">4</span>) , rating TEXT  , categories TEXT  , description TEXT  , cost FLOAT (<span class="hljs-number">1000</span>) )
[ Info: <span class="hljs-number">2022</span>-<span class="hljs-number">02</span>-<span class="hljs-number">01</span> <span class="hljs-number">07</span>:<span class="hljs-number">37</span>:<span class="hljs-number">29</span> CREATE  INDEX courses__idx_title ON courses (title)
[ Info: <span class="hljs-number">2022</span>-<span class="hljs-number">02</span>-<span class="hljs-number">01</span> <span class="hljs-number">07</span>:<span class="hljs-number">37</span>:<span class="hljs-number">29</span> CREATE  INDEX courses__idx_authors ON courses (authors)
[ Info: <span class="hljs-number">2022</span>-<span class="hljs-number">02</span>-<span class="hljs-number">01</span> <span class="hljs-number">07</span>:<span class="hljs-number">37</span>:<span class="hljs-number">29</span> CREATE  INDEX courses__idx_categories ON courses (categories)
[ Info: <span class="hljs-number">2022</span>-<span class="hljs-number">02</span>-<span class="hljs-number">01</span> <span class="hljs-number">07</span>:<span class="hljs-number">37</span>:<span class="hljs-number">29</span> CREATE  INDEX courses__idx_description ON courses (description)
[ Info: <span class="hljs-number">2022</span>-<span class="hljs-number">02</span>-<span class="hljs-number">01</span> <span class="hljs-number">07</span>:<span class="hljs-number">37</span>:<span class="hljs-number">29</span> INSERT INTO schema_migrations VALUES ('<span class="hljs-number">2022020115190055</span>')
[ Info: <span class="hljs-number">2022</span>-<span class="hljs-number">02</span>-<span class="hljs-number">01</span> <span class="hljs-number">07</span>:<span class="hljs-number">37</span>:<span class="hljs-number">29</span> Executed migration CreateTableCourses up
</code></pre>
<p>We have now successfully completed the migrations. If you were to make a change to the schema, you would need to re-run the commands above for those database changes to take effect. </p>
<p>The last step in this process is to define our model. This will allow us to create objects in Julia code and then save them to the database we just defined. We need to navigate to <code>app/resources/courses/Courses.jl</code> or the equivalent path to make these final updates: </p>
<pre><code class="lang-julia"><span class="hljs-keyword">module</span> Courses

<span class="hljs-keyword">import</span> SearchLight: AbstractModel, DbId
<span class="hljs-keyword">import</span> Base: <span class="hljs-meta">@kwdef</span>

<span class="hljs-keyword">export</span> Course

<span class="hljs-meta">@kwdef</span> <span class="hljs-keyword">mutable struct</span> Course &lt;: AbstractModel
  id::DbId = DbId()
  title::<span class="hljs-built_in">String</span> = <span class="hljs-string">""</span>
  authors::<span class="hljs-built_in">String</span> = <span class="hljs-string">""</span>
  year::<span class="hljs-built_in">Int</span> = <span class="hljs-number">0</span>
  rating::<span class="hljs-built_in">String</span> = <span class="hljs-string">""</span>
  categories::<span class="hljs-built_in">String</span> = <span class="hljs-string">""</span>
  description::<span class="hljs-built_in">String</span> = <span class="hljs-string">""</span>
  cost::<span class="hljs-built_in">Float64</span> = <span class="hljs-number">0.0</span>
<span class="hljs-keyword">end</span>

<span class="hljs-keyword">end</span>
</code></pre>
<p>Again, this should be the same as the content you previously defined. To make sure this worked, we can do:</p>
<pre><code class="lang-julia">julia&gt; <span class="hljs-keyword">using</span> Courses
[ Info: <span class="hljs-number">2022</span>-<span class="hljs-number">02</span>-<span class="hljs-number">01</span> <span class="hljs-number">07</span>:<span class="hljs-number">43</span>:<span class="hljs-number">51</span> Precompiling Courses [top-level]
</code></pre>
<p>and then try creating a course via:</p>
<pre><code class="lang-julia">
julia&gt; c = Course(title = <span class="hljs-string">"Web dev with Genie.jl"</span>, authors=<span class="hljs-string">"Logan Kilpatrick"</span>)
Course
| KEY                 | VALUE                 |
|---------------------|-----------------------|
| authors::<span class="hljs-built_in">String</span>     | Logan Kilpatrick      |
| categories::<span class="hljs-built_in">String</span>  |                       |
| cost::<span class="hljs-built_in">Float64</span>       | <span class="hljs-number">0.0</span>                   |
| description::<span class="hljs-built_in">String</span> |                       |
| id::DbId            | NULL                  |
| rating::<span class="hljs-built_in">String</span>      |                       |
| title::<span class="hljs-built_in">String</span>       | Web dev with Genie.jl |
| year::<span class="hljs-built_in">Int64</span>         | <span class="hljs-number">0</span>                     |
</code></pre>
<p>We have successfully created our first object! But it is not saved to the database right away. We can verify this by doing:</p>
<pre><code class="lang-julia">julia&gt; ispersisted(c)
<span class="hljs-literal">false</span>
</code></pre>
<p>so we need to run:</p>
<pre><code class="lang-julia">julia&gt; save(c)
[ Info: <span class="hljs-number">2022</span>-<span class="hljs-number">02</span>-<span class="hljs-number">01</span> <span class="hljs-number">07</span>:<span class="hljs-number">47</span>:<span class="hljs-number">04</span> INSERT  INTO courses (<span class="hljs-string">"title"</span>, <span class="hljs-string">"authors"</span>, <span class="hljs-string">"year"</span>, <span class="hljs-string">"rating"</span>, <span class="hljs-string">"categories"</span>, <span class="hljs-string">"description"</span>, <span class="hljs-string">"cost"</span>) VALUES ('Web dev with Genie.jl', 'Logan Kilpatrick', <span class="hljs-number">0</span>, '', '', '', <span class="hljs-number">0.0</span>) 
[ Info: <span class="hljs-number">2022</span>-<span class="hljs-number">02</span>-<span class="hljs-number">01</span> <span class="hljs-number">07</span>:<span class="hljs-number">47</span>:<span class="hljs-number">04</span> ; SELECT CASE WHEN last_insert_rowid() = <span class="hljs-number">0</span> THEN -<span class="hljs-number">1</span> ELSE last_insert_rowid() END AS LAST_INSERT_ID
<span class="hljs-literal">true</span>
</code></pre>
<p>and now the course is saved! But to really test this out, we need the user to be able to create a course. Let's head back to <code>routes.jl</code> and enable that:</p>
<pre><code class="lang-julia"><span class="hljs-keyword">using</span> Genie, Genie.Router, Genie.Renderer.Html, Genie.Requests
<span class="hljs-keyword">using</span> Courses

form = <span class="hljs-string">"""
&lt;form action="/" method="POST" enctype="multipart/form-data"&gt;
  &lt;input type="text" name="name" value="" placeholder="What's the course name?" /&gt;
  &lt;input type="text" name="author" value="" placeholder="Who is the course author?" /&gt;

  &lt;input type="submit" value="Submit" /&gt;
&lt;/form&gt;
"""</span>

route(<span class="hljs-string">"/"</span>) <span class="hljs-keyword">do</span>
  html(form)
<span class="hljs-keyword">end</span>

route(<span class="hljs-string">"/"</span>, method = POST) <span class="hljs-keyword">do</span>
  c = Course(title=postpayload(:name, <span class="hljs-string">"Placeholder"</span>), authors=postpayload(:author, <span class="hljs-string">"Placeholder"</span>))
  save(c)
  <span class="hljs-string">"Course titled <span class="hljs-subst">$(c.title)</span> created successfully!"</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>We started by defining a simple HTML form (nothing new or exciting here), then, we made it so the default route <code>/</code> renders the HTML form. Lastly, we create another route for the <code>/</code> URL, but specifically for the POST method. Inside that route, we create a new course by pulling the info we want from the form out of the payload via <code>postpayload</code>. </p>
<p>You can try this by navigating back to: <a target="_blank" href="http://127.0.0.1:8000">http://127.0.0.1:8000</a></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/Screen-Shot-2022-02-01-at-8.11.38-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can try and enter some of the details and then press submit. To make sure the submissions worked, you can do:</p>
<pre><code class="lang-julia">julia&gt; all(Course)
[ Info: <span class="hljs-number">2022</span>-<span class="hljs-number">02</span>-<span class="hljs-number">01</span> <span class="hljs-number">08</span>:<span class="hljs-number">10</span>:<span class="hljs-number">19</span> SELECT <span class="hljs-string">"courses"</span>.<span class="hljs-string">"id"</span> AS <span class="hljs-string">"courses_id"</span>, <span class="hljs-string">"courses"</span>.<span class="hljs-string">"title"</span> AS <span class="hljs-string">"courses_title"</span>, <span class="hljs-string">"courses"</span>.<span class="hljs-string">"authors"</span> AS <span class="hljs-string">"courses_authors"</span>, <span class="hljs-string">"courses"</span>.<span class="hljs-string">"year"</span> AS <span class="hljs-string">"courses_year"</span>, <span class="hljs-string">"courses"</span>.<span class="hljs-string">"rating"</span> AS <span class="hljs-string">"courses_rating"</span>, <span class="hljs-string">"courses"</span>.<span class="hljs-string">"categories"</span> AS <span class="hljs-string">"courses_categories"</span>, <span class="hljs-string">"courses"</span>.<span class="hljs-string">"description"</span> AS <span class="hljs-string">"courses_description"</span>, <span class="hljs-string">"courses"</span>.<span class="hljs-string">"cost"</span> AS <span class="hljs-string">"courses_cost"</span> FROM <span class="hljs-string">"courses"</span> ORDER BY courses.id ASC
┌ Warning: <span class="hljs-number">2022</span>-<span class="hljs-number">02</span>-<span class="hljs-number">01</span> <span class="hljs-number">08</span>:<span class="hljs-number">10</span>:<span class="hljs-number">19</span> Unsupported SQLite declared <span class="hljs-keyword">type</span> INTEGER (<span class="hljs-number">4</span>), falling back to <span class="hljs-built_in">Int64</span> <span class="hljs-keyword">type</span>
└ @ SQLite ~/.julia/packages/SQLite/aDggE/src/SQLite.jl:<span class="hljs-number">416</span>
┌ Warning: <span class="hljs-number">2022</span>-<span class="hljs-number">02</span>-<span class="hljs-number">01</span> <span class="hljs-number">08</span>:<span class="hljs-number">10</span>:<span class="hljs-number">19</span> Unsupported SQLite declared <span class="hljs-keyword">type</span> FLOAT (<span class="hljs-number">1000</span>), falling back to <span class="hljs-built_in">Float64</span> <span class="hljs-keyword">type</span>
└ @ SQLite ~/.julia/packages/SQLite/aDggE/src/SQLite.jl:<span class="hljs-number">416</span>
<span class="hljs-number">3</span>-element <span class="hljs-built_in">Vector</span>{Course}:
 Course
| KEY                 | VALUE                 |
|---------------------|-----------------------|
| authors::<span class="hljs-built_in">String</span>     | Logan Kilpatrick      |
| categories::<span class="hljs-built_in">String</span>  |                       |
| cost::<span class="hljs-built_in">Float64</span>       | <span class="hljs-number">0.0</span>                   |
| description::<span class="hljs-built_in">String</span> |                       |
| id::DbId            | <span class="hljs-number">1</span>                     |
| rating::<span class="hljs-built_in">String</span>      |                       |
| title::<span class="hljs-built_in">String</span>       | Web dev with Genie.jl |
| year::<span class="hljs-built_in">Int64</span>         | <span class="hljs-number">0</span>                     |

 Course
| KEY                 | VALUE       |
|---------------------|-------------|
| authors::<span class="hljs-built_in">String</span>     | Logan K     |
| categories::<span class="hljs-built_in">String</span>  |             |
| cost::<span class="hljs-built_in">Float64</span>       | <span class="hljs-number">0.0</span>         |
| description::<span class="hljs-built_in">String</span> |             |
| id::DbId            | <span class="hljs-number">2</span>           |
| rating::<span class="hljs-built_in">String</span>      |             |
| title::<span class="hljs-built_in">String</span>       | Test course |
| year::<span class="hljs-built_in">Int64</span>         | <span class="hljs-number">0</span>           |
</code></pre>
<p>which should show that the entries were saved in the database.</p>
<h2 id="heading-wrapping-up">Wrapping up 🎁</h2>
<p>Wow, that was a lot. We covered a tremendous amount of ground in this single tutorial. </p>
<p>With that said, there is even more to learn about Genie. I highly suggest checking out the <a target="_blank" href="https://genieframework.com/docs/tutorials/Overview.html">docs here</a>, which has lots more tutorials on topics like REST API's, Authentication, and much more. </p>
<h2 id="heading-getting-help-with-geniejl">Getting help with Genie.jl 🚨</h2>
<p>If you run into issues with this tutorial or when using Genie, please post a question on Stack Overflow with the <code>genie.jl</code> and <code>julia</code> tag or on the <a target="_blank" href="https://discourse.julialang.org">Julia Discourse</a>. After that, feel free to tweet the link to the question at me and I will do my best to help: <a target="_blank" href="https://twitter.com/OfficialLoganK">https://twitter.com/OfficialLoganK</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Julia For Beginners – The Future Programming Language of  Data Science and Machine Learning Explained ]]>
                </title>
                <description>
                    <![CDATA[ By Logan Kilpatrick Julia is a high-level, dynamic programming language, designed to give users the speed of C/C++ while remaining as easy to use as Python. This means that developers can solve problems faster and more effectively. Julia is great for... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-julia-programming-language/</link>
                <guid isPermaLink="false">66d4601751f567b42d9f8491</guid>
                
                    <category>
                        <![CDATA[ Data Science ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Julia ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Julialang ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Machine Learning ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 27 Dec 2021 17:13:56 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/12/LearningJuliafreeCodeCamp.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Logan Kilpatrick</p>
<p>Julia is a high-level, dynamic programming language, designed to give users the speed of C/C++ while remaining as easy to use as Python. This means that developers can solve problems faster and more effectively.</p>
<p>Julia is great for computational complex problems. Many early adopters of Julia were concentrated in scientific domains like Chemistry, Biology, and Machine Learning. </p>
<p>This said, Julia is general-purpose language and can be used for tasks like Web Development, Game Development, and more. Many view Julia as the next-generation language for Machine Learning and Data Science, including the CEO of Shopify (among many others):</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/tobi/status/1474369669888937992?s=20"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<h2 id="heading-how-to-download-the-julia-programming-language">How to Download the Julia Programming Language ⤵️</h2>
<p>There are two main ways to run Julia: via a <code>.jl</code> file in an <a target="_blank" href="https://code.visualstudio.com/docs/languages/julia">IDE like VS Code</a> or command by command in the Julia REPL (Read Evaluate Print Loop). In this guide, we will mainly use the Julia REPL. Before you can use either, you will need to download Julia:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/t67TGcf4SmM" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>or just head to: <a target="_blank" href="https://julialang.org/downloads/">https://julialang.org/downloads/</a></p>
<p>After you have Julia installed, you should be able to launch it and see:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screen-Shot-2021-12-24-at-5.56.14-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Julia 1.7 REPL after install</em></p>
<h2 id="heading-julia-programming-language-basics-for-beginners">Julia Programming Language Basics for Beginners</h2>
<p>Before we can use Julia for all of the exciting things it was built for like Machine Learning or Data Science, we first need to get familiar with the basics of the language. </p>
<p>We will start by going over variables, types, and conditionals. Then, we will talk about loops, functions, and packages. Last, we’ll touch on more advanced concepts like structs and talk about additional learning resources. </p>
<p>This is going to be a whirlwind tour so strap in and get ready! It is also worth noting that this tutorial assumes you have some basic familiarity with programming. If you don't, check out this course on an <a target="_blank" href="https://juliaacademy.com/p/julia-programming-for-nervous-beginners">Intro to Julia for Nervous Beginners</a>.</p>
<h2 id="heading-an-introduction-to-julia-variables-and-types">An Introduction to Julia Variables and Types ⌨️</h2>
<p>In Julia, variables are dynamically typed, meaning that you do not need to specify the variable's type when you create it.</p>
<pre><code class="lang-julia">julia&gt; a = <span class="hljs-number">10</span> <span class="hljs-comment"># Create the variable "a" and assign it the number 10</span>
<span class="hljs-number">10</span>

julia&gt; a + <span class="hljs-number">10</span> <span class="hljs-comment"># Do a basic math operation using "a"</span>
<span class="hljs-number">20</span>
</code></pre>
<p><em>(Note that in code snippets, when you see <code>julia&gt;</code> it means the code is being run in the REPL)</em></p>
<p>Just like we defined a variable above and assigned it an integer (whole number), we can also do something similar for strings and other variable types:</p>
<pre><code class="lang-julia">julia&gt; my_string = <span class="hljs-string">"Hello freeCodeCamp"</span> <span class="hljs-comment"># Define a string variable</span>
<span class="hljs-string">"Hello freeCodeCamp"</span>

julia&gt; balance = <span class="hljs-number">238.19</span> <span class="hljs-comment"># Define a float variable </span>
<span class="hljs-number">238.19</span>
</code></pre>
<p>When creating variables in Julia, the variable name will always go on the left-hand side, and the value will always go on the right-hand side after the equals sign. We can also create new variables based on the values of other variables:</p>
<pre><code class="lang-julia">julia&gt; new_balance = balance + a
<span class="hljs-number">248.19</span>
</code></pre>
<p>Here we can see that the <code>new_balance</code> is now the sum (total) of 238.19 and 10. Note further that the type of <code>new_balance</code> is a float (number with decimal place precision) because when we add a float and int together, we automatically get the type with higher precision, which in this case is a float. We can confirm this by doing:</p>
<pre><code class="lang-julia">julia&gt; typeof(new_balance)
<span class="hljs-built_in">Float64</span>
</code></pre>
<p>Due to the nature of dynamic typing, variables in Julia can also change type. This means that at one point, <code>holder_balance</code> could be a float, and then later on it could be a string:</p>
<pre><code class="lang-julia">julia&gt; holder_balance = <span class="hljs-number">100.34</span>
<span class="hljs-number">100.34</span>

julia&gt; holder_balance = <span class="hljs-string">"The Type has changed"</span>
<span class="hljs-string">"The Type has changed"</span>

julia&gt; typeof(holder_balance)
<span class="hljs-built_in">String</span>
</code></pre>
<p>You may also be excited to know that variable names in Julia are very flexible, in fact, you can do something like:</p>
<pre><code class="lang-julia">julia&gt; 😀 = <span class="hljs-number">10</span>
<span class="hljs-number">10</span>

julia&gt; 🥲 = -<span class="hljs-number">10</span>
-<span class="hljs-number">10</span>

julia&gt; 😀 + 🥲
<span class="hljs-number">0</span>
</code></pre>
<p>On top of emoji variable names, you can also use any other Unicode variable name which is very helpful when you are trying to represent mathematical ideas. You can access these Unicode variables by doing a <code>\</code> and then typing the name, followed by pressing tab:</p>
<pre><code class="lang-julia">julia&gt; \sigma <span class="hljs-comment"># press tab and it will render the symbol</span>

julia&gt; σ = <span class="hljs-number">10</span> <span class="hljs-comment"># set sigma equal to 10</span>
</code></pre>
<p>Overall, the variable system in Julia is flexible and provides a huge set of features that make writing Julia code easy while still being expressive. If you want to learn more about variables in Julia, check out the Julia documentation: <a target="_blank" href="https://docs.julialang.org/en/v1/manual/variables/">https://docs.julialang.org/en/v1/manual/variables/</a></p>
<h2 id="heading-how-to-write-conditional-statements-in-julia">How to Write Conditional Statements in Julia  🔀</h2>
<p>In programming, you often need to check certain conditions in order to make sure that specific lines of code run. For example, if you write a banking program, you might only want to let someone withdraw money if the amount they are trying to withdraw is less than the amount they have present in their account. </p>
<p>Let us look at a basic example of a conditional statement in Julia:</p>
<pre><code class="lang-julia">julia&gt; bank_balance = <span class="hljs-number">4583.11</span>
<span class="hljs-number">4583.11</span>

julia&gt; withdraw_amount = <span class="hljs-number">250</span>
<span class="hljs-number">250</span>

julia&gt; <span class="hljs-keyword">if</span> withdraw_amount &lt;= bank_balance
           bank_balance -= withdraw_amount
           print(<span class="hljs-string">"Withdrew "</span>, withdraw_amount, <span class="hljs-string">" from your account"</span>)
       <span class="hljs-keyword">end</span>
Withdrew <span class="hljs-number">250</span> from your account
</code></pre>
<p>Let us take a closer look here at some parts of the if statement that might differ from other code you have seen: First, we use no <code>:</code> to denote the end of the line and we also are not required to use <code>()</code> around the statement (though it is encouraged). Next, we don't use <code>{}</code> or the like to denote the end of the conditional, instead, we use the <code>end</code> keyword. </p>
<p>Just like we used the if statement, we can chain it with an <code>else</code> or an <code>elseif</code>:</p>
<pre><code class="lang-julia">julia&gt; withdraw_amount = <span class="hljs-number">4600</span>
<span class="hljs-number">4600</span>

julia&gt; <span class="hljs-keyword">if</span> withdraw_amount &lt;= bank_balance
           bank_balance -= withdraw_amount
           print(<span class="hljs-string">"Withdrew "</span>, withdraw_amount, <span class="hljs-string">" from your account"</span>)
       <span class="hljs-keyword">else</span>
           print(<span class="hljs-string">"Insufficent balance"</span>)
       <span class="hljs-keyword">end</span>
Insufficent balance
</code></pre>
<p>You can read more about control flow and conditional expressions in the Julia documentation: <a target="_blank" href="https://docs.julialang.org/en/v1/manual/control-flow/#man-conditional-evaluation">https://docs.julialang.org/en/v1/manual/control-flow/#man-conditional-evaluation</a></p>
<h2 id="heading-how-to-use-loops-in-julia">How to use Loops in Julia 🔂</h2>
<p>There are two main types of loops in Julia: a for loop and a while loop. As is the same with other languages, the biggest difference is that in a for loop, you are going through a pre-defined number of items whereas, in a while loop, you are iterating until some condition is changed. </p>
<p>Syntactically, the loops in Julia look very similar in structure to the if conditionals we just looked at:</p>
<pre><code class="lang-julia">julia&gt; greeting = [<span class="hljs-string">"Hello"</span>, <span class="hljs-string">"world"</span>, <span class="hljs-string">"and"</span>, <span class="hljs-string">"welcome"</span>, <span class="hljs-string">"to"</span>, <span class="hljs-string">"freeCodeCamp"</span>] <span class="hljs-comment"># define greeting, an array of strings</span>
<span class="hljs-number">6</span>-element <span class="hljs-built_in">Vector</span>{<span class="hljs-built_in">String</span>}:
 <span class="hljs-string">"Hello"</span>
 <span class="hljs-string">"world"</span>
 <span class="hljs-string">"and"</span>
 <span class="hljs-string">"welcome"</span>
 <span class="hljs-string">"to"</span>
 <span class="hljs-string">"freeCodeCamp"</span>

julia&gt; <span class="hljs-keyword">for</span> word <span class="hljs-keyword">in</span> greeting
           print(word, <span class="hljs-string">" "</span>)
       <span class="hljs-keyword">end</span>
Hello world and welcome to freeCodeCamp
</code></pre>
<p>In this example, we first defined a new type: a vector (also called an array). This array is holding a bunch of strings we defined. The behavior is very similar to that of arrays in other languages but it is worth noting that arrays are mutable (meaning you can change the number of items in the array after you create it).</p>
<p>Again, when we look at the structure of the for loop, you can see that we are iterating through the <code>greeting</code> variable. Each time through, we get a new word (in this case) from the array and assign it to a temporary variable <code>word</code> which we then print out. You will notice that the structure of this loop looks similar to the if statement and again uses the <code>end</code> keyword. </p>
<p>Now that we explored for loops, let us switch gears and take a look at a while loop in Julia:</p>
<pre><code class="lang-julia">julia&gt; <span class="hljs-keyword">while</span> user_input != <span class="hljs-string">"End"</span>
           print(<span class="hljs-string">"Enter some input, or End to quit: "</span>)
           user_input = readline() <span class="hljs-comment"># Prompt the user for input</span>
       <span class="hljs-keyword">end</span>
Enter some input, or End to quit: hi
Enter some input, or End to quit: test
Enter some input, or End to quit: no
Enter some input, or End to quit: End
</code></pre>
<p>For this while loop, we set it up so that it will run indefinitely until the user typed the word "End". As you have now seen it a few times, the structure of the loop should start to look familiar. </p>
<p>If you want to see some more examples of loops in Julia, you can check out the Julia Documentation's section on loops: <a target="_blank" href="https://docs.julialang.org/en/v1/manual/control-flow/#man-loops">https://docs.julialang.org/en/v1/manual/control-flow/#man-loops</a></p>
<h2 id="heading-how-to-use-functions-in-julia">How to use Functions in Julia</h2>
<p>Functions are used to create multiple lines of code, chained together, and accessible when you reference a function name. First, let us look at an example of a basic function:</p>
<pre><code class="lang-julia">julia&gt; <span class="hljs-keyword">function</span> greet()
           print(<span class="hljs-string">"Hello new Julia user!"</span>)
       <span class="hljs-keyword">end</span>
greet (generic <span class="hljs-keyword">function</span> with <span class="hljs-number">1</span> method)

julia&gt; greet()
Hello new Julia user!
</code></pre>
<p>Functions can also take arguments, just like in other languages:</p>
<pre><code class="lang-julia">julia&gt; <span class="hljs-keyword">function</span> greetuser(user_name)
           print(<span class="hljs-string">"Hello "</span>, user_name, <span class="hljs-string">", welcome to the Julia Community"</span>)
       <span class="hljs-keyword">end</span>
greetuser (generic <span class="hljs-keyword">function</span> with <span class="hljs-number">1</span> method)

julia&gt; greetuser(<span class="hljs-string">"Logan"</span>)
Hello Logan, welcome to the Julia Community
</code></pre>
<p>In this example, we take in one argument, and then add its value to the print out. But what if we don't get a string?</p>
<pre><code class="lang-julia">julia&gt; greetuser(<span class="hljs-literal">true</span>)
Hello <span class="hljs-literal">true</span>, welcome to the Julia Community
</code></pre>
<p>In this case, since we are just printing, the function continues to work despite not taking in a string anymore and instead of taking a boolean value (true or false). To prevent this from occurring, we can explicitly type the input arguments as follows:</p>
<pre><code class="lang-julia">julia&gt; <span class="hljs-keyword">function</span> greetuser(user_name::<span class="hljs-built_in">String</span>)
           print(<span class="hljs-string">"Hello "</span>, user_name, <span class="hljs-string">", welcome to the Julia Community"</span>)
       <span class="hljs-keyword">end</span>
greetuser (generic <span class="hljs-keyword">function</span> with <span class="hljs-number">2</span> methods)

julia&gt; greetuser(<span class="hljs-string">"Logan"</span>)
Hello Logan, welcome to the Julia Community
</code></pre>
<p>So now the function is defined to take in only a string. Let us test this out to make sure we can only call the function with a string value:</p>
<pre><code class="lang-julia">julia&gt; greetuser(<span class="hljs-literal">true</span>)
Hello <span class="hljs-literal">true</span>, welcome to the Julia Community
</code></pre>
<p>Wait a second, why is this happening? We re-defined the <code>greetuser</code> function, it should not take <code>true</code> anymore. </p>
<p>What we are experiencing here is one of the most powerful underlying features of Julia: Multiple Dispatch. Julia allows us to define functions with the same name and number of arguments but that accept different types. This means we can build either generic or type specific versions of functions which helps immensely with code readability since you don't need to handle every scenario in one function. </p>
<p>We should quickly confirm that we actually defined both functions:</p>
<pre><code class="lang-julia">julia&gt; methods(greetuser)
<span class="hljs-comment"># 2 methods for generic function "greetuser":</span>
[<span class="hljs-number">1</span>] greetuser(user_name::<span class="hljs-built_in">String</span>) <span class="hljs-keyword">in</span> Main at REPL[<span class="hljs-number">34</span>]:<span class="hljs-number">1</span>
[<span class="hljs-number">2</span>] greetuser(user_name) <span class="hljs-keyword">in</span> Main at REPL[<span class="hljs-number">30</span>]:<span class="hljs-number">1</span>
</code></pre>
<p>The built-in <code>methods</code> function is perfect for this and it tells us we have two functions defined, with the only difference being one takes in any type, and the other takes in just a string. </p>
<p>It is worth noting that since we defined a specialized version that accepts just a string, anytime we call the function with a string it will call the specialized version. The more generic function will not be called when a string is passed in.</p>
<p>Next, let us talk about returning values from a function. In Julia, you have two options, you can use the explicit <code>return</code> keyword, or you can opt to do it implicitly by having the last expression in the function serve as the return value like so:</p>
<pre><code class="lang-julia">julia&gt; <span class="hljs-keyword">function</span> sayhi()
           <span class="hljs-string">"This is a test"</span>
           <span class="hljs-string">"hi"</span>
       <span class="hljs-keyword">end</span>
sayhi (generic <span class="hljs-keyword">function</span> with <span class="hljs-number">1</span> method)

julia&gt; sayhi()
<span class="hljs-string">"hi"</span>
</code></pre>
<p>In the above example, the string value "hi" is returned from the function since it is the last expression and there is no explicit return statement. You could also define the function like:</p>
<pre><code class="lang-julia">julia&gt; <span class="hljs-keyword">function</span> sayhi()
           <span class="hljs-string">"This is a test"</span>
          <span class="hljs-keyword">return</span> <span class="hljs-string">"hi"</span>
       <span class="hljs-keyword">end</span>
sayhi (generic <span class="hljs-keyword">function</span> with <span class="hljs-number">1</span> method)

julia&gt; sayhi()
<span class="hljs-string">"hi"</span>
</code></pre>
<p>In general, from a readability standpoint, it makes sense to use the explicit return statement in case someone reading your code does not know about the implicit return behavior in Julia functions.</p>
<p>Another useful functions feature is the ability to provide optional arguments: </p>
<pre><code class="lang-julia">
julia&gt; <span class="hljs-keyword">function</span> sayhello(response=<span class="hljs-string">"hello"</span>)
          <span class="hljs-keyword">return</span> response
       <span class="hljs-keyword">end</span>
sayhello (generic <span class="hljs-keyword">function</span> with <span class="hljs-number">2</span> methods)

julia&gt; sayhello()
<span class="hljs-string">"hello"</span>

julia&gt; sayhello(<span class="hljs-string">"hi"</span>)
<span class="hljs-string">"hi"</span>
</code></pre>
<p>In this example, we define <code>response</code> as an optional argument so that we can either allow it to use the default behavior we defined or we can manually override it when necessary. These examples just scratch the surface on what is possible with functions in Julia. If you want to read more about all the cool things you can do, check out: <a target="_blank" href="https://docs.julialang.org/en/v1/manual/functions/">https://docs.julialang.org/en/v1/manual/functions/</a></p>
<h2 id="heading-how-to-use-packages-in-julia">How to use Packages in Julia 📦</h2>
<p>The Julia package manager and package ecosystem are some of the most important features of the language. I actually wrote an entire article on <a target="_blank" href="https://logankilpatrick.medium.com/the-most-underrated-feature-of-the-julia-programming-language-the-package-manager-652065f45a3a">why it is one of the most underrate features of the language</a>. </p>
<p>With that said, there are two ways to interact with packages in Julia: via the REPL or using the Pkg package. We will mostly focus on the REPL in this post since it is much easier to use in my experience.</p>
<p>After you have Julia installed, you can enter the package manager from the REPL by typing <code>]</code>. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screen-Shot-2021-12-26-at-9.50.05-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Pkg mode in the Julia REPL</em></p>
<p>Now that we are in the package manager, there are a few things we commonly want to do:</p>
<ul>
<li>Add a package</li>
<li>Remove a package</li>
<li>Check what is already installed</li>
</ul>
<p>If you want to see all the possible commands in the REPL, simply enter Pkg mode by typing <code>]</code> and then type <code>?</code>  followed by the enter / return key.</p>
<h3 id="heading-how-to-add-julia-packages">How to Add Julia Packages ➕</h3>
<p>Let’s add our first package, <code>Example.jl</code> . To do so, we can run:</p>
<pre><code class="lang-julia">(<span class="hljs-meta">@v1</span><span class="hljs-number">.7</span>) pkg&gt; add Example
</code></pre>
<p>which should provide output that looks something like:</p>
<pre><code class="lang-julia">(<span class="hljs-meta">@v1</span><span class="hljs-number">.7</span>) pkg&gt; add Example
Updating registry at <span class="hljs-string">`~/.julia/registries/General`</span>
Updating git-repo <span class="hljs-string">`https://github.com/JuliaRegistries/General.git`</span>
Updating registry at <span class="hljs-string">`~/.julia/registries/JuliaPOMDP`</span>
Updating git-repo <span class="hljs-string">`https://github.com/JuliaPOMDP/Registry`</span>
Resolving package versions...
Installed Example ─ v0<span class="hljs-number">.5</span><span class="hljs-number">.3</span>
Updating <span class="hljs-string">`~/.julia/environments/v1.7/Project.toml`</span>
[<span class="hljs-number">7876</span>af07] + Example v0<span class="hljs-number">.5</span><span class="hljs-number">.3</span>
Updating <span class="hljs-string">`~/.julia/environments/v1.7/Manifest.toml`</span>
[<span class="hljs-number">7876</span>af07] + Example v0<span class="hljs-number">.5</span><span class="hljs-number">.3</span>
Precompiling project...
<span class="hljs-number">1</span> dependency successfully precompiled <span class="hljs-keyword">in</span> <span class="hljs-number">1</span> seconds (<span class="hljs-number">69</span> already precompiled)
(<span class="hljs-meta">@v1</span><span class="hljs-number">.7</span>) pkg&gt;
</code></pre>
<p><em>For space reasons, I will skip further outputs under the assumption that you are following along with me.</em></p>
<h3 id="heading-how-to-check-the-package-status-in-julia">How to Check the Package Status in Julia 🔍</h3>
<p>Now that we think we have a package installed, let’s doublecheck if it is really there by typing <code>status</code> (or <code>st</code> for shorthand) into the package manager:</p>
<pre><code class="lang-julia">(<span class="hljs-meta">@v1</span><span class="hljs-number">.7</span>) pkg&gt; st
Status <span class="hljs-string">`~/.julia/environments/v1.7/Project.toml`</span>
[<span class="hljs-number">7876</span>af07] Example v0<span class="hljs-number">.5</span><span class="hljs-number">.3</span>
[<span class="hljs-number">587475</span>ba] Flux v0<span class="hljs-number">.12</span><span class="hljs-number">.8</span>
</code></pre>
<p>Here we can see I have two packages installed, Flux and Example. It also gives me the path to the file which manages my current environment (in this case, global Julia v1.7) along with the package versions I have installed.</p>
<h3 id="heading-how-to-remove-a-julia-package">How to Remove a Julia package 📛</h3>
<p>If I wanted to remove a package from my active environment, like Flux, I can simply type <code>remove Flux</code> (or <code>rm</code> as the shorthand):</p>
<pre><code class="lang-julia">(<span class="hljs-meta">@v1</span><span class="hljs-number">.7</span>) pkg&gt; rm Flux
Updating <span class="hljs-string">`~/.julia/environments/v1.7/Project.toml`</span>
[<span class="hljs-number">587475</span>ba] - Flux v0<span class="hljs-number">.12</span><span class="hljs-number">.8</span>
</code></pre>
<p>A quick <code>status</code> afterward shows this was successful:</p>
<pre><code class="lang-julia">(<span class="hljs-meta">@v1</span><span class="hljs-number">.7</span>) pkg&gt; st
Status <span class="hljs-string">`~/.julia/environments/v1.7/Project.toml`</span>
[<span class="hljs-number">7876</span>af07] Example v0<span class="hljs-number">.5</span><span class="hljs-number">.3</span>
</code></pre>
<p>We now know the very basics of working with packages. But we have committed a major programming crime, using our global package environment. </p>
<h3 id="heading-how-to-use-julia-packages">How to Use Julia Packages 📦</h3>
<p>Now that we have gone over how to manage packages, let’s explore how to use them. Quite simply, you just need to type <code>using packageName</code> to use a specific package you want. One of my favorite new features in Julia 1.7 (highlighted in <a target="_blank" href="https://julialang.org/blog/2021/11/julia-1.7-highlights/">this blog post</a>) is shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/1-jI58_UDd87Q4fQ326r6E6Q.png" alt="Image" width="600" height="400" loading="lazy">
<em>Image captured by Author</em></p>
<p>If you recall, we removed the Flux package, and of course, I forgot this so I went to use it and load it in by typing <code>using Flux</code>. The REPL automatically prompts me to install it via a simple "y/n" prompt. This is a small feature but saves a tremendous amount of time and potential confusion.</p>
<p>It is worth noting that there are two ways to access a package's exported functions: via the <code>using</code> keyword and the <code>import</code> keyword. The big difference is that <code>using</code> automatically brings all of the functions into the current namespace (for which you can think about as a big list of functions which Julia knows the definitions) whereas <code>import</code> gives you access to all of the functions but you have to prefix the function with the package name like: <code>Flux.gradient()</code> where <code>Flux</code> is the name of the package and <code>gradient()</code> is the name of a function.</p>
<hr>
<h2 id="heading-how-to-use-structs-in-julia">How to use Structs in Julia?</h2>
<p>Julia does not have Object Orientated Programming (OOP) paradigms built into the language like classes. However, structs in Julia can be used similar to classes to create custom objects and types. Below, we will show a basic example:</p>
<pre><code class="lang-julia">julia&gt; <span class="hljs-keyword">mutable struct</span> dog
           breed::<span class="hljs-built_in">String</span>
           paws::<span class="hljs-built_in">Int</span>
           name::<span class="hljs-built_in">String</span>
           weight::<span class="hljs-built_in">Float64</span>
       <span class="hljs-keyword">end</span>

julia&gt; my_dog = dog(<span class="hljs-string">"Australian Shepard"</span>, <span class="hljs-number">4</span>, <span class="hljs-string">"Indy"</span>, <span class="hljs-number">34.0</span>)
dog(<span class="hljs-string">"Australian Shepard"</span>, <span class="hljs-number">4</span>, <span class="hljs-string">"Indy"</span>, <span class="hljs-number">34.0</span>)

julia&gt; my_dog.name
<span class="hljs-string">"Indy"</span>
</code></pre>
<p>In this example, we define a struct to represent a dog. In the struct, we define four attributes which make up the dog object. In the lines after that, we show the code to actually create a dog object and then access some of its attributes. Note that you need not specify the types of the attributes, you could leave it more open. For this example, we defined explicit types to highlight that feature.</p>
<p>You will notice that similar to classes in Python (and other languages), we did not define an explicit constructor to create the dog object. We can, however, define one if that would be useful to use:</p>
<pre><code class="lang-julia">julia&gt; <span class="hljs-keyword">mutable struct</span> dog
           breed::<span class="hljs-built_in">String</span>
           paws::<span class="hljs-built_in">Int</span>
           name::<span class="hljs-built_in">String</span>
           weight::<span class="hljs-built_in">Float64</span>

           <span class="hljs-keyword">function</span> dog(breed, name, weight, paws=<span class="hljs-number">4</span>)
               new(breed, paws, name, weight)
           <span class="hljs-keyword">end</span>
       <span class="hljs-keyword">end</span>

julia&gt; new_dog = dog(<span class="hljs-string">"German Shepard"</span>, <span class="hljs-string">"Champ"</span>, <span class="hljs-number">46</span>)
dog(<span class="hljs-string">"German Shepard"</span>, <span class="hljs-number">4</span>, <span class="hljs-string">"Champ"</span>, <span class="hljs-number">46.0</span>)
</code></pre>
<p>Here we defined a constructor and used the special keyword <code>new</code> in order to create the object at the end of the function. You can also create getters and setters specifically for the dog object by doing the following:</p>
<pre><code class="lang-julia">julia&gt; <span class="hljs-keyword">function</span> get_name(dog_obj::dog)
           print(<span class="hljs-string">"The dogs's name is: "</span>, dog_obj.name)
       <span class="hljs-keyword">end</span>
get_name (generic <span class="hljs-keyword">function</span> with <span class="hljs-number">1</span> method)

julia&gt; get_name(new_dog)
The dogs's name is: Champ
</code></pre>
<p>In this example, the <code>get_name</code> function only takes an object of type <code>dog</code>. If you try to pass in something else, it will error out:</p>
<pre><code class="lang-julia">julia&gt; get_name(<span class="hljs-string">"test"</span>)
ERROR: <span class="hljs-built_in">MethodError</span>: no method matching get_name(::<span class="hljs-built_in">String</span>)
Closest candidates are:
  get_name(::dog) at REPL[<span class="hljs-number">61</span>]:<span class="hljs-number">1</span>
Stacktrace:
 [<span class="hljs-number">1</span>] top-level scope
   @ REPL[<span class="hljs-number">63</span>]:<span class="hljs-number">1</span>
</code></pre>
<p>It is worth noting that we also defined the struct to be mutable initially so that we could change the field values after we created the object. You omit the keyword <code>mutable</code> if you want the objects initial state to persist.</p>
<p>Structs in Julia not only allow us to create object's, we also are defining a custom type in the process:</p>
<pre><code class="lang-julia">julia&gt; typeof(new_dog)
dog
</code></pre>
<p>In general, structs are used heavily across the Julia ecosystem and you can learn more about them in the docs: <a target="_blank" href="https://docs.julialang.org/en/v1/base/base/#struct">https://docs.julialang.org/en/v1/base/base/#struct</a></p>
<h2 id="heading-additional-julia-programming-learning-resources">Additional Julia Programming Learning Resources 📚</h2>
<p>I hope that this tutorial helped get you up to speed on many of the core ideas of the Julia language. With that said, I know that there are still gaps as this is an extended but non-comprehensive guide. To learn more about Julia, you can check out the learning tab on the Julia website: <a target="_blank" href="https://julialang.org/learning/">https://julialang.org/learning/</a> which has guided courses, YouTube videos, and mentored practice problems. </p>
<p>If you have other questions or need help getting started with Julia, please feel free to get in touch with me: <a target="_blank" href="https://twitter.com/OfficialLoganK">https://twitter.com/OfficialLoganK</a></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
