<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Daniel Elegberun</title>
    <description>The latest articles on Forem by Daniel Elegberun (@gbengelebs).</description>
    <link>https://forem.com/gbengelebs</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F399117%2Ff37aacbe-05de-41ad-902f-a4ae9cb82fe0.jpeg</url>
      <title>Forem: Daniel Elegberun</title>
      <link>https://forem.com/gbengelebs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/gbengelebs"/>
    <language>en</language>
    <item>
      <title>Building a personalized workout recommender using content-based filtering with ML.NET</title>
      <dc:creator>Daniel Elegberun</dc:creator>
      <pubDate>Wed, 19 Feb 2025 20:23:27 +0000</pubDate>
      <link>https://forem.com/gbengelebs/building-a-personalized-workout-recommender-with-mlnet-a-step-by-step-guide-1nji</link>
      <guid>https://forem.com/gbengelebs/building-a-personalized-workout-recommender-with-mlnet-a-step-by-step-guide-1nji</guid>
      <description>&lt;p&gt;We are currently experiencing the Artificial Intelligence(AI) revolution. The explosion of large language models (LLMs) and machine learning has transformed multiple industries, including the health and fitness space.&lt;/p&gt;

&lt;p&gt;One of the most exciting applications of AI in fitness is the creation of personalized workout plans. With libraries like &lt;a href="https://dotnet.microsoft.com/en-us/apps/ai/ml-dotnet" rel="noopener noreferrer"&gt;ML.NET&lt;/a&gt;, developers can leverage the power of machine learning in the C# and .NET ecosystem. In this article, we’ll explore how to build a simple workout recommender application using content filtering in ML.NET.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is content filtering?
&lt;/h2&gt;

&lt;p&gt;Content-based filtering is a recommendation technique that suggests items (e.g., workouts, movies, products) to users based on the similarity between the item’s features and the input preferences of the system. Content filtering is used in recommendation systems and information retrieval (e.g., searching for similar documents).&lt;/p&gt;

&lt;p&gt;In our workout recommendation, the user would enter the query &lt;strong&gt;“beginner chest exercises with dumbbells”&lt;/strong&gt;  and get exercise recommendations that are most similar to the query. &lt;/p&gt;

&lt;h2&gt;
  
  
  How does content-based filtering work?
&lt;/h2&gt;

&lt;p&gt;Content-based filtering works by analyzing the characteristics of the features of items in a dataset comparing it to the user’s query and then recommending items or features that are similar. &lt;/p&gt;

&lt;h3&gt;
  
  
  1. Exercise representation
&lt;/h3&gt;

&lt;p&gt;Each exercise in our dataset is represented by its features, such as the body part(s) it targets &lt;strong&gt;(chest, legs, arms)&lt;/strong&gt;, equipment needed &lt;strong&gt;(dumbbells, resistance bands)&lt;/strong&gt;, or difficulty level &lt;strong&gt;(beginner, intermediate, advanced)&lt;/strong&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  2. User query as input
&lt;/h3&gt;

&lt;p&gt;The user enters a query, such as &lt;strong&gt;"beginner exercises for the chest with dumbbells"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This query is processed and transformed into a feature vector that represents the user’s intent. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Query: "Exercises for the chest with dumbbells"&lt;/li&gt;
&lt;li&gt;Features: {"chest": 1, "equipment": "dumbbell", "difficulty": beginner}&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Similarity measurement
&lt;/h3&gt;

&lt;p&gt;The system compares the &lt;strong&gt;user’s query vector&lt;/strong&gt; with the &lt;strong&gt;feature vectors&lt;/strong&gt; of all exercises in the database.&lt;/p&gt;

&lt;p&gt;For this project, we’ll be making use of cosine similarity. Cosine similarity is a common metric used to measure how similar two vectors are. It calculates the cosine of the angle between the two vectors, providing a score between 0 and 1, where 1 indicates a perfect match and 0 indicates no match.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Recommendation generation
&lt;/h3&gt;

&lt;p&gt;Based on the similarity scores, the system ranks the exercises and recommends the top-N exercises that best match the user’s query.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cosine similarity in depth
&lt;/h2&gt;

&lt;p&gt;Cosine similarity is particularly useful for comparing the user’s query with the exercise features because it focuses on the direction of the vectors rather than their magnitude. This makes it ideal for comparing sparse or unevenly weighted features.&lt;/p&gt;

&lt;p&gt;To compute cosine similarity, we first need to represent the text as numerical vectors. One common way is to use the term frequency or TF-IDF (Term Frequency-Inverse Document Frequency).&lt;/p&gt;

&lt;p&gt;Let's consider a simple user query looking for exercises targeting the chest. The original query is &lt;strong&gt;“recommend chest exercises”&lt;/strong&gt;. From the query, we can extract the word: &lt;strong&gt;chest&lt;/strong&gt;. We want to compare this to existing chest workouts in our database for similarity.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User query: "Chest"&lt;/li&gt;
&lt;li&gt;Database entry: "Chest press"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can represent these exercises as vectors based on their features. For simplicity, let’s use "Chest," and "press”, as the key features:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Words&lt;/th&gt;
&lt;th&gt;Chest&lt;/th&gt;
&lt;th&gt;Press&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chest&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chest press&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The resulting vectors are:&lt;br&gt;
Vector A (Chest): [1, 0]&lt;br&gt;
Vector B (Chest press): [1, 1]&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ke8iuhdqwgg3d2vs7tx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ke8iuhdqwgg3d2vs7tx.png" alt="graph showing the angle between 2 vectors" width="283" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The angle between the two vectors determines the cosine similarity. In this case, the angle is 45°, and the cosine of 45° is approximately &lt;strong&gt;0.707.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Cosine similarity ignores the frequency of the words
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Words&lt;/th&gt;
&lt;th&gt;Chest&lt;/th&gt;
&lt;th&gt;Press&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chest chest chest&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chest press&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqn33o4nzcpxx5aqjybt0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqn33o4nzcpxx5aqjybt0.png" alt="graph showing the angle between 2 vectors" width="396" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The point of the &lt;strong&gt;Chest chest chest&lt;/strong&gt; on the graph will be further out on the X axis but the angle will remain the same and thus the same cosine similarity. Cosine similarity is determined by the angle between the lines and ignores the magnitude of the vectors.&lt;/p&gt;
&lt;h3&gt;
  
  
  Cosine similarity when the words are the same
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Words&lt;/th&gt;
&lt;th&gt;Chest&lt;/th&gt;
&lt;th&gt;Press&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chest press&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chest press&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffdohahmgas7dj1lrpvi3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffdohahmgas7dj1lrpvi3.png" alt="graph showing the angle between 2 vectors" width="253" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since the 2 words are the same the angle between the lines will be 0 and the cosine similarity will be Cos 0 = 1. &lt;/p&gt;

&lt;p&gt;While these examples work well in a 2-dimensional space, real-world scenarios often involve higher-dimensional data (e.g., 5 or more features). In such cases, we use the cosine similarity formula:&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;Cosine Similarity=X⋅Y∣X∣∣Y∣\text{Cosine Similarity} = \frac{\mathbf{X} \cdot \mathbf{Y}}{|\mathbf{X}| |\mathbf{Y}|}

&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt;Cosine Similarity&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;∣&lt;/span&gt;&lt;span class="mord mathbf"&gt;X&lt;/span&gt;&lt;span class="mord"&gt;∣∣&lt;/span&gt;&lt;span class="mord mathbf"&gt;Y&lt;/span&gt;&lt;span class="mord"&gt;∣&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathbf"&gt;X&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathbf"&gt;Y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;x → The embedding vector of an item you liked in the past.&lt;br&gt;
y → The embedding vector of another item (e.g., a recommendation candidate).&lt;br&gt;
x · y (dot product) → Measures how similar the two vectors are in direction.&lt;br&gt;
||x|| * ||y|| (product of magnitudes) → Normalizes the similarity score so it’s between -1 and 1.&lt;/p&gt;
&lt;h2&gt;
  
  
  How content-based filtering works in our fitness app
&lt;/h2&gt;

&lt;p&gt;Let’s break it down step by step:&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Define item features
&lt;/h3&gt;

&lt;p&gt;The first step in the process is determining what the item’s features are. In our dataset, our item features are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bodypart:&lt;/strong&gt; chest, legs, abs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level:&lt;/strong&gt; beginner, intermediate, expert.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Equipment:&lt;/strong&gt; dumbbell, barbell, bodyweight.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
Dumbbell Bench Press → Features: BodyPart=chest, Level=beginner, Equipment=dumbbell.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Create a user profile
&lt;/h3&gt;

&lt;p&gt;When the user types a query like “beginner chest exercises with dumbbells”, the system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Extracts keywords:&lt;/strong&gt; beginner, chest, dumbbells.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expands synonyms:&lt;/strong&gt; Maps chest to ["chest", "pectoral"] and legs to [“quads”, “hamstrings”]&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encodes preferences:&lt;/strong&gt; Converts these terms into a numerical vector (a list of numbers representing the user’s preferences). User Vector: (0.6, 0.3, 0.1, 1, 0, 0] {chest, beginner, dumbbell}&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  3. Choose a similarity metric
&lt;/h3&gt;

&lt;p&gt;As discussed previously we use cosine similarity to compare the user’s preferences to exercises.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;User vector:&lt;/strong&gt; [0.6, 0.3, 0.1, 1, 0, 0] {chest, beginner, dumbbell}&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exercise vector:&lt;/strong&gt; [0.5, 0.3, 0.2, 1, 0, 0] {chest, beginner, dumbbell}&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Similarity Score:&lt;/strong&gt; 0.98 {nearly identical!}&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  4. Score and rank exercises
&lt;/h3&gt;

&lt;p&gt;The system calculates the similarity between the user’s vector and every exercise’s vector, then ranks them from most to least similar.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Exercise&lt;/th&gt;
&lt;th&gt;BodyPart&lt;/th&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;Equipment&lt;/th&gt;
&lt;th&gt;Similarity Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Dumbbell Bench Press&lt;/td&gt;
&lt;td&gt;chest&lt;/td&gt;
&lt;td&gt;beginner&lt;/td&gt;
&lt;td&gt;dumbell&lt;/td&gt;
&lt;td&gt;0.98&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Push-ups&lt;/td&gt;
&lt;td&gt;chest&lt;/td&gt;
&lt;td&gt;beginner&lt;/td&gt;
&lt;td&gt;bodyweight&lt;/td&gt;
&lt;td&gt;0.85&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Barbell Squats&lt;/td&gt;
&lt;td&gt;legs&lt;/td&gt;
&lt;td&gt;intermediate&lt;/td&gt;
&lt;td&gt;barbell&lt;/td&gt;
&lt;td&gt;0.12&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The user gets the top recommendations: Dumbbell Bench Press and Push-ups.&lt;/p&gt;
&lt;h2&gt;
  
  
  The dataset
&lt;/h2&gt;

&lt;p&gt;We’ll be using the &lt;a href="https://www.kaggle.com/datasets/niharika41298/gym-exercise-data" rel="noopener noreferrer"&gt;Gym Exercise Dataset&lt;/a&gt; from Kaggle. This dataset contains the following columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Title:&lt;/strong&gt; The name of the exercise (e.g., Barbell Squats).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BodyPart:&lt;/strong&gt; The muscle group targeted (e.g., legs, chest).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Equipment:&lt;/strong&gt; The equipment required (e.g., dumbbell, barbell).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level:&lt;/strong&gt; The difficulty level (e.g., beginner, intermediate).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ExerciseType:&lt;/strong&gt; The type of exercise (e.g., strength, cardio).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Building the code
&lt;/h2&gt;

&lt;p&gt;Prerequisites&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;Vscode&lt;/a&gt; or any code editor of your choice&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dotnet.microsoft.com/en-us/download" rel="noopener noreferrer"&gt;Download .NET &lt;/a&gt;(I'm using .NET 8)&lt;/li&gt;
&lt;li&gt;Full GitHub code &lt;a href="https://github.com/GbengaElebs/WorkoutRecommender" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Step 1: Setting up the project
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a .NET console app:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;dotnet&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;console&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="n"&gt;WorkoutRecommender&lt;/span&gt;
&lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="n"&gt;WorkoutRecommender&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install the ML package&lt;/strong&gt; 
&lt;code&gt;dotnet add package Microsoft.ML&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Download the dataset:&lt;/strong&gt; Place the &lt;strong&gt;gym_exercise_data.csv&lt;/strong&gt; file in a Data folder within your project.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Step 2: Loading and preprocessing the data
&lt;/h3&gt;

&lt;p&gt;The first step is to load the dataset and preprocess it for machine learning.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a class to represent the exercises:&lt;/strong&gt; I added a processed exercises class which contains an attribute for the body part synonyms.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.ML.Data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Exercise&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;LoadColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;LoadColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Desc&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;LoadColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;LoadColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;BodyPart&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;LoadColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Equipment&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;LoadColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Level&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="c1"&gt;// Used for synonym mapping&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProcessedExercise&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Exercise&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;BodyPartSynonyms&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExerciseVector&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;VectorType&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// Indicates this is a numerical vector&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;Features&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a body part synonym:&lt;/strong&gt; Add a recommendation class file and add a dictionary. Since users might enter terms like “legs” instead of “glutes”, we’ll create a synonym dictionary to map related terms.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;Dictionary&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;BodyPartSynonyms&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"chest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"chest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"pectoral"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"legs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"legs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"glutes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"quads"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"hamstrings"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"abs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"abs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"core"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"abdominals"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"arms"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"arms"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"biceps"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"triceps"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;};&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Load the CSV file:&lt;/strong&gt; Use ML.NET’s LoadFromTextFile to read the dataset and convert it to a list of Exercise objects. This method loads the list of exercises and converts it to the processed exercises object containing the body part synonyms.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Method to load exercises from CSV&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ProcessedExercise&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;LoadExercises&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="c1"&gt;// Step 1: Load raw CSV data using ML.NET&lt;/span&gt;
       &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;mlContext&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MLContext&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
       &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dataPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetCurrentDirectory&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"Data"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"megaGymDataset.csv"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dataView&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mlContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LoadFromTextFile&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Exercise&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
           &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dataPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;separatorChar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sc"&gt;','&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;hasHeader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;// If your CSV has headers&lt;/span&gt;
       &lt;span class="p"&gt;);&lt;/span&gt;

       &lt;span class="c1"&gt;// Convert to list of Exercise objects&lt;/span&gt;
       &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;exercises&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mlContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Exercise&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;dataView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reuseRowObject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

       &lt;span class="c1"&gt;// Convert to ProcessedExercise and add synonyms&lt;/span&gt;
       &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;processedExercises&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exercises&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ProcessedExercise&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;Desc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Desc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;BodyPart&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BodyPart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;Equipment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equipment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;Level&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;BodyPartSynonyms&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;GetSynonymsForBodyPart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BodyPart&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// Join synonyms into a single string&lt;/span&gt;
       &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;processedExercises&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;


   &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetSynonymsForBodyPart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;bodyPart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="c1"&gt;// Normalize body part to lowercase&lt;/span&gt;
       &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;normalizedBodyPart&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bodyPart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;ToLower&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


       &lt;span class="c1"&gt;// Find the synonym group that contains this body part&lt;/span&gt;
       &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;matchingGroup&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BodyPartSynonyms&lt;/span&gt;
           &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kvp&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;kvp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;normalizedBodyPart&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;matchingGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;normalizedBodyPart&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 3: Building the ML pipeline
&lt;/h3&gt;

&lt;p&gt;The ML pipeline is the heart of our application. It transforms raw data into a format the computer can understand. Here’s how we build the ML pipeline in the Program.cs file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mlContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Transforms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FeaturizeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="n"&gt;outputColumnName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"BodyPartFeatures"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;inputColumnName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ProcessedExercise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BodyPartSynonyms&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mlContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Transforms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Categorical&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OneHotEncoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="n"&gt;outputColumnName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"LevelFeatures"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;inputColumnName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exercise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mlContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Transforms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Categorical&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OneHotEncoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="n"&gt;outputColumnName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"EquipmentFeatures"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;inputColumnName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exercise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equipment&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mlContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Transforms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Concatenate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="n"&gt;outputColumnName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Features"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s"&gt;"BodyPartFeatures"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s"&gt;"LevelFeatures"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s"&gt;"EquipmentFeatures"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;FeaturizeText:&lt;/strong&gt; Converts body part synonyms into numerical vectors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OneHotEncoding:&lt;/strong&gt; Converts categorical features like Level and Equipment into binary vectors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concatenate:&lt;/strong&gt; Combines all features into a single vector for each exercise.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 4: Preprocessing and prediction engine
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;preprocessedData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataView&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;predictionEngine&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mlContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreatePredictionEngine&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ProcessedExercise&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ExerciseVector&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;preprocessedData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fit:&lt;/strong&gt; Trains the pipeline on the exercise data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;predictionEngine:&lt;/strong&gt; Generates feature vectors for new user query inputs.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 5: Handling user queries
&lt;/h3&gt;

&lt;p&gt;To make the system user-friendly, we’ll parse natural language queries and extract keywords.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Get user input&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enter your query:"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadLine&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;userQuery&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;helper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ParseInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// "Recommend leg workouts for intermediates"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1.&lt;strong&gt;ParseInput:&lt;/strong&gt; Extracts key components (e.g., BodyParts, Level, Equipment) from the user’s query using Regex.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;UserQuery&lt;/span&gt; &lt;span class="nf"&gt;ParseInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;userQuery&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;UserQuery&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

       &lt;span class="c1"&gt;// Case-insensitive regex patterns&lt;/span&gt;
       &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;bodyPartPattern&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"(?i)\b(chest|legs|abs|arms|core|glutes|back|traps|neck|shoulders)\b"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;levelPattern&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"(?i)\b(beginner|intermediate|expert|advanced)\b"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;equipmentPattern&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"(?i)\b(dumbbell|barbell|kettlebells|bodyweight|bands|cable|machine|body)\b"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="c1"&gt;// Extract body parts&lt;/span&gt;
       &lt;span class="n"&gt;userQuery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BodyParts&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Regex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bodyPartPattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
           &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToLower&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
           &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

       &lt;span class="c1"&gt;// Extract fitness level (default to "beginner" if unspecified)&lt;/span&gt;
       &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;levelMatch&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Regex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;levelPattern&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="n"&gt;userQuery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Level&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;levelMatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;levelMatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToLower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"beginner"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

       &lt;span class="c1"&gt;// Extract equipment (optional)&lt;/span&gt;
       &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;equipmentMatch&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Regex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;equipmentPattern&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="n"&gt;userQuery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equipment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;equipmentMatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;equipmentMatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToLower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;userQuery&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Expand Synonyms:&lt;/strong&gt; Map user-friendly terms like "legs" to dataset-specific terms like "glutes".
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;ExpandQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;userBodyParts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;expandedTerms&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
       &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;userBodyParts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;normalizedTerm&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;ToLower&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
           &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BodyPartSynonyms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ContainsKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;normalizedTerm&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="n"&gt;expandedTerms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BodyPartSynonyms&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;normalizedTerm&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
           &lt;span class="p"&gt;}&lt;/span&gt;
           &lt;span class="k"&gt;else&lt;/span&gt;
           &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;matchingGroup&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BodyPartSynonyms&lt;/span&gt;
                   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kvp&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;kvp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;normalizedTerm&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
               &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matchingGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="n"&gt;expandedTerms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matchingGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
               &lt;span class="p"&gt;}&lt;/span&gt;
               &lt;span class="k"&gt;else&lt;/span&gt;
               &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="n"&gt;expandedTerms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;normalizedTerm&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
               &lt;span class="p"&gt;}&lt;/span&gt;
           &lt;span class="p"&gt;}&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expandedTerms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Distinct&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// Join into a single string&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Generating recommendations
&lt;/h3&gt;

&lt;p&gt;Finally, we’ll compare the user’s input to the dataset and recommend exercises.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;recommendations&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exercises&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;Exercise&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;Similarity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;helper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ComputeSimilarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userVector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;predictionEngine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Features&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;})&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OrderByDescending&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Similarity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;ComputeSimilarity:&lt;/strong&gt; Calculates cosine similarity between the user’s vector and each exercise’s vector.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OrderByDescending:&lt;/strong&gt; Ranks exercises by similarity score.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Take(5):&lt;/strong&gt; Returns the top 5 recommendations.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Full code on GitHub&lt;a href="https://github.com/GbengaElebs/WorkoutRecommender" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Output
&lt;/h3&gt;

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

&lt;p&gt;In this article, we built a personalized workout recommendation engine by leveraging ML.NET., We created a system that understands user queries like "leg workouts for intermediates" and ranks exercises based on cosine similarity. &lt;/p&gt;

&lt;p&gt;If you have questions please leave them in the comment section below. I would be happy to discuss further.&lt;/p&gt;

&lt;p&gt;Also, please share if you found it helpful.&lt;/p&gt;

&lt;p&gt;Follow me on Dev.to, &lt;a href="https://medium.com/@danielelebs" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; or &lt;a href="https://instagram.com/elebs_d" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; for more AI, .NET, and fitness-related content.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>ai</category>
      <category>machinelearning</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Introduction to algorithms: Big O notation, time complexity</title>
      <dc:creator>Daniel Elegberun</dc:creator>
      <pubDate>Tue, 27 Sep 2022 17:21:04 +0000</pubDate>
      <link>https://forem.com/gbengelebs/introduction-to-algorithms-big-o-notation-time-complexity-5do8</link>
      <guid>https://forem.com/gbengelebs/introduction-to-algorithms-big-o-notation-time-complexity-5do8</guid>
      <description>&lt;p&gt;We live in a world of algorithms. From the posts we see on Twitter to the people we swipe on Tinder. Algorithms surround us, controlling machines, computers, and robots, but what exactly are they, how do we analyze them, and why do we need them to get a job?&lt;/p&gt;

&lt;p&gt;This article discusses algorithms, how to represent them using asymptotic notations like Big O, and how to analyze their time complexities.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an algorithm?
&lt;/h2&gt;

&lt;p&gt;An algorithm is a step-by-step procedure that details how to solve a problem. A more formal definition is "an unambiguous specification of how to solve a class of problems." Going by these definitions, the recipe for baking a cake, the method for solving long division problems, and the process of planning your route for a trip are all algorithms.&lt;/p&gt;

&lt;p&gt;Algorithmic programming is all about writing a set of rules that instruct the computer on how to perform a task. Algorithms are written using a particular syntax, depending on the programming language being used.&lt;/p&gt;

&lt;p&gt;Suppose we have this array of numbers in ascending order, and we want to search if this array contains the number 9. &lt;/p&gt;

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

&lt;p&gt;There are several ways we can tackle this problem. The first that comes to mind is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Approach 1: Linear Search&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start from the beginning and iterate through the entire array&lt;/li&gt;
&lt;li&gt;Compare the value at the current index of the array to the target value. &lt;/li&gt;
&lt;li&gt;Repeat the process until the target value is found&lt;/li&gt;
&lt;li&gt;Return the target value&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Even though this approach has solved our problem, we must consider if it is the most optimal solution. Let's consider another method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Approach 2: Binary Search&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;a. Find the midpoint of the array and split it into two halves.&lt;/p&gt;

&lt;p&gt;b. Compare the value at the midpoint of the array to the target value.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkp344deqzgqkkhs093gk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkp344deqzgqkkhs093gk.png" alt="approach2array comparison" width="706" height="120"&gt;&lt;/a&gt;Input array halved&lt;/p&gt;

&lt;p&gt;c. Since the target value is greater than our midpoint value, the value we are searching for must be on the right side of the array division. So, we can discard the left side of the array.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgn53ijvonybd8nk1rapp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgn53ijvonybd8nk1rapp.png" alt="approach2array comparison step2" width="743" height="118"&gt;&lt;/a&gt;Array halved &lt;/p&gt;

&lt;p&gt;d. We repeat the process of splitting the right side into two halves and comparing the value at the midpoint to our target value until the target value is found&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwheq1dftjhlx4hreaaby.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwheq1dftjhlx4hreaaby.png" alt="approach2array comparison step3" width="800" height="129"&gt;&lt;/a&gt;Target found &lt;/p&gt;

&lt;p&gt;e. Return the target value&lt;/p&gt;

&lt;p&gt;In this algorithm, we reduce the search area of our array by half each time we iterate through it. Since we are searching only half of the array in each iteration, we can find the target element faster. &lt;/p&gt;

&lt;p&gt;If we compare the two approaches, while it took nine comparisons to guess the target element in the first approach, the second only took 3. This approach to solving problems by dividing them into smaller subsets is called a divide and conquer approach. And the algorithm used in approach B is used in many search engines and databases today and is referred to as binary search.  &lt;/p&gt;

&lt;p&gt;We cannot use the same algorithm for every problem; knowing when to use a particular algorithmic approach is essential. For example, even though the binary search was more efficient for solving our example above, it can only work if the input array is sorted. &lt;/p&gt;

&lt;p&gt;How do we solve this same problem if we are given an array of unsorted numbers and asked to find a target element? If we use a binary search, we will have to sort the array first before performing the binary search, which will be less efficient than the first linear search approach. Therefore, we must constantly analyze our algorithmic approach to ensure we are considering the optimal solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do we analyze algorithms?
&lt;/h2&gt;

&lt;p&gt;We analyze algorithms to evaluate their performance and suitability for the problem we want to solve. When we design algorithms, we are not just interested in the algorithm's correctness but also its efficiency and scalability as the input size grows. &lt;/p&gt;

&lt;p&gt;In the previous example, even though the linear search approach was slower, the speed difference was negligible because the input size was small. However, think about this problem from the perspective of companies like Facebook and Google, with billions of users. Imagine how long it will take to search for data in a dataset containing billions of users using the linear search approach vs. the binary search approach. We can see how the binary search approach is much more efficient in that case. &lt;/p&gt;

&lt;h2&gt;
  
  
  How to analyze algorithms
&lt;/h2&gt;

&lt;p&gt;We analyze an algorithm's complexity in two ways, time and space.&lt;/p&gt;

&lt;p&gt;Time complexity is crucial because we need our programs to run as quickly as possible to deliver the results. Space complexity is essential because machines have only a limited amount of memory to spare.&lt;/p&gt;

&lt;p&gt;A good algorithm takes less time in execution and saves space during the process. Ideally, we want to optimize for both time and space, but sometimes that may not be possible, and we can settle for a middle ground. The method we use in analyzing algorithms must:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a. Be independent of the machine and its configuration on which the algorithm is running:&lt;/strong&gt; This is important because we do not know the actual specifications of the computer that our algorithm will run on, so we cannot factor in hardware or CPU specs when analyzing algorithms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;b. Show a direct correlation between the algorithm and the input size:&lt;/strong&gt; How does the algorithm perform as our input size approach infinity (an asymptote)?&lt;/p&gt;

&lt;p&gt;When analyzing the complexity of any algorithm in terms of time and space, we can never provide an exact number to define the time required and the space needed by the algorithm. So instead, we express them using standard notations, known as Asymptotic Notations. &lt;/p&gt;

&lt;h2&gt;
  
  
  What are asymptotic notations?
&lt;/h2&gt;

&lt;p&gt;Asymptotic notations are the mathematical notations used to describe the running time of an algorithm when the input tends towards a particular or infinite value. &lt;/p&gt;

&lt;p&gt;The complexity of algorithms can be represented using three asymptotic notations: Big O, Big Theta (Θ), and Big Omega (Ω).&lt;/p&gt;

&lt;h3&gt;
  
  
  Big O notation
&lt;/h3&gt;

&lt;p&gt;Big O notation represents the upper bound running time complexity of an algorithm and "can" be used to describe the worst-case scenario of an algorithm. A common misconception about Big O notation is that it represents the worst-case scenario of an algorithm. This is somewhat incorrect as it doesn't mean the worst case, but "can" be used to describe the worst case. We can also use it to represent the best and average cases. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgz92pse4lnoj1gfuveip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgz92pse4lnoj1gfuveip.png" alt="BigO notation" width="405" height="284"&gt;&lt;/a&gt;Big O Graph&lt;/p&gt;

&lt;p&gt;Look at it this way, Big O notation answers the question, "In the &lt;strong&gt;worst&lt;/strong&gt; case, what's the &lt;strong&gt;longest&lt;/strong&gt; time this algorithm will take to run? &lt;/p&gt;

&lt;p&gt;It can also answer the question. "In the &lt;strong&gt;best&lt;/strong&gt; case, what's the &lt;strong&gt;longest&lt;/strong&gt; time our algorithm will take to run." And for the average case, "In the &lt;strong&gt;average&lt;/strong&gt; case, what's the &lt;strong&gt;longest&lt;/strong&gt; time our algorithm will take to run." We can see the common factor here is the &lt;strong&gt;longest time(upper bound)&lt;/strong&gt; our algorithm will take to run. Best, worst, and average are scenarios, and we are upper bounding those scenarios using Big O.&lt;/p&gt;

&lt;p&gt;Because we're always interested in the longest running time of the worst-case scenario, we mainly represent our algorithms using Big O.&lt;/p&gt;

&lt;h3&gt;
  
  
  Big Omega (Ω)
&lt;/h3&gt;

&lt;p&gt;Big O notation represents the lower-bound running time complexity of an algorithm and "can" be used to describe the best-case scenario of an algorithm. Similar to Big O, Big Ω can be used to represent the best, average, and worst-case scenarios. Big Omega (Ω) answers the questions. "In the &lt;strong&gt;best/worst/average&lt;/strong&gt; case, what's the &lt;strong&gt;fastest&lt;/strong&gt; time this algorithm will take to run? We can use Big Ω to lower-bound our best, worst, and average running time scenarios.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadwmpco8bgwwyf6ggdbe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadwmpco8bgwwyf6ggdbe.png" alt="Big Omega" width="392" height="280"&gt;&lt;/a&gt;Big Ω Graph&lt;/p&gt;

&lt;h3&gt;
  
  
  Big Theta (Θ)
&lt;/h3&gt;

&lt;p&gt;Big Theta (Θ) represents the upper and the lower bound of the running time complexity of an algorithm. Like the first two, this "can" represent the best, average, and worst cases. For example, "In the &lt;strong&gt;average/best/worst case&lt;/strong&gt; scenario, what's the &lt;strong&gt;average&lt;/strong&gt; time this algorithm will take to run"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftku1vqk1uc5dgf7ntw98.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftku1vqk1uc5dgf7ntw98.png" alt="Big Theta" width="397" height="280"&gt;&lt;/a&gt;Big Θ Graph&lt;/p&gt;

&lt;p&gt;As stated earlier, we mainly use Big O notation because we're always interested in measuring the longest time an algorithm runs in the worst-case scenario. For the rest of the series, we will measure our algorithms' complexity in Big O. &lt;/p&gt;

&lt;h2&gt;
  
  
  How to find the time complexity of an algorithm
&lt;/h2&gt;

&lt;p&gt;We typically consult Big-O because we must always plan for the worst case. In our linear search example, the best case is that the number we are searching for is the first in the list, and the worst case is that the number we are searching for is at the end of the array. So, for an array of size 10, we iterate 10 times, and for size 1000, we iterate 1000 times. We can say that the running time of our linear search algorithm grows as the input increases. We represent this as O(n). &lt;/p&gt;

&lt;p&gt;In the binary search approach, the best case complexity will be when the target element is at the center of the list, and the worst case will be when the target element is at either extremity of the list. However, since we half the array at every iteration, we are reducing the size of the problem by half. 𝑛,𝑛/2,𝑛/4,𝑛/8&lt;/p&gt;

&lt;p&gt;We call this type of growth logarithmic (O(log N)). O(log n) means that as the input increases exponentially, operation time increases linearly. So if it takes binary search 1 second to compute 10 elements, it will take 2 seconds to compute 100 elements, 3 seconds to compute 1000 elements, and so on. &lt;/p&gt;

&lt;p&gt;The common algorithmic runtimes from slowest to fastest are:&lt;/p&gt;

&lt;p&gt;O(1) &amp;lt; O(log n) &amp;lt; O(n) &amp;lt; O(n log n) &amp;lt; O( n2) &amp;lt; O(n2 logn) &amp;lt; O(n3) &amp;lt; O(2n) &amp;lt; O(n!)&lt;/p&gt;

&lt;p&gt;Plotting them on a graph of operation time vs. input size, we can see that the rate of growth of the running times of the best algorithms is much slower than the input size growth.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd5duzw5dvwdxl04xg4q8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd5duzw5dvwdxl04xg4q8.png" alt="big o comparison chart" width="800" height="450"&gt;&lt;/a&gt;Big O comparison chart &lt;a href="https://hackr.io/blog/big-o-notation-cheat-sheet" rel="noopener noreferrer"&gt;Hackr&lt;/a&gt; &lt;br&gt;
Let's look at some Big O notation examples.&lt;/p&gt;
&lt;h2&gt;
  
  
  Big O Notation examples
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;O(1)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Print the first element in an array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[apple, orange, cherry, mango, grapes]

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

&lt;/div&gt;



&lt;p&gt;This would always be constant time irrespective of whether the input is 100 or 10,000&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O(n)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Iterate through an array and print all items.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[apple, orange, cherry, mango, grapes] 

apple
orange
cherry
mango
grapes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The time complexity of this algorithm will always depend on the input size.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O(log n)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using binary search to find a given element in an array. Like in our example above&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O(n²)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Print all possible combinations of elements in an array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[a,b,c,d,e] =&amp;gt; [abcde, bacde, cabde, dabce, eabcd]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time complexity of this algorithm grows exponentially as the input size grows. This is because, for each item in the array, you need to iterate through the rest of the array. The number of operations your program has to do is the number of inputs (or n) times itself (n squared). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;General tips for asymptotic analysis:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When an entire array gets iterated over, it is most likely in O(n) time.&lt;/li&gt;
&lt;li&gt;When you see an algorithm where the number of elements in the problem space gets halved after each iteration, it will probably be in O(logn) runtime.&lt;/li&gt;
&lt;li&gt;Whenever you have a  nested loop, the problem is most likely in quadratic time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Improve your algorithmic thinking with practice
&lt;/h2&gt;

&lt;p&gt;Algorithms are behind most of the impressive applications we use every day. Learning common algorithms are helpful, but what's even better is improving our algorithmic thinking. Algorithmic thinking allows us to break down problems, analyze them and implement solutions. Like all skills, algorithmic thinking is learnable, and with enough practice, we can train our brains to become better at it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Helpful links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=8hly31xKli0&amp;amp;t=9259s" rel="noopener noreferrer"&gt;Algorithms and Data Structures Tutorial - Full Course for Beginners&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=rL8X2mlNHPM" rel="noopener noreferrer"&gt;Intro to Algorithms: Crash Course Computer Science #13&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=HtSuA80QTyo" rel="noopener noreferrer"&gt;Lecture 1: Algorithmic Thinking, Peak Finding&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>algorithms</category>
      <category>programming</category>
    </item>
    <item>
      <title>Introduction to data structures</title>
      <dc:creator>Daniel Elegberun</dc:creator>
      <pubDate>Tue, 20 Sep 2022 16:38:16 +0000</pubDate>
      <link>https://forem.com/gbengelebs/introduction-to-data-structures-ok3</link>
      <guid>https://forem.com/gbengelebs/introduction-to-data-structures-ok3</guid>
      <description>&lt;p&gt;Cover Photo by &lt;a href="https://unsplash.com/@alvaropinot?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Alvaro Pinot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Data by itself is not very valuable; what gives data value is when it is organized in a way that can help us solve problems. We see this every day in our lives. For example, the words in the dictionary are organized alphabetically to help us search faster. Likewise, products on shopping sites are arranged by price and category to navigate products quickly. Similarly, computers need to organize data to analyze and process it efficiently. The format used to manage data in a computer's memory is called a data structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a data structure?
&lt;/h2&gt;

&lt;p&gt;A data structure is a format for storing and organizing data in a way that can be accessed and modified efficiently in a computer's memory. Knowing how data is structured in the computer's memory helps design and develop efficient software systems that scale effectively. It also helps in creating algorithms that help us solve complex problems. For instance, GPS systems and Google Maps use a Graph data structure to find the shortest path between two distances. &lt;/p&gt;

&lt;h3&gt;
  
  
  Classification of data structures
&lt;/h3&gt;

&lt;p&gt;There are two general types of data structures: Linear and non-linear.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linear data structures:&lt;/strong&gt; These are data structures where all elements are arranged linearly/sequentially. Every element in the structure is attached to its previous and next parts. Examples of linear data structures are arrays,linked lists, stacks and queues.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhv921ko7m3xbfsgztyei.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhv921ko7m3xbfsgztyei.jpg" alt="Linear" width="300" height="180"&gt;&lt;/a&gt;&lt;br&gt;Linear data structure
 &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Non-linear data structure:&lt;/strong&gt; These are data structures where the elements are not arranged in a linear format. Mainly, data elements are arranged in hierarchal order without forming a linear system. Examples of non-linear data structures are trees, heaps, tries, graphs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkguehtngk49bnx52n6xu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkguehtngk49bnx52n6xu.png" alt="Non-linear" width="597" height="267"&gt;&lt;/a&gt;&lt;br&gt;Non-linear data structure
 &lt;/p&gt;

&lt;p&gt;When we study data structures, we usually define them in 2 ways.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mathematical/logical models:&lt;/strong&gt; Here, we look at the data structures from a high level. We only define the logic or the behavior of the data types but not any implementations. This representation is referred to as Abstract Data Types(ADT). ADTs do not specify how the data structure must is implemented or laid out in memory but provides a minimal expected interface and set of behaviors. For example, we define a car as an ADT by defining the properties a car should have.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Four wheels&lt;/li&gt;
&lt;li&gt;Steering&lt;/li&gt;
&lt;li&gt;Brake&lt;/li&gt;
&lt;li&gt;Seats&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Similarly, a List ADT contains methods to &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get elements&lt;/li&gt;
&lt;li&gt;Insert elements &lt;/li&gt;
&lt;li&gt;Modify elements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Concrete models:&lt;/strong&gt; This is a direct implementation of an ADT. In the example above, where we defined a Car ADT. The concrete implementation could be a Tesla, Audi, or Ford. The concrete implementation of a List ADT can be represented as an Array or a Linked List because these contain properties that satisfy the condition of the List ADT.&lt;/p&gt;

&lt;p&gt;Unless you have some specific requirements, you generally don't create these concrete implementations of basic data structures yourself. Instead, you'd use one provided by the programming language's standard library. These data structures tend to be well-tested and complete, so using them saves you time compared to rolling your own. However, knowing how they operate under the hood helps you know when to use what.&lt;/p&gt;

&lt;p&gt;Let's now take a look at a few of the more common data structures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of common data structures
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Arrays
&lt;/h3&gt;

&lt;p&gt;An array is a linear data structure that holds an ordered collection of elements stored at contiguous memory locations (next to each other). Example use cases of arrays are to store collections of elements of the same type, like a collection of integers or the letters of an alphabet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmjmwfomjkqhji9rckkop.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmjmwfomjkqhji9rckkop.png" alt="Array data structure" width="429" height="195"&gt;&lt;/a&gt;&lt;br&gt;Array data structure (Source: &lt;a href="https://www.geeksforgeeks.org/array-data-structure/" rel="noopener noreferrer"&gt;GeeksforGeeks&lt;/a&gt;)
 &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Applications of Arrays&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Useful when storing elements of the same data type. A collection of countries, alphabets, products, etc. &lt;/li&gt;
&lt;li&gt;Serves as a fundamental building block for implementing other data structures: Stacks, Queues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Advantages of arrays&lt;/strong&gt;&lt;br&gt;
They provide fast access to any element in the array. Because elements are stored next to each other in memory, it's faster for the computer to access each element randomly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages of arrays&lt;/strong&gt;&lt;br&gt;
Arrays are declared with a fixed size and cannot grow dynamically. &lt;/p&gt;

&lt;h3&gt;
  
  
  Linked List
&lt;/h3&gt;

&lt;p&gt;Similar to arrays, Linked Lists are linear data structures that hold a collection of elements. However, unlike arrays, they do not occupy contiguous blocks of memory. Instead, each element (called a node) in a Linked List consists of value/data and a pointer/link to the address of the next node in the linked List.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faco2s204fwykrf4181cw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faco2s204fwykrf4181cw.png" alt="Linked List" width="771" height="307"&gt;&lt;/a&gt;&lt;br&gt;Linked List data structure (Source: &lt;a href="https://www.javatpoint.com/singly-linked-list-vs-doubly-linked-list" rel="noopener noreferrer"&gt;Javatpoint&lt;/a&gt;) 
  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Applications of Linked Lists&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Image viewer software uses a linked list to view the previous and the next images&lt;/li&gt;
&lt;li&gt;Web pages can be accessed using the previous and the next button in a browser&lt;/li&gt;
&lt;li&gt;We can use linked Lists to implement other data structures: Stacks, Queues, Graphs, and Trees&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Advantages of Linked Lists&lt;/strong&gt;&lt;br&gt;
Unlike Arrays, Linked Lists can grow dynamically because the elements are not stored in contiguous memory blocks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages of Linked Lists&lt;/strong&gt;&lt;br&gt;
Linked List uses extra memory to store the links to the next node. Additionally, because the nodes are not stored next to each other(contiguously), it is not as easy to access elements randomly, like arrays.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stacks
&lt;/h3&gt;

&lt;p&gt;Stacks are linear data structures used for storing a collection of elements with the constraint that the last element must be the first out(LIFO). Think of an analogy of placing plates above each other. Stacks can be implemented using arrays or Linked List as long as it meets the condition that the last element in is the first out.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcy2q18i4m7mfilli5c9z.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcy2q18i4m7mfilli5c9z.jpeg" alt="Stack data structure" width="500" height="345"&gt;&lt;/a&gt;&lt;br&gt;Stack data structure (Source: &lt;a href="https://www.tutorialspoint.com/data_structures_algorithms/stack_algorithm.htm" rel="noopener noreferrer"&gt;Tutorialspoint&lt;/a&gt;)
 &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Applications of Stacks&lt;/strong&gt;&lt;br&gt;
Suitable for applications where the most recently added element appears first (LIFO). Website history, call history, Undo/Redo button/operation in word processors, recursion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages of Stacks&lt;/strong&gt;&lt;br&gt;
Useful in managing data problems that meet the requirements of the LIFO format.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages of Stacks&lt;/strong&gt;&lt;br&gt;
Stacks implemented using arrays have a fixed size. An attempt to add an element to a full stack results in the famous "stack overflow" error.&lt;/p&gt;

&lt;h3&gt;
  
  
  Queues
&lt;/h3&gt;

&lt;p&gt;Queues are linear data structures used for storing a collection of elements with the constraint that the first element added to the queue must be the first one out(FIFO). Just like a queue in the real world. In software systems, queues are very effective for managing systems that involve scheduling. For example, when you want to execute a series of tasks sequentially. Like stacks, queues can also be implemented using arrays and LinkedList.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flfmqt1g1doel26i6dg2l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flfmqt1g1doel26i6dg2l.png" alt="Queue data structure" width="800" height="283"&gt;&lt;/a&gt;&lt;br&gt;Queue data structure (Source: &lt;a href="https://www.geeksforgeeks.org/queue-data-structure/" rel="noopener noreferrer"&gt;GeeksforGeeks&lt;/a&gt;)
 &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Applications of Queues&lt;/strong&gt;&lt;br&gt;
Suitable for applications following the FIFO principle. For example, job scheduling, escalators, networked printers, internet requests, and processes. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages of Queues&lt;/strong&gt;&lt;br&gt;
Useful for services that follow the FIFO principle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages of Queues&lt;/strong&gt;&lt;br&gt;
Like stacks, queues implemented using arrays have a fixed size.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trees
&lt;/h3&gt;

&lt;p&gt;A tree is a non-linear data structure that stores a collection of elements called nodes linked together to simulate a hierarchy. Trees usually have a root or parent node referencing one or more child nodes. Mainly, tree data structures represent hierarchical data. An example is the folder and file system on your computer. A folder (as a parent node) can contain files and sub-folders, which are its children. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fta2hipcly0psv6wsmlpo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fta2hipcly0psv6wsmlpo.png" alt="Trees Data structure" width="800" height="346"&gt;&lt;/a&gt;&lt;br&gt;Trees data structure (Source: &lt;a href="https://www.geeksforgeeks.org/introduction-to-tree-data-structure-and-algorithm-tutorials/" rel="noopener noreferrer"&gt;GeeksforGeeks&lt;/a&gt;)&lt;br&gt;

 &lt;/p&gt;

&lt;p&gt;The most common type of tree is the one with the constraint that any node can contain at most two child nodes. This type of tree is called a binary tree. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Applications of Trees&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Useful in hierarchical parent/child data representations. For example, folders and subfolders systems in computers and genealogical information in biological species. &lt;/li&gt;
&lt;li&gt;Databases use B-Tree data structures for indexing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Advantages of Trees&lt;/strong&gt;&lt;br&gt;
Efficient way of storing data that is naturally hierarchal. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages of Trees&lt;/strong&gt;&lt;br&gt;
Uses extra memory to store nodes and address to child nodes&lt;/p&gt;

&lt;h3&gt;
  
  
  Graphs
&lt;/h3&gt;

&lt;p&gt;A graph is a non-linear data structure consisting of a collection of elements called vertices, connected through links called edges. Going by this definition, a tree is a special type of graph. However, unlike trees, graphs have no rules in how the nodes are connected. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgo40hjr08ny0zs17ch4d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgo40hjr08ny0zs17ch4d.png" alt="Graphs data structure" width="491" height="212"&gt;&lt;/a&gt;&lt;/p&gt;
Graphs data structure (Source: GeeksforGeeks)



&lt;p&gt;&lt;strong&gt;Applications of Graphs&lt;/strong&gt;&lt;br&gt;
Systems that use a relationship (graph-like) structure: Social media applications like Facebook and LinkedIn to show user relationships, Maps and GPS systems, telecom and flight networks &lt;br&gt;
&lt;strong&gt;Advantages of Graphs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Useful in representing hierarchical data and solving algorithms like finding the shortest path between several points.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages of Graphs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Graphs can be complex to handle due to the different nodes and pointers&lt;/li&gt;
&lt;li&gt;Graphs use a lot of memory allocation because you need memory to store the addresses of the nodes and their pointers to the nodes connected to them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Heaps
&lt;/h3&gt;

&lt;p&gt;Heap is a special tree-based data structure that satisfies the heap property. Heap has two unique properties: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Max-Heap:&lt;/strong&gt; The root node must have a higher value than all its children (sub-trees)&lt;br&gt;
&lt;strong&gt;Min-Heap:&lt;/strong&gt; The root node must have a lower value than all its children (sub-trees)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9zgx8ds6ywe6lj1hizql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9zgx8ds6ywe6lj1hizql.png" alt="Heap data structure" width="800" height="479"&gt;&lt;/a&gt;&lt;br&gt;Heaps data structure - Source: &lt;a href="https://www.geeksforgeeks.org/heap-data-structure/" rel="noopener noreferrer"&gt;GeeksforGeeks&lt;/a&gt;&lt;br&gt;

 &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Applications of Heaps&lt;/strong&gt;&lt;br&gt;
Useful in scenarios where fast access to the highest or lowest element is needed. For example, in operating systems, to assign resources to specific tasks and Priority queues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages of Heaps&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Efficient for scenarios where you need quick access to the largest (or smallest) element.&lt;/li&gt;
&lt;li&gt;Heaps typically use an array-based data structure; as such, they do not require extra memory for pointers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages of Heaps&lt;/strong&gt;&lt;br&gt;
Searching for elements in a heap requires traversing the entire heap.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tries
&lt;/h3&gt;

&lt;p&gt;A Trie is a special kind of tree-based data structure that simply stores a set of strings. It is known by many names, including prefix tree, digital search tree, and retrieval tree. Every node (except the root/parent node) in the trie stores a letter of an alphabet from the string, and strings or words can be retrieved by traversing the trie. For example, if we have a set of strings {cat, bat, ball, rat, cap, be}, our trie will look like this. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0zcpt4dfen1w69i8f09i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0zcpt4dfen1w69i8f09i.png" alt="trie data structure" width="800" height="636"&gt;&lt;/a&gt;&lt;/p&gt;
Tries data structure (Source:Btechsmartclass)




&lt;p&gt;Any traversal from the root to the end of any nodes will represent one of the words in our set of words.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Applications of Tries&lt;/strong&gt;&lt;br&gt;
Tries are very beneficial in solving problems related to strings, most especially searching in strings. A good example is the autocomplete and spell check feature in applications. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages of Tries&lt;/strong&gt;&lt;br&gt;
Very efficient for searching elements&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages of Tries&lt;/strong&gt;&lt;br&gt;
Tries require a lot of memory for storing each of the strings. &lt;/p&gt;

&lt;h3&gt;
  
  
  Hashtable
&lt;/h3&gt;

&lt;p&gt;Hashtable is a data structure that stores elements in an associative or dictionary-like manner(key/value pairs). A hash table always uses some function, known as a hash function, acting on the key to compute an index location where the computer will store the value. To look a value up given a key, you hash the key and get back the location of the corresponding value. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbhtferob7uyh92boc7gs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbhtferob7uyh92boc7gs.png" alt="Hash table" width="800" height="584"&gt;&lt;/a&gt;&lt;/p&gt;
Hash Table data structure (Source: Wikipedia)




&lt;p&gt;&lt;strong&gt;Applications of Hash Tables&lt;/strong&gt;&lt;br&gt;
Useful in scenarios where associative data is required. Data stored in databases is generally of the key-value format, which is done through hash tables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages of Hashtable&lt;/strong&gt;&lt;br&gt;
They are efficient for fast look-ups and in cases where you have associative data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages of Hashtable&lt;/strong&gt;&lt;br&gt;
The ordering of elements in Hash tables is not guaranteed. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
Data structures are essential to many computer algorithms because they allow programmers to manage data efficiently. The right data structure can significantly increase the performance of a computer program or algorithm. Ultimately, the data structures you choose will depend on how much data you have, what that data looks like, and what operations you want to perform.&lt;/p&gt;

&lt;p&gt;In the rest of the series, I will be going into depth about these data structures'concrete implementations, use cases, and the different operations we can perform on them. &lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>datastructures</category>
    </item>
    <item>
      <title>Unboxing a Database-How Databases Work Internally</title>
      <dc:creator>Daniel Elegberun</dc:creator>
      <pubDate>Fri, 30 Jul 2021 15:23:53 +0000</pubDate>
      <link>https://forem.com/gbengelebs/unboxing-a-database-how-databases-work-internally-155h</link>
      <guid>https://forem.com/gbengelebs/unboxing-a-database-how-databases-work-internally-155h</guid>
      <description>&lt;p&gt;Cover Photo by &lt;a href="https://unsplash.com/@nuvaproductions?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Javier Miranda&lt;/a&gt; on &lt;a href="https://unsplash.com/@nuvaproductions?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Databases are one of those abstract, mysterious things that "just work" when you run an insert statement, where's the data stored?. How is it stored? Why are queries so fast? What's underneath the black box of a database? Sometimes it all just feels like magic. &lt;/p&gt;

&lt;p&gt;It's 1 am in Lagos and I can't sleep. I pick up my phone and head to Google to help me demystify this black box. The next words you read are my attempt to unbox a database.&lt;/p&gt;

&lt;p&gt;My focus on this article will be on SQL databases but I believe the underlying concepts can be passed to other types of databases. Before we go on let us define some terms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Database
&lt;/h2&gt;

&lt;p&gt;A database is a set of physical files(data) on a hard disk stored and accessed electronically from a computer system. Usually created by the &lt;strong&gt;CREATE DATABASE&lt;/strong&gt; statement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Database management system
&lt;/h2&gt;

&lt;p&gt;A database management system is software that handles the storage, retrieval, and updating of data in a computer system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F86sxwxawaoacafgf470t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F86sxwxawaoacafgf470t.png" alt="dbms" width="800" height="217"&gt;&lt;/a&gt;&lt;/p&gt;
Popular database management systems



&lt;h2&gt;
  
  
  Database engine
&lt;/h2&gt;

&lt;p&gt;A database engine is the underlying software component that a database management system uses to create, read, update and delete data from a database.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the difference between a database management system and a database engine?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;database management&lt;/strong&gt; system is the software with its functions that allow us to connect to a &lt;strong&gt;database engine&lt;/strong&gt;. The database engines are the internal tools that allow or facilitate a certain number of operations on the tables and their data.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does a database management system store data?
&lt;/h2&gt;

&lt;p&gt;Most database management systems store data in files. MySQL for example stores data in files in a specific directory that has the system variable "datadir". Opening a MySQL console and running the following command will tell you exactly where the folder is located.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mysql&amp;gt;  SHOW VARIABLES LIKE 'datadir';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| datadir       | /var/lib/mysql/ |
+---------------+-----------------+
1 row in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;a href="https://stackoverflow.com/questions/10378693/how-does-mysql-store-data" rel="noopener noreferrer"&gt;stack overflow answer&lt;/a&gt; explains it really well.&lt;/p&gt;

&lt;p&gt;As you can see from the above command, my "datadir" was located in /var/lib/mysql/. The location of the "datadir" may vary in different systems. The directory contains folders and some configuration files. Each folder represents a MySQL database and contains files with data for that specific database, below is a screenshot of the "datadir" directory in my system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fotqaz8lnxwoz2dajmdr7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fotqaz8lnxwoz2dajmdr7.png" alt="mysql" width="675" height="463"&gt;&lt;/a&gt;&lt;/p&gt;
a data dir folder in a system



&lt;p&gt;Each folder in the directory represents a MySQL database. Each database folder contains files that represent the tables in that database. There are two files for each table, one with a .frm extension and the other with a .idb extension. See the screenshot below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd4m1q0u99tt8rezjjcq9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd4m1q0u99tt8rezjjcq9.png" alt="mysql2" width="681" height="403"&gt;&lt;/a&gt;&lt;/p&gt;
Files in a database folder



&lt;ul&gt;
&lt;li&gt;The .frm table file stores the table's format. &lt;a href="https://dev.mysql.com/doc/internals/en/frm-file-format.html" rel="noopener noreferrer"&gt;Details: MySQL .frm File Format&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The .ibd file stores the table's data. &lt;a href="https://dev.mysql.com/doc/refman/5.7/en/innodb-multiple-tablespaces.html" rel="noopener noreferrer"&gt;Details: InnoDB File-Per-Table Tablespaces&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When we insert a record into a table we are actually inserting into a datafile. A page (representing the rows of the table)is created in that datafile. By default, all datafiles have a page size of 16KB, you can reduce or increase the page size depending on the database engine you are using.&lt;/p&gt;

&lt;p&gt;As more and more records are inserted into the table(datafile) several data pages are created.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Pages Relate to Table Rows
&lt;/h2&gt;

&lt;p&gt;The maximum row length is slightly less than half a database page. For example, the maximum row length is slightly less than 8KB for the default 16KB InnoDB page size. For 64KB pages, the maximum row length is slightly less than 16KB.&lt;/p&gt;

&lt;p&gt;If a row does not exceed the maximum row length, all of its data is stored locally within the page. If a row exceeds the maximum row length the database engine stores a 20-byte pointer to the next page locally in the row, and stores the remaining rows externally in overflow pages.&lt;/p&gt;

&lt;p&gt;These two articles do a wonderful job of describing how data pages look in sql server. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.c-sharpcorner.com/UploadFile/ff0d0f/how-sql-server-stores-data-in-data-pages-part-1/" rel="noopener noreferrer"&gt;how-sql-server-stores-data-in-data-pages-part1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.c-sharpcorner.com/UploadFile/ff0d0f/how-sql-server-stores-data-in-data-pages-part-2/" rel="noopener noreferrer"&gt;how-sql-server-stores-data-in-data-pages-part2&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let us assume we have a table(tblEmployees) and we insert a single record into it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;INSERT&lt;/span&gt; &lt;span class="n"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;tblEmployees&lt;/span&gt; &lt;span class="nf"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Abhishek&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a sample data page of that insertion into the datafile. It is divided into 3 main sections&lt;/p&gt;

&lt;h3&gt;
  
  
  Section 1:Page Header
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2hmh4p65rcqnj85epihc.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2hmh4p65rcqnj85epihc.jpeg" alt="page-header" width="590" height="497"&gt;&lt;/a&gt;&lt;/p&gt;
Page Header



&lt;ul&gt;
&lt;li&gt;m_type =1 indicates that it is a data page.&lt;/li&gt;
&lt;li&gt;m_nextpage: This is the link to the memory location of the next data page that will be created, in this case, we have a single data page so it is(0:0).&lt;/li&gt;
&lt;li&gt;m_Prevpage: This is the link to the memory location of the previous data page. Since we have a single data page the value is(0:0). &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Section 2:Actual Data
&lt;/h3&gt;

&lt;p&gt;The actual data that we insert into our table is stored in this section. If you remember, we inserted 1 record with an employee named "Abhishek". That record will be saved here, in this section as shown below.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhnmrbzwtu5xun058tv07.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhnmrbzwtu5xun058tv07.jpeg" alt="actual-data" width="519" height="493"&gt;&lt;/a&gt;&lt;/p&gt;
Actual Data



&lt;ul&gt;
&lt;li&gt;Record Type = PRIMARY_RECORD, which means it's our actual data.&lt;/li&gt;
&lt;li&gt;Memory Dump = This points to the Actual data's location in memory.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Section 3:Offset Table
&lt;/h3&gt;

&lt;p&gt;Offset Table: This section of the data file tells you where the record Abhishek is saved exactly in memory.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyxp7ska6onsxbztdwvw2.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyxp7ska6onsxbztdwvw2.jpeg" alt="offset-table" width="577" height="162"&gt;&lt;/a&gt;&lt;/p&gt;
Offset Table



&lt;p&gt;If you see the row offset, it's pointing to the actual data's location.&lt;/p&gt;

&lt;p&gt;These diagrams show how rows are stored in a  datafile.&lt;/p&gt;
&lt;h2&gt;
  
  
  How does indexing work?
&lt;/h2&gt;

&lt;p&gt;A database index is a data structure that improves the speed of data retrieval operations on a database table.&lt;/p&gt;

&lt;p&gt;Indexing is the way to get an unordered table into an order that will maximize the query efficiency. A Clustered Index is a special type of index that reorders the way records in the table are physically stored on the disk. So how does it work?&lt;/p&gt;

&lt;p&gt;In reality, the database table does not reorder itself every time the query conditions change to optimize the query performance, what happens is that when you create an index you cause the database to create a data structure which in most cases is likely to be a B+Tree. The main advantage of this data structure is that it is sortable and this makes our search more efficient.&lt;/p&gt;

&lt;p&gt;A B+Tree is a type of dictionary, no more and no less. If you think about a linguistic dictionary, it's ordered by "words", and associated with each word is a definition. You look up a word and get a definition.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4yrqlqco1psk4ex01zpi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4yrqlqco1psk4ex01zpi.jpg" alt="Indexed Dictionary" width="740" height="416"&gt;&lt;/a&gt;&lt;/p&gt;
An Indexed Dictionary



&lt;p&gt;So the context of a map data structure is that you have keys ("words") and you want to map this to values ("definitions").&lt;/p&gt;

&lt;p&gt;B+trees have an advantage for certain types of queries. For example, you can do range queries, say if you want to find all entries where the key is between two values (e.g. all words in the dictionary starting with "q").&lt;/p&gt;

&lt;p&gt;B+trees are page-structured (meaning they can be implemented on top of fixed-size disk pages; which minimizes the number of disk accesses needed to perform a query.&lt;/p&gt;
&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Let us assume we have a table called Employee_Detail. We can create a clustered index with the following command on the Emp_Iid column.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create Clustered Index My_ClusteredIndex  
on Employee_Detail(Emp_Iid) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's insert some records&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Head over to this &lt;a href="https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html" rel="noopener noreferrer"&gt;site&lt;/a&gt; and insert records from 1 to 6 simulating how records will be inserted in a database. You will see how the tree automatically adjusts as records are being inserted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Another thing to note the data value locations never change but the (pointers to those values are the ones that are constantly shifting).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The B+Tree will be formed like this. - The center point of the records which in our case is 3 will be the head node. All the Ids that are lower than 3 will be moved to the left and the Ids greater than 3 to the right as shown in this diagram.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy8ahdte53ai5d1vshxwv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy8ahdte53ai5d1vshxwv.png" alt="btree" width="688" height="407"&gt;&lt;/a&gt;&lt;/p&gt;
BTree Visualized



&lt;p&gt;The left side value of each node is always less than the node itself and the right-side value is always greater than the node. The last set of values are called leaf nodes and they contain the actual data value while the intermediate rows hold pointers to the actual data value location.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Think of it like a dictionary that contains a name tag. All the words with "c" are labeled under the "c" tag. words higher than "c" are shifted to the right and words lower than "c" to the left. The tag "c" does not contain the value but a (pointer) to the actual words&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;From the earlier explanation on how SQL stores data in data pages we can infer that the leaf nodes represent data pages containing the table rows. &lt;/p&gt;

&lt;p&gt;If we want to get the employees where Emp_Iid is 4.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;select * from employee_Detail where Emp_Iid=4  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a normal case, the system will perform 4 comparisons, the first for 1, the second for 2, and the third for 3  and in the fourth comparison, it will find the desired result.&lt;/p&gt;

&lt;p&gt;Using an index, the system only does a single comparison because 3 is the head node of the B+Tree and it knows that 4 is greater than 3 so the record will be on the right. Once it checks the next key It will find a pointer to the data value 4 which is the value that is being requested.&lt;/p&gt;

&lt;p&gt;From this example, we can say that by using an index we can increase the speed of data retrieval.&lt;/p&gt;

&lt;h2&gt;
  
  
  Components of a Database Engine
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw0wqk2vpxfvi7br0dvce.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw0wqk2vpxfvi7br0dvce.png" alt="database-engine" width="800" height="721"&gt;&lt;/a&gt;&lt;/p&gt;
Components of a database engine



&lt;p&gt;All SQL database engines have a compiler to translate the SQL statement into byte code and a virtual machine to evaluate the byte code. &lt;/p&gt;

&lt;p&gt;The RDBMS processes the SQL statement by:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.Parsing&lt;/strong&gt;: Validates the statement by checking the SQL statement against the system’s catalog and seeing if these databases, tables, and columns that the user wants exist, and if the user has privileges to execute the SQL query.&lt;br&gt;
Under the parsing stage, there is a syntax check, semantic check, and shared pool check.&lt;/p&gt;
&lt;h3&gt;
  
  
  Syntax check
&lt;/h3&gt;

&lt;p&gt;A statement that breaks a rule for well-formed SQL syntax fails the check. For example, the following statement fails because the keyword FROM is misspelled as FORM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQL&amp;gt; SELECT * FORM employees;
SELECT * FORM employees
         *
ERROR at line 1:
ORA-00923: FROM keyword not found where expected
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Semantic Check
&lt;/h3&gt;

&lt;p&gt;The semantics of a statement is its meaning. A semantic check determines whether a statement is meaningful, for example, whether the objects and columns in the statement exist.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQL&amp;gt; SELECT * FROM nonexistent_table;
SELECT * FROM nonexistent_table
              *
ERROR at line 1:
ORA-00942: table or view does not exist

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Shared Pool Check
&lt;/h3&gt;

&lt;p&gt;During the parse, the database performs a shared pool check to determine whether it can skip resource-intensive steps of statement processing.&lt;/p&gt;

&lt;p&gt;To this end, the database uses a hashing algorithm to generate a hash value for every SQL statement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.Compiling (Binding)&lt;/strong&gt;: Generates a query plan for the statement which is the binary representation of the steps required to carry out the statement. In almost all SQL engines, it will be byte code. What has now been compiled is a command-line shell — a program that reads SQL statements and now sends them to the database server for optimization and execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.Optimizing&lt;/strong&gt;: Optimizes the query plan and chooses the best algorithms such as for searching and sorting. This feature is called the Query Optimizer. The Query Optimizer devises several possible ways to execute the query i.e. several possible execution plans. An execution plan is, in essence, a set of physical operations (an index seek, a nested loop join, and so on) to be performed.&lt;br&gt;
Once this is done, we now have a prepared SQL statement.&lt;/p&gt;
&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;This example shows the execution plan of a SELECT statement when AUTOTRACE is enabled. The statement selects the last name, job title, and department name for all employees whose last names begin with the letter A.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT e.last_name, j.job_title, d.department_name 
FROM   hr.employees e, hr.departments d, hr.jobs j
WHERE  e.department_id = d.department_id
AND    e.job_id = j.job_id
AND    e.last_name LIKE 'A%';

Execution Plan
----------------------------------------------------------
Plan hash value: 975837011

--------------------------------------------------------------------------------
| Id| Operation                     | Name        |Rows|Bytes|Cost(%CPU)|Time  |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT              |             |  3 | 189 | 7(15)| 00:00:01 |
|*1 |  HASH JOIN                    |             |  3 | 189 | 7(15)| 00:00:01 |
|*2 |   HASH JOIN                   |             |  3 | 141 | 5(20)| 00:00:01 |
| 3 |    TABLE ACCESS BY INDEX ROWID| EMPLOYEES   |  3 |  60 | 2 (0)| 00:00:01 |
|*4 |     INDEX RANGE SCAN          | EMP_NAME_IX |  3 |     | 1 (0)| 00:00:01 |
| 5 |    TABLE ACCESS FULL          | JOBS        | 19 | 513 | 2 (0)| 00:00:01 |
| 6 |   TABLE ACCESS FULL           | DEPARTMENTS | 27 | 432 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
   2 - access("E"."JOB_ID"="J"."JOB_ID")
   4 - access("E"."LAST_NAME" LIKE 'A%')
       filter("E"."LAST_NAME" LIKE 'A%')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4.Executing&lt;/strong&gt;: The RDBMS executes the SQL statement by running the query plan.&lt;/p&gt;

&lt;p&gt;For an in-depth view, check out this &lt;a href="https://docs.oracle.com/database/121/TGSQL/tgsql_sqlproc.htm#TGSQL186" rel="noopener noreferrer"&gt;tutorial&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;This article has covered a lot of ground, but by now you should have an understanding (or at least an appreciation) of the components and processes that form the databases we use every day.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

&lt;p&gt;Follow me here and across my social media for more content like this &lt;a href="https://www.linkedin.com/in/olugbenga-elegberun/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;. &lt;a href="https://twitter.com/ElegberunDaniel?s=09" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  REFERENCES AND MORE
&lt;/h2&gt;

&lt;p&gt;1.&lt;a href="https://blog.devgenius.io/how-a-sql-database-engine-works-c319200889d7" rel="noopener noreferrer"&gt;How a sql database engine works by Andres reyes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2.&lt;a href="https://medium.com/@grepdennis/how-a-sql-database-engine-works-c67364e5cdfd" rel="noopener noreferrer"&gt;How a sql database engine works by Dennis Pham&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3.&lt;a href="https://www.red-gate.com/simple-talk/databases/sql-server/performance-sql-server/the-sql-server-query-optimizer/" rel="noopener noreferrer"&gt;The sql server query optimizer by Benjamin Nevarez&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4.&lt;a href="https://www.freecodecamp.org/news/database-indexing-at-a-glance-bb50809d48bd/" rel="noopener noreferrer"&gt;An in-depth look at Database Indexing by Kousik Nath&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5.&lt;a href="https://dzone.com/articles/database-btree-indexing-in-sqlite" rel="noopener noreferrer"&gt;Database btree indexing in sqlite by Dhanushka Madushan&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6.&lt;a href="https://www.sqlskills.com/blogs/paul/inside-the-storage-engine-using-dbcc-page-and-dbcc-ind-to-find-out-if-page-splits-ever-roll-back/" rel="noopener noreferrer"&gt;Inside the storage engine by Paul Randal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;7.&lt;a href="https://cs.stackexchange.com/questions/27985/b-tree-and-how-it-is-used-in-practice" rel="noopener noreferrer"&gt;B-tree and how it is used in practice answered by Pseudonym&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;8.&lt;a href="https://www.c-sharpcorner.com/UploadFile/f0b2ed/index-in-sql/" rel="noopener noreferrer"&gt;Index in sql by Pankaj Kumar Choudhary&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;9.&lt;a href="https://www.c-sharpcorner.com/UploadFile/ff0d0f/how-sql-server-stores-data-in-data-pages-part-1/" rel="noopener noreferrer"&gt;How sql server stores data in data pages part 1 by Abhishek Yadav&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;10.&lt;a href="https://www.c-sharpcorner.com/UploadFile/ff0d0f/how-sql-server-stores-data-in-data-pages-part-2/" rel="noopener noreferrer"&gt;How sql server stores data in data pages part 2 by Abhishek Yadav&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;11.&lt;a href="https://docs.oracle.com/database/121/TGSQL/tgsql_sqlproc.htm#TGSQL186" rel="noopener noreferrer"&gt;SQL Processing by Oracle&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;12.&lt;a href="https://stackoverflow.com/questions/2468202/how-does-a-sql-query-work" rel="noopener noreferrer"&gt;How does a sql query work by &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;13.&lt;a href="https://hackernoon.com/how-sql-database-engine-work-483e32o7" rel="noopener noreferrer"&gt;How sql database engine works by Vijay Singh Khatri&lt;/a&gt;&lt;/p&gt;

</description>
      <category>database</category>
      <category>bigdata</category>
      <category>distributedsystems</category>
    </item>
    <item>
      <title>How Search Engines Work: Finding a Needle in a Haystack</title>
      <dc:creator>Daniel Elegberun</dc:creator>
      <pubDate>Fri, 16 Jul 2021 15:10:51 +0000</pubDate>
      <link>https://forem.com/gbengelebs/how-search-engines-work-finding-a-needle-in-a-haystack-4lnp</link>
      <guid>https://forem.com/gbengelebs/how-search-engines-work-finding-a-needle-in-a-haystack-4lnp</guid>
      <description>&lt;p&gt;Every time I go to bed I consider myself lucky to have been born at a time like this. In one-tenth of a second I can find out information about anything. It's incredible!.&lt;/p&gt;

&lt;p&gt;As of June 18, 2021, there are currently over 1.86 billion websites online. A report by &lt;a href="https://sitefy.co/" rel="noopener noreferrer"&gt;sitefy&lt;/a&gt; estimates 547,200 new websites are created every day. It's estimated that Google processes approximately 63,000 search queries every second, translating to 5.6 billion searches per day and approximately 2 trillion global searches per year. These are outrageous numbers by any standard, Yet to the end-user, it's as easy as a click of a button - The true beauty of distributed systems. &lt;/p&gt;

&lt;p&gt;If you have ever wondered how search results get delivered to you in a split second, then this article is for you. I will be explaining how search engines work and the different components that work together to deliver results to you - FAST.&lt;/p&gt;

&lt;h1&gt;
  
  
  How do search engines work?
&lt;/h1&gt;

&lt;p&gt;On a basic level, search engines do three main things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Organize the entire web on their database&lt;/li&gt;
&lt;li&gt;Instantly match your search &lt;/li&gt;
&lt;li&gt;Present the results in the way you want them.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Organize the web on their database
&lt;/h2&gt;

&lt;p&gt;Contrary to what you might first think. Search Engines do not actually search the internet when you type in a query. That will take yearsss. A lot of things go on behind the scenes to make sense of the internet before you type in your search. So when you hit that little microsope. It only searches its own organized version of the internet which is a lot faster.&lt;/p&gt;

&lt;p&gt;Search Engines organize the web through three fundamental actions: crawling, indexing, and ranking.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv3es2kzhx5ixyelr2cvu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv3es2kzhx5ixyelr2cvu.png" alt="how-search-engines-work" width="600" height="95"&gt;&lt;/a&gt;&lt;/p&gt;
Search Engines Actions



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CRAWLING&lt;/strong&gt;
A search engine navigates the web by downloading web pages and following anchor links on these pages to discover new pages that have been made available. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These search engine bots popularly called(Spiders)start from a seed or a list of known URLs, and crawl the web pages at these URLs first. As they crawl those web pages, they find hyperlinks to other pages, and add those to the list of pages to crawl next. They keep going until they have finally crawled the entire web. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuk764vq96xiv5x9x37xz.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuk764vq96xiv5x9x37xz.PNG" alt="web-crawler" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;
web crawler: Image from code.org



&lt;p&gt;Interestingly enough only about 70% of the internet has been crawled. This is because there isn't a central registry of all web pages, so Google must constantly search for new pages and add them to its list of known pages. Other pages are discovered when a website owner submits a list of pages (a sitemap) for Google to crawl.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does the web crawler know what to crawl?
&lt;/h3&gt;

&lt;p&gt;A web crawler will follow certain policies that make it more selective about which pages to crawl, in what order to crawl them, and how often they should crawl them again to check for content updates. Some of these policies are :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Web page importance - The crawlers use the number of active visitors to that site and the number of other pages that link to that page. If people are visiting the site and referencing its content then it must provide reliable information. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By using the Robots.txt file- A robots.txt file is a set of instructions for bots. This file is included in the source files of most websites. It guides the web bots on what to crawl. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;:&lt;br&gt;
Check out this site &lt;a href="https://www.netflix.com/robots.txt" rel="noopener noreferrer"&gt;robots.txt&lt;/a&gt; for Netflix's own Robot.txt file. &lt;/p&gt;

&lt;p&gt;Some examples of popular bots are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Google: Googlebot (actually two crawlers, Googlebot Desktop and Googlebot Mobile, for desktop and mobile searches)&lt;/li&gt;
&lt;li&gt;Bing: Bingbot&lt;/li&gt;
&lt;li&gt;Yandex (Russian search engine): Yandex Bot&lt;/li&gt;
&lt;li&gt;Baidu (Chinese search engine): Baidu Spider.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;INDEXING&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Imagine having to look for a word in a dictionary that is not arranged or a dictionary that does not have a name tag on each alphabet. Now compare it to a dictionary that has all these. Searching for a word in dictionary 2 will be considerably faster than dictionary 1.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4yrqlqco1psk4ex01zpi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4yrqlqco1psk4ex01zpi.jpg" alt="Indexed Dictionary" width="740" height="416"&gt;&lt;/a&gt;&lt;/p&gt;
An Indexed Dictionary



&lt;p&gt;Indexing is done to arrange web pages in a way that information can be easily retrieved from it.&lt;/p&gt;

&lt;p&gt;After the pages have been crawled the page URL, along with the full Html document of the page are sent to the store server to compress and store in the database. Every web page has an associated ID number called a docID which is assigned whenever a new URL is parsed out of a web page.&lt;/p&gt;

&lt;p&gt;An indexer function reads the pages from the database, uncompresses the documents, and parses them to form an inverted index.&lt;/p&gt;

&lt;p&gt;An inverted index is a database index which stores a mapping from content, such as words or numbers, to its locations in a table, or in a document or a set of documents.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwjsdzlsxk9xubpga0ob.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwjsdzlsxk9xubpga0ob.png" alt="inverted index" width="588" height="447"&gt;&lt;/a&gt;&lt;/p&gt;
A sample Inverted Index



&lt;p&gt;A sentence is broken into words stripped of the stopped words and stored in a row alongside the frequency of occurrence of the word and its position in the HTML document.(stopped words are words that will occur regularly in any sentence such as "the", "is", "at", "which").&lt;/p&gt;

&lt;p&gt;If you have  a query for example:&lt;em&gt;How long does it take to travel to mars&lt;/em&gt;, multiple query words like ("travel" and "mars") are searched independently in the Inverted Index. If travel occurs in documents (2,4,6,8) and mars occurs in documents (3,7,8,11,19). You can take the intersection of both lists where the words occur frequently,(8) in this case, which is the document in which both query words occur. &lt;/p&gt;

&lt;p&gt;Storing the documents this way makes search considerably faster. Once a search query comes in. The search engine just needs to get the most frequently occurring words, intersects them and parse them through its own custom search ranking algorithm to deliver the results.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg2zrm74dd9bi2ts8hmdj.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg2zrm74dd9bi2ts8hmdj.PNG" alt="inverted index" width="729" height="578"&gt;&lt;/a&gt;&lt;/p&gt;
Inverted Index processing



&lt;p&gt;&lt;a href="https://community.hitachivantara.com/s/article/search-the-inverted-index" rel="noopener noreferrer"&gt;Search the Inverted Index&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RANKING&lt;/strong&gt;
The algorithms used to rank the most relevant results differ for each search engine. For example, a page that ranks highly for a search query in Google may not rank highly for the same query in Bing. The ranking is accomplished by assessing a number of different factors based on an end user’s query for quality and relevancy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The exact algorithms of these search engines have been kept a secret by these companies but a guess can be made based on certain factors. &lt;br&gt;
In addition to the search query, search engines use other relevant data to return results, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Page Quality- Several factors contribute to the page quality such as: how many links references that page, how many page visits the site receives and how long users spend on the page. All these factors determine if the page is quality and if search engines should rank it highly.&lt;/li&gt;
&lt;li&gt;Location – Some search queries are location-dependent e.g. ‘restaurants near me’ or ‘movie times’.&lt;/li&gt;
&lt;li&gt;Language detected – Search engines will return results in the language of the user if they can be detected.&lt;/li&gt;
&lt;li&gt;Previous search history – Search engines will return different results for a query dependent on what the user has previously searched for.&lt;/li&gt;
&lt;li&gt;Device – A different set of results may be returned based on the device from which the query was made.&lt;/li&gt;
&lt;li&gt;The freshness of data- How relevant is the data the user needs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What database do search engines use to store data?
&lt;/h3&gt;

&lt;p&gt;Google uses Bigtable which is a distributed storage system for managing structured data that is designed to scale to a very large size: petabytes of data across thousands of commodity servers.&lt;a href="http://research.google.com/archive/bigtable.html" rel="noopener noreferrer"&gt;BigTable&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bigtable is not a relational database. Tables consist of rows and columns, and each cell has a timestamp. There can be multiple versions of a cell with different time stamps. The timestamp allows for operations such as "select 'n' versions of this Web page" or "delete cells that are older than a specific date/time."&lt;a href="https://stackoverflow.com/questions/362956/what-database-does-google-use" rel="noopener noreferrer"&gt;What Database does Google Use?&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is a statement from Google's Big table research paper.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv2k6q2ow1h3lrmwxo127.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv2k6q2ow1h3lrmwxo127.PNG" alt="Big Table" width="692" height="157"&gt;&lt;/a&gt;&lt;/p&gt;
A slice of Big Table Row



&lt;blockquote&gt;A slice of an example table that stores Web pages. The row name is a reversed URL. The contents column family contains the page contents, and the anchor column family contains the text of any anchors that reference the page. CNN's home page is referenced by both the Sports Illustrated and the MY-look home pages, so the row contains columns named anchor:cnnsi.com and anchor:my.look.ca. Each anchor cell has one version; the contents column has three versions, at timestamps t3, t5, and t6.
&lt;/blockquote&gt;

&lt;p&gt;To manage the huge tables, Bigtable splits tables at row boundaries and saves them as tablets. A tablet is around 200 MB, and each machine saves about 100 tablets. This setup allows tablets from a single table to be spread among many servers. It also allows for fine-grained load balancing. If one table is receiving many queries, it can shed other tablets or move the busy table to another machine that is not so busy. Also, if a machine goes down, a tablet may be spread across many other servers so that the performance impact on any given machine is minimal.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. How are search engines so fast? (Instantly matching your search)
&lt;/h2&gt;

&lt;p&gt;If you have N computers and want to search a large document, you can split the document into N ranges and let each computer search that range. So, with string parallelization, you can speed up search queries faster. Your query is split into individual words and sent to a bunch of computers to handle different parts of the query, If you throw in an already inverted indexed database like the one we discussed earlier then the speed could go up faster. If we now store this indexed information on the RAM of these database servers we can take speed to another level. (Information in the RAM is 30 times faster than the real-world performance of an SSD) &lt;/p&gt;

&lt;p&gt;Another interesting thing is that search engines do not have to provide you the most absolute correct information all the time. They can cache results and just show the ones that are already high in their ranking for similar queries or show cached information that they have shown you before.&lt;/p&gt;

&lt;p&gt;Search Engines also predict words for you. This is done to speed up the search process and reduce the load on the server by preparing already made search results for you so you get things faster. Immediately you start typing Google has already started to look for the first N results so that once you hit enter, the result is already there.&lt;/p&gt;

&lt;p&gt;In summary, Search engines return relevant results in response to user queries quickly by using their index and taking advantage of parallelism to break up the large search problem into many small pieces that are solved in parallel.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Presenting the results in the way you would want them.
&lt;/h3&gt;

&lt;p&gt;Now let us walk through the process from end to end. When I type into my search bar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpih68klszffcx3h4b8g0.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpih68klszffcx3h4b8g0.PNG" alt="micheal-jordan-search-query" width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;
Sample search Query



&lt;p&gt;My browser first completes a DNS lookup mapping &lt;a href="http://www.google.com" rel="noopener noreferrer"&gt;www.google.com&lt;/a&gt; to a specific IP address. At this stage, Google’s DNS load balancer determines which cluster of computers at which of Google’s data centers will process the query. Once a data center has been determined, the query is transmitted via “HTTP” to a specific data center and individual clusters of servers. &lt;/p&gt;

&lt;p&gt;Upon arrival at the data center cluster, each query is greeted by Google’s second load balancer. The Google hardware load balancer consists of 10 to 15 machines and determines which machines are available to process the query.&lt;/p&gt;

&lt;p&gt;The query is then split into words and executed, simultaneously hitting 300 to 400 back-end machines representing Google’s verticals, advertising, and spell check among others. At this point, the best results are gathered and the query data returns to the Google Mixer. &lt;/p&gt;

&lt;p&gt;The mixer takes this data, blends Universal elements with ads while pasting results in order, based on relevancy criteria set by Google's Ranking Algorithm. The ordered results then go back to the Google web server for HTML coding. Once the HTML is completed and pages are formatted, the search engine results are marked “done” by the load balancer and returned to the user as search engine results pages (SERPs). The entire process taking, about 3 centiseconds".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0u8ye14zz34yofx3jr24.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0u8ye14zz34yofx3jr24.PNG" alt="micheal=jordan-search-query-result" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;
Search Query Result



&lt;p&gt;Follow me here and across my social media for more content like this &lt;a href="https://www.linkedin.com/in/olugbenga-elegberun/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;. &lt;a href="https://twitter.com/ElegberunDaniel?s=09" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  SUMMARY
&lt;/h3&gt;

&lt;p&gt;Search engines have changed how we access information and understanding their anatomy helps us to truly appreciate the beauty behind the madness.&lt;/p&gt;

&lt;h2&gt;
  
  
  REFERENCES
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.cloudflare.com/learning/bots/what-is-a-web-crawler/" rel="noopener noreferrer"&gt;What is a Web-crawler&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.cloudflare.com/learning/bots/what-is-robots.txt/" rel="noopener noreferrer"&gt;What-is-robots.txt&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://research.google.com/archive/bigtable-osdi06.pdf" rel="noopener noreferrer"&gt;Bigtable&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.google.com/search/howsearchworks/" rel="noopener noreferrer"&gt;How Search Works&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://ahrefs.com/blog/how-do-search-engines-work/" rel="noopener noreferrer"&gt;How do Search Engines Work&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;6.&lt;a href="https://www.deepcrawl.com/knowledge/technical-seo-library/how-do-search-engines-work/" rel="noopener noreferrer"&gt;How do search Engines Work&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;7.&lt;a href="http://blogoscoped.com/archive/2008-07-08-n70.html" rel="noopener noreferrer"&gt;Behind the scenes of a Google Query&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;8.&lt;a href="https://stackoverflow.com/questions/47524311/how-does-google-perform-search-for-any-given-query-so-quickly-over-so-many-do" rel="noopener noreferrer"&gt;Stack Overflow- How does google perform search very fast?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;9.&lt;a href="https://www.youtube.com/watch?v=LVV_93mBfSU&amp;amp;t=142s" rel="noopener noreferrer"&gt;How Google searches one document among Billions of documents quickly?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;10.&lt;a href="https://community.hitachivantara.com/s/article/search-the-inverted-index" rel="noopener noreferrer"&gt;Search: The Inverted Index&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;11.&lt;a href="http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/334.pdf" rel="noopener noreferrer"&gt;The Anatomy of a Large-Scale Hypertextual&lt;br&gt;
Web Search Engine&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;12.&lt;a href="https://static.googleusercontent.com/media/research.google.com/en//archive/bigtable-osdi06.pdf" rel="noopener noreferrer"&gt;Bigtable: A Distributed Storage System for Structured Data&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;13.&lt;a href="https://www.youtube.com/watch?v=LVV_93mBfSU" rel="noopener noreferrer"&gt;The Internet: How Search Works&lt;/a&gt;&lt;/p&gt;

</description>
      <category>google</category>
      <category>searchengines</category>
      <category>cloudcomputing</category>
      <category>distrubutedsystems</category>
    </item>
    <item>
      <title>Netflix System Design- Backend Architecture</title>
      <dc:creator>Daniel Elegberun</dc:creator>
      <pubDate>Thu, 24 Jun 2021 08:09:38 +0000</pubDate>
      <link>https://forem.com/gbengelebs/netflix-system-design-backend-architecture-10i3</link>
      <guid>https://forem.com/gbengelebs/netflix-system-design-backend-architecture-10i3</guid>
      <description>&lt;p&gt;&lt;em&gt;Cover Photo by &lt;a href="https://unsplash.com/@alexbemore?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Alexander Shatov&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/netflix?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Netflix accounts for about 15% of the world's internet bandwidth traffic, serving over 6 billion hours of content per month to nearly every country in the world. Building a robust, highly scalable, reliable, and efficient backend system is no small engineering feat, but the ambitious team at Netflix has proven that problems exist to be solved.&lt;/p&gt;

&lt;p&gt;This article analyzes the Netflix system architecture as researched from online sources. Section 1 provides a simplified overview of the Netflix system. Section 2 provides an overview of the backend architecture, and section 3 provides a detailed look at the individual system components. For a complete guide on modern system design, you can try &lt;a href="https://www.educative.io/courses/grokking-modern-system-design-interview-for-engineers-managers" rel="noopener noreferrer"&gt;grokking the modern system design for engineers course.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Overview
&lt;/h2&gt;

&lt;p&gt;Netflix operates in two clouds Amazon Web Services and Open Connect(Netflix content delivery network).&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4rq466utjqzmkvt5jjrz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4rq466utjqzmkvt5jjrz.png" alt="Netflix-High-Level-System-Architecture" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The overall Netflix system consists of three main parts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open Connect Appliances(OCA)&lt;/strong&gt; - Open Connect is Netflix’s custom global content delivery network(CDN). These OCA servers are placed inside internet service providers (ISPs) and internet exchange locations (IXPs) networks around the world to deliver Netflix content to users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Client&lt;/strong&gt; — A client is any device from which you play Netflix videos. This consists of all the applications that interface with the Netflix servers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Netflix supports many different devices, including smart TVs, Android and iOS platforms, gaming consoles, etc. All these apps are written using platform-specific code. The Netflix web app is written using reactJS, which was influenced by several factors, some of which include startup speed, runtime performance, and modularity.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt; - This includes databases, servers, logging frameworks, application monitoring, recommendation engine, background services, etc... When the user loads the Netflix app, all requests are handled by the backend server in AWS Login, recommendations, the home page, users history, billing, customer support. Some of these backend services include (AWS EC2 instances, AWS S3, AWS DynamoDB, Cassandra, Hadoop, Kafka, etc).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Backend Architecture
&lt;/h2&gt;

&lt;p&gt;Netflix is one of the major drivers of microservices architecture. Every component of their system is a collection of loosely coupled services that collaborate. The microservice architecture enables the rapid, frequent, and reliable delivery of large, complex applications. The figure below is an overview of the backend architecture.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuzh1rz679blx2rlhm9da.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuzh1rz679blx2rlhm9da.jpeg" alt="backend" width="720" height="540"&gt;&lt;/a&gt;&lt;/p&gt;
Backend Architecture



&lt;ol&gt;
&lt;li&gt;The Client sends a Play request to a Backend running on AWS. Netflix routes traffic to its services using Amazon's Elastic Load Balancer (ELB) service.&lt;/li&gt;
&lt;li&gt;AWS ELB will forward that request to the API Gateway Service. Netflix uses Zuul as its API gateway, which is built to allow dynamic routing, traffic monitoring, security, and resilience to failures at the edge of cloud deployment.&lt;/li&gt;
&lt;li&gt;The application API component is the core business logic behind Netflix's operations. Several types of API correspond to different user activities, such as the Signup API and the Discovery/Recommendation API for retrieving video recommendations. In this scenario, the forwarded request from the API Gateway Service is handled by the Play API.&lt;/li&gt;
&lt;li&gt;Play API will call a microservice or a sequence of microservices to fulfill the request. &lt;/li&gt;
&lt;li&gt;Microservices are mostly stateless small programs. Thousands of these services can communicate with each other. &lt;/li&gt;
&lt;li&gt;Microservices can save or get data from a data store during this process.&lt;/li&gt;
&lt;li&gt;Microservices can send events to track user activities or other data to the Stream Processing Pipeline for either real-time processing of personalized recommendations or batch processing of business intelligence tasks.&lt;/li&gt;
&lt;li&gt;The Stream Processing Pipeline data can be persistented to other data stores such as AWS S3, Hadoop HDFS, Cassandra, etc.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  3. Backend Components
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Open Connect
&lt;/h3&gt;

&lt;p&gt;Open Connect handles everything that happens after you hit play on a video. This system is responsible for streaming video to your device. The following diagram illustrates how the playback process works.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhdg8io3upt0ioogjvz6v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhdg8io3upt0ioogjvz6v.png" alt="PlayBlackProcess" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;
Open Connect Design Image



&lt;ol&gt;
&lt;li&gt;OCAs ping AWS instances to report their health, the routes they have learned, and the files they have on them.&lt;/li&gt;
&lt;li&gt;A user on a client device requests playback of a title (TV show or movie) from the Netflix application in AWS.&lt;/li&gt;
&lt;li&gt;The Netflix playback service checks for the user's authorization, permission, and licensing, then chooses which files to serve the client taking into account the current network speed and client resolution.&lt;/li&gt;
&lt;li&gt;The steering service picks the OCA from which the files should be served, generates URLs for these OCAs, and hands them back to the playback service.&lt;/li&gt;
&lt;li&gt;The playback service hands over the URLs of the OCA to the client, and the client requests the video files from that OCA.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Zuul2-API GATEWAY
&lt;/h2&gt;

&lt;p&gt;Netflix uses Amazon's Elastic Load Balancer (ELB) service to route traffic to services. ELBs are set up such that the load is balanced across zones first, then instances.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvb4u8c24qg9ftca8qgp9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvb4u8c24qg9ftca8qgp9.png" alt="AmazonELB" width="588" height="550"&gt;&lt;/a&gt;&lt;/p&gt;
Amazon Elastic Load Balancer



&lt;p&gt;This load balancer routes requests to the API gateway service; Netflix uses Zuul as its API gateway; it handles all the requests and performs the dynamic routing of microservice applications. It works as a front door for all the requests.&lt;/p&gt;

&lt;p&gt;For Example, /api/products is mapped to the product service, and /api/user is mapped to the user service. The Zuul Server dynamically routes the requests to the respective backend applications. Zuul provides a range of different types of filters that allow them to quickly and nimbly apply functionality to the edge service. &lt;/p&gt;

&lt;blockquote&gt;The Cloud Gateway team at Netflix runs and operates more than 80 clusters of Zuul 2, sending traffic to about 100 (and growing) backend service clusters which amount to more than 1 million requests per second. 
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://netflixtechblog.com/open-sourcing-zuul-2-82ea476cb2b3" rel="noopener noreferrer"&gt;open-sourcing-zuul-2&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqkjl4fb94l51dx0qsbj3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqkjl4fb94l51dx0qsbj3.png" alt="zuul2" width="800" height="661"&gt;&lt;/a&gt;&lt;/p&gt;
Zuul Architecture



&lt;p&gt;The Netty handlers on the front and back of the filters are mainly responsible for handling the network protocol, web server, connection management, and proxying work. With those inner workings abstracted away, the filters do all the heavy lifting. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The inbound filters run before proxying the request and can be used for authentication, routing, or decorating the request. &lt;/li&gt;
&lt;li&gt;The endpoint filters can either return a static response or proxy the request to the backend service. 
The outbound filters run after a response has been returned and can be used to add or remove custom headers or metrics.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Zuul 2 Api gateway forwards the request to the appropriate Application API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Application API
&lt;/h2&gt;

&lt;p&gt;Currently, the Application APIs are defined under three categories: &lt;strong&gt;Signup API&lt;/strong&gt; -for non-member requests such as sign-up, billing, free trial, etc., &lt;strong&gt;Discovery API&lt;/strong&gt;-for search, recommendation requests, and &lt;strong&gt;Play API&lt;/strong&gt;- for streaming, view licensing requests, etc. When a user clicks signup, for example, Zuul will route the request to the Signup API. &lt;/p&gt;

&lt;p&gt;If you consider an example of an already subscribed user. Supposing the user clicks on play for the latest episode of Peaky Blinders, the request will be routed to the playback API. The API, in turn, calls several microservices under the hood. Some of these calls can be made in parallel because they don’t depend on each other. Others have to be sequenced in a specific order. The API contains all the logic to sequence and parallelize the calls as necessary. The device, in turn, doesn’t need to know anything about the orchestration that goes on under the hood when the customer clicks “play.”&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk298u17sizjb8ib7xg65.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk298u17sizjb8ib7xg65.jpeg" alt="Api archi" width="474" height="510"&gt;&lt;/a&gt;&lt;/p&gt;
Netflix API Architecture



&lt;p&gt;Signup requests map to signup backend services, Playback requests, with some exceptions, map only to playback backend services, and similarly, discovery APIs map to discovery services.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hystrix- Distributed API Services Management
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://netflix.github.io/titus/" rel="noopener noreferrer"&gt;Hystrix&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ry3q3t2vizu7o55ixg3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ry3q3t2vizu7o55ixg3.png" alt="Hystrix" width="800" height="511"&gt;&lt;/a&gt;&lt;/p&gt;
Hystrix Architecture



&lt;p&gt;In any distributed environment (with a lot of dependencies), inevitably, some of the many service dependencies will fail. It can be unmanageable to monitor the health and state of all the services as more and more services will be stood up, and some services may be taken down or simply broken down. Hystrix comes with help by providing a user-friendly dashboard. &lt;strong&gt;Hystrix library&lt;/strong&gt; is used to control the interaction between these distributed services by adding some latency tolerance and fault tolerance logic. &lt;/p&gt;

&lt;p&gt;Consider this example from Netflix: They have a microservice that provides a tailored list of movies back to the user. If the service fails, they reroute the traffic to circumvent the failure to another vanilla microservice that simply returns the top 10 family-friendly movies. So they have this safe failover that they can go to, and that is the classic example of the first circuit breaking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;/p&gt;
&lt;blockquote&gt;
&lt;em&gt;Netflix Hystrix is no longer in active development and is currently in maintenance mode. Some internal projects are currently being built with resilience4j&lt;/em&gt;&lt;br&gt;
&lt;/blockquote&gt;
&lt;br&gt;
&lt;a href="https://github.com/resilience4j/resilience4j" rel="noopener noreferrer"&gt;https://github.com/resilience4j/resilience4j&lt;/a&gt;
&lt;h3&gt;
  
  
  Titus- Container Management
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://netflix.github.io/titus/" rel="noopener noreferrer"&gt;Titus&lt;/a&gt;&lt;br&gt;
Titus is a container management platform that provides scalable and reliable container execution and cloud-native integration with Amazon AWS.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2k22xkjv5ed0vbc69oay.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2k22xkjv5ed0vbc69oay.png" alt="titus-arch" width="351" height="334"&gt;&lt;/a&gt;&lt;/p&gt;
Titus Architecture



&lt;p&gt;It is a framework on top of Apache Mesos, a cluster management system that brokers available resources across a fleet of machines.&lt;br&gt;
Titus is run in production at Netflix, managing thousands of AWS EC2 instances and launching hundreds of thousands of containers daily for both batch and service workloads. Just think of it as the Netflix version of Kubernetes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Titus runs about 3 million containers per week.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Datastores
&lt;/h2&gt;

&lt;h3&gt;
  
  
  EVCache
&lt;/h3&gt;

&lt;p&gt;A cache's primary purpose is to increase data retrieval performance by reducing the need to access the underlying slower storage layer. Trading off capacity for speed, a cache typically stores a subset of data transiently.&lt;br&gt;
&lt;a href="https://github.com/Netflix/EVCache" rel="noopener noreferrer"&gt;EVCache&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two use cases for caching is to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provides fast access to frequently stored data.&lt;/li&gt;
&lt;li&gt;Provides fast access to computed(memoized) data. Netflix's microservices rely on caches for fast, reliable access to multiple types of data like a member’s viewing history, ratings, and personalized recommendations. 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9e65uku3fk6jvgpjdsfp.png" alt="EVCache" width="800" height="524"&gt;EVCache Diagram

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;EVCache is a Memcached and spymemcached-based caching solution mainly used for caching frequently used data on AWS EC2 infrastructure.&lt;br&gt;
EVCache is an abbreviation for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ephemeral - The data stored is for a short duration as specified by its TTL (Time To Live).&lt;/li&gt;
&lt;li&gt;Volatile - The data can disappear at any time (Evicted).&lt;/li&gt;
&lt;li&gt;Cache - An in-memory key-value store.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  SSDs for Caching
&lt;/h3&gt;

&lt;p&gt;Traditionally, caching is done on RAM. Storing large amounts of data on RAM is expensive, so Netflix decided to move some caching data to SSD. &lt;/p&gt;

&lt;blockquote&gt; Modern disk technologies based on SSD are providing fast access to data but at a much lower cost when compared to RAM. The cost to store 1 TB of data on SSD is much lower than storing the same amount using RAM.
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://netflixtechblog.com/evolution-of-application-data-caching-from-ram-to-ssd-a33d6fa7a690" rel="noopener noreferrer"&gt;Evolution of application Data Caching&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  MySQL
&lt;/h3&gt;

&lt;p&gt;Netflix uses AWS EC2 instances of MYSQL for its Billing infrastructure. Billing infrastructure is responsible for managing Netflix members' billing states. This includes keeping track of open/paid billing periods, the amount of credit on the member’s account, managing the member's payment status, initiating charge requests, and what date the member has paid through.&lt;/p&gt;

&lt;p&gt;The payment processor needed the ACID capabilities of an RDBMS to process charge transactions.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2cdd1qpqbl3ckw6ebyn4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2cdd1qpqbl3ckw6ebyn4.png" alt="Netflix Datastore" width="800" height="510"&gt;&lt;/a&gt;&lt;/p&gt;
Netflix Datastore



&lt;h3&gt;
  
  
  Apache Cassandra
&lt;/h3&gt;

&lt;p&gt;Cassandra is a free and open-source distributed wide-column store. The NoSQL database is designed to handle large amounts of data across many commodity servers, providing high availability with no single point of failure.&lt;/p&gt;

&lt;p&gt;Netflix uses Cassandra for its scalability, lack of single points of failure, and cross-regional deployments. ” In effect, a single global Cassandra cluster can simultaneously service applications and asynchronously replicate data across multiple geographic locations.&lt;/p&gt;

&lt;p&gt;Netflix stores all kinds of data across its Cassandra DB instances, including all user-collected event metrics. &lt;/p&gt;

&lt;p&gt;As user data began to increase, there needed to be a more efficient way to manage data storage. Netflix Redesigned data storage architecture with two main goals in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Smaller Storage Footprint.&lt;/li&gt;
&lt;li&gt;Consistent Read/Write Performance as viewing per member grows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The solution to the large data problem was to compress the old rows. Data were divided into two types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live Viewing History (LiveVH): Small number of recent viewing records with frequent updates. The data is stored in uncompressed form.&lt;/li&gt;
&lt;li&gt;Compressed Viewing History (CompressedVH): A large number of older viewing records with rare updates. The data is compressed to reduce the storage footprint. Compressed viewing history is stored in a single column per row key.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8w132e8676mx2xzmti5x.png" alt="CompressedVH" width="720" height="407"&gt;Compressed Viewing History

&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Stream Processing Pipeline
&lt;/h2&gt;

&lt;p&gt;Did you know that Netflix personalizes movie artwork just for you? You might be surprised to learn the image shown for each video is selected specifically for you. Not everyone sees the same image.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6zbpyp23tozgvhsng18z.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6zbpyp23tozgvhsng18z.jpeg" alt="stranger-things" width="500" height="293"&gt;&lt;/a&gt;&lt;br&gt;
Netflix tries to select artwork that highlights the most relevant aspect of a video based on the data it has learned about you, such as your viewing history and interests.&lt;/p&gt;

&lt;p&gt;Stream Processing Data Pipeline has become Netflix’s data backbone of business analytics and personalized recommendation tasks. It is responsible for producing, collecting, processing, aggregating, and moving all microservice events to other data processors in near real-time.&lt;/p&gt;

&lt;blockquote&gt;
Streaming data is data that is generated continuously by thousands of data sources, which typically send in the data records simultaneously and in small sizes (order of Kilobytes). Streaming data includes a wide variety of data such as log files generated by customers using your mobile or web applications, e-commerce purchases, in-game player activity, information from social networks, financial trading floors, or geospatial services, and telemetry from connected devices or instrumentation in data centers.
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/streaming-data/" rel="noopener noreferrer"&gt;AWS- What is streaming Data?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This data needs to be processed sequentially and incrementally on a record-by-record basis or over sliding time windows and used for a wide variety of analytics, including correlations, aggregations, filtering, and sampling. &lt;/p&gt;

&lt;p&gt;Information derived from such analysis gives companies visibility into many aspects of their business and customer activity, such as service usage (for metering/billing), server activity, website clicks, and the geo-location of devices, people, and physical goods, and enables them to respond promptly to emerging situations. For example, businesses can track changes in public sentiment on their brands and products by continuously analyzing social media streams and responding promptly as necessary.&lt;/p&gt;

&lt;p&gt;The stream processing platform processes trillions of events and petabytes of data per day.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfv8wddthnk9m37uf628.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfv8wddthnk9m37uf628.png" alt="streaming" width="562" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Viewing History Service captures all the videos played by members. Beacon is another service that captures all impression events and user activities within Netflix. All the data collected by the Viewing History and Beacon services is sent to Kafka.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apache Kafka- Analyzing Streaming Data
&lt;/h3&gt;

&lt;p&gt;Kafka is open-source software that provides a framework for storing, reading, and analyzing streaming data.&lt;/p&gt;

&lt;blockquote&gt;Netflix embraces Apache Kafka® as the de-facto standard for its eventing, messaging, and stream processing needs. Kafka acts as a bridge for all point-to-point and Netflix Studio-wide communications. 
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.confluent.io/blog/how-kafka-is-used-by-netflix/" rel="noopener noreferrer"&gt;How Netflix uses Kafka&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F78gmjgardflv97rrwxyj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F78gmjgardflv97rrwxyj.png" alt="Kafka" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Apache Chukwe- Analyzing Streaming Data
&lt;/h3&gt;

&lt;p&gt;Apache Chukwe is an open-source data collection system that collects logs or events from a distributed system. It is built on top of HDFS and Map-reduce framework. It comes with Hadoop’s scalability and robustness features. It includes a lot of powerful and flexible toolkits to display, monitor, and analyze data. Chukwe collects the events from different parts of the system; From Chukwe, you can do monitoring and analysis, or you can use the dashboard to view the events. Chukwe writes the event in the Hadoop file sequence format (S3).&lt;/p&gt;

&lt;h3&gt;
  
  
  Apache Spark - Analyzing Streaming Data
&lt;/h3&gt;

&lt;p&gt;Netflix uses Apache Spark and Machine learning to recommend movies. Apache Spark is an open-source unified analytics engine for large-scale data processing. &lt;/p&gt;

&lt;p&gt;On a live user request, the aggregated play popularity(how many times a video is played) and take rate(Fraction of play events over impression events for a given video) data, along with other explicit signals such as members’ viewing history and past ratings, are used to compute personalized content for the user. The following figure shows the end-to-end infrastructure for building user movie recommendations.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3335yl4ojj3h2fyn95hx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3335yl4ojj3h2fyn95hx.png" alt="data-processor-engine" width="619" height="292"&gt;&lt;/a&gt;&lt;/p&gt;
Data Processing Engine



&lt;h3&gt;
  
  
  Elastic Search - Error Logging and Monitoring
&lt;/h3&gt;

&lt;p&gt;Netflix uses elastic search for data visualization, customer support, and error detection in the system.&lt;/p&gt;

&lt;p&gt;Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.&lt;/p&gt;

&lt;p&gt;With elastic search, they can easily monitor the state of the system and troubleshoot error logs and failures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This article provides a detailed analysis of the Netflix Backend architecture. To test your knowledge of Netflix system design, try out this interactive &lt;a href="https://www.educative.io/courses/grokking-modern-system-design-interview-for-engineers-managers/quiz-on-netflixs-design" rel="noopener noreferrer"&gt;Quiz on Netflix's Design&lt;/a&gt;. For more information, refer to the references in the section below. &lt;/p&gt;

&lt;p&gt;If you're looking for a detailed guide to system design, check out this &lt;a href="https://www.educative.io/blog/how-to-prepare-system-design-interview" rel="noopener noreferrer"&gt;system design interview prep&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Follow me here and across my social media for more content like this &lt;a href="https://www.linkedin.com/in/olugbenga-elegberun/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;. &lt;a href="https://twitter.com/ElegberunDaniel?s=09" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  REFERENCES
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://netflix.github.io/titus/overview/" rel="noopener noreferrer"&gt;Titus&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://netflixtechblog.com/open-sourcing-zuul-2-82ea476cb2b3" rel="noopener noreferrer"&gt;Open Sourcing Zuul&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openconnect.netflix.com/Open-Connect-Overview.pdf" rel="noopener noreferrer"&gt;Open Connect&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nexsoftsys.com/articles/how-netflix-backend-system-operates.html" rel="noopener noreferrer"&gt;How Netflix Backend Operates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/swlh/a-design-analysis-of-cloud-based-microservices-architecture-at-netflix-98836b2da45f" rel="noopener noreferrer"&gt;A Design Analysis Of Cloud-Based Microservices Architecture At Netflix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@narengowda/netflix-system-design-dbec30fede8d" rel="noopener noreferrer"&gt;Netflix System Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://riteeksrivastava.medium.com/hystrix-what-is-it-and-why-is-it-used-f84614c8df5e" rel="noopener noreferrer"&gt;Hystrix What is it and Why is it Used&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://netflixtechblog.com/engineering-trade-offs-and-the-netflix-api-re-architecture-64f122b277dd" rel="noopener noreferrer"&gt;Engineering Tradeoffs and the Netflix API Re-architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://netflixtechblog.com/application-data-caching-using-ssds-5bf25df851ef" rel="noopener noreferrer"&gt;Application Data Caching Using ssds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://netflixtechblog.com/evolution-of-application-data-caching-from-ram-to-ssd-a33d6fa7a690" rel="noopener noreferrer"&gt;Evolution Of Application Data Caching From Ram To ssd&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://netflixtechblog.com/netflix-billing-migration-to-aws-451fba085a4" rel="noopener noreferrer"&gt;Netflix Billing Migration To Aws&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://netflixtechblog.com/optimizing-the-netflix-api-5c9ac715cf19" rel="noopener noreferrer"&gt;Optimizing The Netflix Api&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://netflixtechblog.com/whats-trending-on-netflix-f00b4b037f61" rel="noopener noreferrer"&gt;What's Trending On Netflix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://netflixtechblog.com/evolution-of-the-netflix-data-pipeline-da246ca36905" rel="noopener noreferrer"&gt;Evolution Of The Netflix Data Pipeline&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.javatpoint.com/zuul-api-gateway" rel="noopener noreferrer"&gt;Zuul API Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/CAP_theorem" rel="noopener noreferrer"&gt;CAP_theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://highscalability.com/blog/2017/12/11/netflix-what-happens-when-you-press-play.html?currentPage=2" rel="noopener noreferrer"&gt;What Happens When You Press Play&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://netflixtechblog.com/scaling-time-series-data-storage-part-i-ec2b6d44ba39" rel="noopener noreferrer"&gt;Scaling Time Series Data Storage Part1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.geeksforgeeks.org/system-design-netflix-a-complete-architecture/" rel="noopener noreferrer"&gt;Netflix-High-Level-System-Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.confluent.io/blog/how-kafka-is-used-by-netflix/" rel="noopener noreferrer"&gt;How-Kafka-is-used-by-Netflix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fortune.com/2018/10/02/netflix-consumes-15-percent-of-global-internet-bandwidth/#:~:text=When%20it%20comes%20to%20devouring,to%2019.1%25%20of%20total%20traffic." rel="noopener noreferrer"&gt;Netflix Consumes 15% of the World's Internet Bandwidth&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.educative.io/blog/top-10-system-design-interview-questions" rel="noopener noreferrer"&gt;Top 14 System Design interview questions for software engineers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.educative.io/courses/grokking-modern-system-design-interview-for-engineers-managers/quiz-on-netflixs-design" rel="noopener noreferrer"&gt;Quiz on Netflix System Design&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>openconnect</category>
      <category>systemdesign</category>
      <category>netflixbackend</category>
      <category>aws</category>
    </item>
    <item>
      <title>Netflix System Design- How Netflix Onboards New Content</title>
      <dc:creator>Daniel Elegberun</dc:creator>
      <pubDate>Tue, 15 Jun 2021 16:49:43 +0000</pubDate>
      <link>https://forem.com/gbengelebs/netflix-system-design-how-netflix-onboards-new-content-2dlb</link>
      <guid>https://forem.com/gbengelebs/netflix-system-design-how-netflix-onboards-new-content-2dlb</guid>
      <description>&lt;blockquote&gt;In the battle for the Game of Attention, content is the two-edged sword and user experience is the horse that leads it to battle.
&lt;/blockquote&gt;

&lt;p&gt;The streaming wars are in full blast with Netflix positioned for continual dominance, armed with over 50,000 individual titles, 200million subscribers in 180+ countries, even more impressive is the underlying technology powering this growth. In this series, my goal is to scratch more than the surface of how Netflix operates, digging deeper into the technicalities of the end-to-end processes involved in delivering content at scale. In the maiden edition of this series, I focus on the Netflix content onboarding system and open connect.&lt;br&gt;
This diagram shows an overview of the system we will be discussing in this article.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi2gmvjmu55vflk3a5wpa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi2gmvjmu55vflk3a5wpa.png" alt="Netflixsysdesign" width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Content Content Content.
&lt;/h2&gt;

&lt;p&gt;Netflix has a combined library of over 50,000 titles, supporting over 2200 devices, each device with its resolution and network speed. For them to be able to serve that many devices at different Network speeds they need to have the original video in different formats. Netflix receives the video from the production houses in the best possible format. The thing is the videos from the production houses are large, very large. For a commercial blu ray 2hr movie, you're looking at 15-25Gb. Serving this to users in that format will consume data and bandwidth, So Netflix performs a series of preprocessing on the original videos to convert them into different file formats. These preprocessing are referred to as Encoding and Transcoding. &lt;/p&gt;

&lt;p&gt;Encoding is the process of compressing video and audio files to be compatible with a single target device. Transcoding, on the other hand, allows for already encoded data to be converted to another encoding format.(MP4,WLM,MOV,MPEG-4) This process is particularly useful when users use multiple target devices, such as different mobile phones and web browsers, that do not all support the same native formats or have limited storage capacity.&lt;br&gt;
The reasons for this preprocessing are fairly simple.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduce file size.&lt;/li&gt;
&lt;li&gt;Reduce buffering for streaming video.&lt;/li&gt;
&lt;li&gt;Change resolution or aspect ratio.&lt;/li&gt;
&lt;li&gt;Change audio format or quality.&lt;/li&gt;
&lt;li&gt;Convert obsolete files to modern formats.&lt;/li&gt;
&lt;li&gt;Make a video compatible with a certain device (computer, tablet, smartphone, smartTV, legacy devices).&lt;/li&gt;
&lt;li&gt;Make a video compatible with certain software or service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compressing a 25Gb movie will take a lot of time, to solve this problem. Netflix breaks the original video into different smaller chunks and using parallel workers in AWS EC2, it performs encoding and transcoding on these chunks converting them into different formats (MP4, MOV, etc) across different resolutions(4k, 1080p, and more).&lt;/p&gt;

&lt;p&gt;Netflix also creates multiple replicas of the same video chunk to cater to different network speeds. About 1300 replicas of a video chunk.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;-High Quality ------4K,1080p,720p,360p&lt;br&gt;
-Medium Quality ------4K,1080p,720p,360p&lt;br&gt;
-Low Quality ------4K,1080p,720p,360p&lt;/p&gt;

&lt;p&gt;Netflix stores all these processed video data on Amazon S3.Which is a highly scalable and available storage platform for storing static data. Each video file is stored in &lt;em&gt;chunks of scenes&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;Netflix uses AWS for nearly all its computing and storage needs, including databases, analytics, recommendation engines, video transcoding, and more—hundreds of functions that in total use more than 100,000 server instances on AWS.
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/solutions/case-studies/netflix/#:~:text=Netflix%20on%20AWS&amp;amp;text=Netflix%20uses%20AWS%20for%20nearly,100%2C000%20server%20instances%20on%20AWS" rel="noopener noreferrer"&gt;https://aws.amazon.com/solutions/case-studies/netflix&lt;/a&gt;&lt;br&gt;
By default, most chunks are 10 seconds of video. Each time you skip to different parts of a movie you are querying Netflix's Playback API for different video chunks. You usually have one chunk actively playing, one chunk ready to play when the current chunk is done, and one chunk downloaded. This is done to deliver a seamless watch experience to the user and maximize the best possible speed at that moment.&lt;/p&gt;

&lt;p&gt;The speed at which these chunks arrive determines the bit rate(bit rate refers to the number of bits used per second) of the following chunks.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp5q1gfcu33do0bogozcx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp5q1gfcu33do0bogozcx.png" alt="Bitrate" width="227" height="222"&gt;&lt;/a&gt;&lt;br&gt;
If the first one takes longer than the chunk’s playback duration, it grabs the next lower bitrate chunk for the following one. If it comes faster, it will go for a higher resolution chunk if one is available. That's why sometimes your video resolution can be grainy at first and then adjust to a better definition.&lt;/p&gt;

&lt;p&gt;Netflix has users in over 200 countries. If a user in Nigeria wants to watch a movie on an amazon instance hosted in America. The internet service providers will need to travel to America to access those servers which will take time and bandwidth. In an era where fractional delays in serving content can lead to declines in revenue, it is paramount that users get access to the content fast. Netflix solved this problem by creating mini servers inside ISPs and IXP(internet exchange points) known as open connect. These boxes are capable of storing 280 terabytes of data. After the videos have been compressed and transcoded on Amazon S3 they are then transferred to these open connect boxes during an off-peak period (Let's say 4 am). When the user requests for a video instead of hitting Netflix servers directly in the US. It hits the open connect boxes. This ensures less bandwidth, faster playtime, and ultimately a better user experience. Movies can also be localized depending on the region. You could store different movies on the open connect appliances in  Nigeria and Brazil. About 90% of Netflix content is served this way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Connect
&lt;/h2&gt;

&lt;p&gt;A CDN is a geographically distributed group of services that work together to provide fast delivery of internet content. Open Connect is Netflix’s custom global content delivery network (CDN).&lt;br&gt;
Everything that happens after you hit play on a video is handled by Open Connect.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open Connect stores Netflix video in different locations throughout the world. When you press play the video streams from Open Connect, into your device.&lt;/li&gt;
&lt;li&gt;Netflix has been in partnership with Internet Service Providers (ISPs) and Internet Exchange Points (IXs or IXPs) around the world to deploy specialized devices called Open Connect Appliances (OCAs) inside their network.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5rgl0964x0q8bt8lyq7o.png" alt="Open Connect" width="800" height="427"&gt;Open Connect Design Image from &lt;a href="https://openconnect.netflix.com/Open-Connect-Overview.pdf" rel="noopener noreferrer"&gt;Netflix&lt;/a&gt;

&lt;/li&gt;
&lt;li&gt;These servers periodically report health metrics optimal routes they learned from IXP/ISP networks and what videos they store on their SSD disks to Open Connect Control Plane services on AWS.&lt;/li&gt;
&lt;li&gt;When new video files have been transcoded successfully and stored on AWS S3, the control plane services on AWS will transfer these files to OCAs servers on IXP sites. These OCAs servers will apply cache fill to transfer these files to OCAs servers on ISP's sites under their sub-networks.&lt;/li&gt;
&lt;li&gt;When an OCA server has successfully stored the video files, it will be able to start the peer fill to copy these files to other OCAs servers within the same site if needed.&lt;/li&gt;
&lt;li&gt;Between 2 different sites which can see each other's IP address, the OCAs can apply the tier fill process instead of a regular cache fill.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7izxd85vxw5dyiumvwtm.png" alt="Alt Text" width="800" height="608"&gt;Open Connect Transfering content from &lt;a href="https://openconnect.netflix.com/Open-Connect-Overview.pdf" rel="noopener noreferrer"&gt;Netflix&lt;/a&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In summary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Netflix performs compression and transcoding of the original video file.&lt;/li&gt;
&lt;li&gt;The file is split into chunks using parallel workers in AWS for faster processing.&lt;/li&gt;
&lt;li&gt;Each chunk is subdivided across several resolutions and internet speeds.&lt;/li&gt;
&lt;li&gt;These chunks are stored on Amazon S3.&lt;/li&gt;
&lt;li&gt;During the off-peak period. The files are transferred to open connect boxes, which is Netflix's custom content delivery network spread out across the world.&lt;/li&gt;
&lt;li&gt;These boxes are capable of communicating and sharing content between themselves.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the next part of the series, I will be explaining Netflix's core backend architecture. &lt;br&gt;
Follow me here and across my social media for more content like this &lt;a href="https://twitter.com/ElegberunDaniel?s=09" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; &lt;a href="https://www.linkedin.com/in/olugbenga-elegberun/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt; &lt;/p&gt;

</description>
      <category>netflix</category>
      <category>systemdesign</category>
      <category>openconnect</category>
      <category>aws</category>
    </item>
    <item>
      <title>Introduction To Solidity</title>
      <dc:creator>Daniel Elegberun</dc:creator>
      <pubDate>Mon, 07 Jun 2021 16:18:18 +0000</pubDate>
      <link>https://forem.com/gbengelebs/introduction-to-solidity-228c</link>
      <guid>https://forem.com/gbengelebs/introduction-to-solidity-228c</guid>
      <description>&lt;p&gt;In the previous article we discussed about smart contracts and tokens. In this article I will be taking a look at solidity the language for programming smart contracts. Solidity is a high-level programming language designed for implementing smart contracts. It is statically-typed object-oriented(contract-oriented) language. Solidity is highly influenced by Python, c++, and JavaScript which runs on the Ethereum Virtual Machine(EVM). In this article we will provide an introduction into the solidity language.&lt;/p&gt;

&lt;p&gt;The first thing we need is an IDE to write our solidity code. One of the most popular development environments for programming solidity is the Remix IDE and it is what we will be using in this tutorial. Luckily we can access it online &lt;a href="https://remix.ethereum.org/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  .SOL
&lt;/h2&gt;

&lt;p&gt;Solidity Files are saved with the .sol extension to indicate that it is a solidity file.&lt;/p&gt;

&lt;h2&gt;
  
  
  PRAGMA
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;- The first line of a solidity file is the pragma statement. It indicates the solidity version that is being used. It helps ensure compatibility in code files.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma solidity ^0.8.2;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  CONTRACT
&lt;/h2&gt;

&lt;p&gt;This keyword is used to create a smart contract. By convention the name of the contract is usually the name of the solidity file. Every function and variable declaration in the file will be encapsulated within the smart contract.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract Test{ 
 Functions and Data 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  VARIABLES
&lt;/h2&gt;

&lt;p&gt;variables are reserved memory locations to store value.&lt;br&gt;
You may like to store information of various data types like character, wide character, integer, floating point, double floating point, boolean etc. Based on the data type of a variable, the operating system allocates memory and decides what can be stored in the reserved memory.&lt;br&gt;
examples of variables are-- integer,string,bool.&lt;/p&gt;
&lt;h2&gt;
  
  
  ADDRESS
&lt;/h2&gt;

&lt;p&gt;This is a variable type that holds the 20 byte value representing the size of an Ethereum address.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; address x = 0x212;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  MAPPING -
&lt;/h2&gt;

&lt;p&gt;A mapping holds a reference to a value. Below is the syntax. They act as hash tables which consist of key types and corresponding value type pairs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mapping(_KeyType =&amp;gt; _ValueType)

mapping(address =&amp;gt; uint) public balances;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This maps the address variable as a key to an integer variable and assigns the mapping to a public variable called balances.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5iu42j3qxdheb02lf1m8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5iu42j3qxdheb02lf1m8.png" alt="mapping" width="429" height="329"&gt;&lt;/a&gt;&lt;/p&gt;
https://medium.com/upstate-interactive/mappings-in-solidity-explained-in-under-two-minutes-ecba88aff96e



&lt;p&gt;We can assign a value to a key adress like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;balances[keyAddress] =  value;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Solidity supports. State,local and global variables.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;State Variables − Variables whose values are permanently stored in a contract storage.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract SolidityTest {
   uint storedData;      // State variable
   constructor() public {
      storedData = 10;   // Using State variable
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we declared an integer variable called storedData. And we assign a value to it in the constructor of the contract.This value will be available throughout the contract context.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Local Variables − Variables whose values are present only within a function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Global Variables − Special variables exists in the global namespace used to get information about the blockchain. Common Examples are :&lt;br&gt;
block.coinbase (address payable)     which returns Current block miner's address. See the list of variables here&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0o9s8rwyhpwzmuixp0rz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0o9s8rwyhpwzmuixp0rz.png" alt="GlobalVariables" width="800" height="740"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
Image Source [TutorialPoint](https://www.tutorialspoint.com/solidity/solidity_variables.htm)



&lt;h2&gt;
  
  
  FUNCTION
&lt;/h2&gt;

&lt;p&gt;A function is a group of resuable code that can be used anywhere in your application. They perform a specific task. The most common way to define a function in Solidity is by using the function keyword, followed by a unique function name, a list of parameters (that might be empty), and a statement block surrounded by curly braces.&lt;/p&gt;

&lt;p&gt;Functions can be specified as being external, public, internal or private, where the default is public.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Public: Public functions are part of the contract interface and can be either called internally or via messages.&lt;/li&gt;
&lt;li&gt;Internal: Those functions and state variables can only be accessed internally (i.e. from within the current contract or contracts deriving from it).&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Private: Private functions and state variables are only visible for the contract they are defined in and not in derived contracts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functions can be declared &lt;em&gt;view&lt;/em&gt; in which case they promise not to modify the state. &lt;strong&gt;Read only functions&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function function-name(parameter-list) scope returns() {
   //statements
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract BlogDemo {
   function addNumbers() public view returns(uint){
      uint a = 1; // local variable
      uint b = 2;
      uint result = a + b;
      return result;
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example we named our function addNumbers, it is declared as public view Which means it does not modify any contract state, It just adds two numbers together.It returns an integer and it does not take in any parameters.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;function with multiple return Parameters.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract BlogDemo {
   function addNumbers() public view returns(uint sum, uint product){
      uint a = 1; // local variable
      uint b = 2;
      sum = a + b;
      product = a * b;    
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function will return both the product and sum.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;require keyword.
The require keyword in a Solidity function guarantees validity of conditions that cannot be detected before execution. It checks inputs, contract state variables and return values from calls to external contracts. If I wanted to execute a function only if a particular condition is met, I add the required keyword.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract BlogDemo {
uint value1 = 5;
uint value2 = 4;

function addNumbers() public view returns(uint sum, uint product){
    require(  value1 &amp;gt; value2 ,'5 is not greater than 4')
      uint a = 1; // local variable
      uint b = 2;
      sum = a + b;
      product = a * b;    
   }
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function will only execute if value1 is greater than value 2. if the condition is not met It will return the error message ('5 is not greater than 4'). &lt;/p&gt;

&lt;h2&gt;
  
  
  Modifiers
&lt;/h2&gt;

&lt;p&gt;Modifier allow control to the behaviour of a function. They can be used in a vareity of scenarios. Like for example checking who has access to a function before executing that function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract Test {
  address testAddress;
  constructor() {
    testAddress = msg.sender;
  }

  // Check if the function is called by the owner of the contract
  modifier onlyOwner() {
      if (msg.sender == testAddress) {
         _;
      }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function body is inserted where the special symbol "_;" appears in the definition of a modifier. So if condition of modifier is satisfied while calling this function, the function is executed and otherwise, an exception is thrown.&lt;/p&gt;

&lt;p&gt;We can then use this function modifier as a condition checker in other functions. For example to only execute the function if it is called by the sender.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  // Can only be called by the owner cause I am using the onlyOwner modifier
  function test() public onlyOwner {
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Constructors
&lt;/h2&gt;

&lt;p&gt;A constructor is an optional function declared with the constructor keyword which is executed only upon contract creation. Constructor functions can be either public or internal. If there is no constructor, the contract will assume the default constructor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contructor() public {}
contract SolidityTest {
   uint storedData;      // State variable
   constructor() public {
      storedData = 10;   // Using State variable
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Events.
&lt;/h2&gt;

&lt;p&gt;An event stores arguments passed to it in the transaction logs of the blockchain. If you want to store something like transfer information. You could do so using an event.&lt;/p&gt;

&lt;h2&gt;
  
  
  Event Syntax
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;event Transfer(address indexed from, address indexed to, uint _value);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To write to an event. You &lt;em&gt;emit&lt;/em&gt; that event. To write to event Transfer. I emit it using the following syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Emit an event
emit Transfer(msg.sender, receiverAddress, msg.value);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this article we have explained some common syntax and terms in the solidity language. In the next article in the series we will be building our own smart contract using solidity and deploying to the Binance Smart Chain. &lt;/p&gt;

&lt;p&gt;Follow me here and across my social media for more content like this &lt;a href="https://twitter.com/ElegberunDaniel?s=09" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; &lt;a href="https://www.linkedin.com/in/olugbenga-elegberun/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt; &lt;/p&gt;

</description>
      <category>solidity</category>
      <category>etherum</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>An Introduction to Cryptocurrency Tokens</title>
      <dc:creator>Daniel Elegberun</dc:creator>
      <pubDate>Mon, 31 May 2021 17:06:02 +0000</pubDate>
      <link>https://forem.com/gbengelebs/an-introduction-to-cryptocurrency-tokens-2chf</link>
      <guid>https://forem.com/gbengelebs/an-introduction-to-cryptocurrency-tokens-2chf</guid>
      <description>&lt;p&gt;Hey👀!.Ever thought of creating your own currency?. With your name,identity and stuff?. Well you can(kinda🤫)One of the best ways to learn about the inner workings of the Cryptocurrency universe is to build your very own token. If you are new to cryptocurrency, you can check out my previous article where I demistify blockchain and cryptocurrency.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is part 1 of a 3 part series on building our your token on the Binance Smart Blockchain with Solidity.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Before we proceed we must differentiate between a cyptocurrency and a token. The main difference being that a cryptocurrency is the native currency of a blockchain network whereas tokens are built ontop an existing blockchain.&lt;/p&gt;

&lt;p&gt;Etherum and bitcoin like other crypto currencies allow you to transfer and trade digital currencies. Some cyptocurrencies like Etherum took it one step further.  Ethereum introduced an Etherum Virtual Machine(EVM) which enables developers to create and launch code which runs on the etherum decentralized network. This code is often referred to as a Smart contract.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Etherum is not the only block chain that allows smart contracts just one of the most popular,other ones exist such as the Binance smart chain.&lt;/em&gt;&lt;br&gt;
Etherum Virtual Machines allows nodes to store and process data in exchange for payment. This Payment is usually in the form of (Ether) which is the native currency of the Etherum Block Chain. The smart contract integration opened up blockchain to a myriad of opportunities and industries. Popular use cases are Decentralized finance, Logistics and Supply chain,Real-time IoT operating systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Lets say, I have a voting App where users can vote for their favourite footballer using a token I created lets call it (vtokens). The more vtokens a player has the higher the rating. Users of my app can transfer vtokens  with each other and also use vtokens to vote for their favourite player. &lt;/p&gt;

&lt;p&gt;Daniel a user of my app wants to send 5,000 vTokens to Lionel Messi, Daniel calls a function inside my Voting App asking it to do so."Please transfer 5000vtokens from adress D to adress LM"&lt;/p&gt;

&lt;p&gt;I want to to use the Etherums Blockchain to store and process the voting information (who voted for who and token transfer between users). &lt;/p&gt;

&lt;p&gt;Even though Daniel isn’t sending ether, He must still pay a fee denominated in (ether) to have his transaction request included in the Etherums blockchain and utilize the blockchains resources to send that token. I  dont want Daniel to go through the stress of also buying ether. I could peg my own vtokens to the ether i.e 20,000 vtokens = 1 Ether. So for every transaction that occurs in my app I could take a percentage of my vtoken convert it to ether which can be used as payment to the Etherum network to help me do work. The more users that want my token, the more my tokens value increases. All this interopability is made possible by "Smart Contracts" which is a self-executing contract with the terms of the agreement between buyer and seller being directly written into lines of code.&lt;/p&gt;

&lt;h2&gt;
  
  
  TOKEN STANDARDS
&lt;/h2&gt;

&lt;p&gt;For two systems to work together they need a common agreement. To create your own token on an existing blockchain you need to follow the token standard. Popular token standards are ERC-20 &amp;amp; BEP-20.&lt;br&gt;
You can think of it as a blueprint for tokens that defines how they can be spent, who can spend them, and other rules for their usage. By following the outline, developers don’t need to reinvent the wheel. Instead, they can build off a foundation already used across the industry.&lt;/p&gt;

&lt;p&gt;For example, To be ERC-20-compliant, your contract needs to include six mandatory functions: totalSupply, balanceOf, transfer, transferFrom, approve, and allowance. In addition, you can specify optional functions, such as name, symbol, and decimal. From their names you might've already deduced what these functions do.  Below are the functions as they appear in the Ethereums Solidity language. Dont worry if you do not understand the code syntax. The next article we will be an introduction into the Solidity Language.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;totalSupply
function totalSupply() public view returns (uint256)
Returns total coin supply in circulation&lt;/li&gt;
&lt;li&gt;balanceOf
function balanceOf(address _owner) public view returns (uint256 balance)
When called, it returns the balance of the specified address’s token holdings.&lt;/li&gt;
&lt;li&gt;transfer
function transfer(address _to, uint256 _value) public returns (bool success)
Transfers tokens from the person calling the smart contracts address to another.&lt;/li&gt;
&lt;li&gt;transferFrom
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
Unlike the regular transfer, in transferFrom you specify the sender  address.It doesnt necesarrily have to be the address of the person calling the smart contract. A good use case is if you want to set up recurring payments using a smart contract. You could transfer the token to an "Admin user" that you created and then authourize that user to transfer the token at specific intervals.&lt;/li&gt;
&lt;li&gt;approve
function approve(address _spender, uint256 _value) public returns (bool success)
With this function, you can limit the number of tokens that a smart contract can withdraw from your balance.&lt;/li&gt;
&lt;li&gt;allowance
function allowance(address _owner, address _spender) public view returns (uint256 remaining)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is used together with the approve function. For example if your smart contract is permitted to withdraw 30tokens and it has withdrawn 20. Calling the allowance should return 10tokens. Basically how many tokens are left for the smart contract to call.&lt;/p&gt;

&lt;p&gt;To create your own token there is an easy and a hard way. Easy way using the cointool app(Very Basic functionality). Hard way programming your smart contract in Solidity.(Endless possiblities). In this article we will be exploring this. But later on in this series we will create our tokens smart contract with solidity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating your own token on Binance Smart Chain
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Download trust wallet app &lt;a href="https://play.google.com/store/apps/details?id=com.wallet.crypto.trustapp&amp;amp;referrer=utm_source%3Dwebsite" rel="noopener noreferrer"&gt;Andriod&lt;/a&gt;&lt;a href="https://apps.apple.com/app/apple-store/id1288339409?pt=1324988&amp;amp;ct=website&amp;amp;mt=8" rel="noopener noreferrer"&gt;ios&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create a token using the coin tool app &lt;a href="https://cointool.app/bnb/bsccreateToken" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqu9psc3bg78m4igsxcco.png" alt="Create Token" width="800" height="439"&gt;
-Specify the token name,symbol,initial supply(How many total tokens you want to create) and decimals.
-Token decimals are an interesting concept. Basically this specifies the lowest unit of your token. Example. 1ETH = 1,000,000,000,000,000,000 wei. 1 Bitcoin = 100,000,000 Satoshis. This means I can own 0.000000000000000001 Eth, OR 0.0000001 BTC. It essentially helps to make our token very divisible.
1.Can Burn- This means the total circulating token can be reduced
2.Can Mint- Means an addtional amount of this token can be "minted"/"created".
3.Can Pause- This specifies whether your token and its associated functions can pause.Maybe due to hacking.
-Click on Connect wallet --&amp;gt; Trust wallet --&amp;gt; BNB Network Chain.
-Logon to your trust wallet --&amp;gt; settings --&amp;gt; Wallet Connect&lt;/li&gt;
&lt;li&gt;Scan the QR code and Approve&lt;/li&gt;
&lt;li&gt;Create token
-The token will be created once you approve this transaction fee.Usually about (0.01)BNB.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0g6imz4rajyha9ec0nwt.png" alt="Token Confirmation" width="800" height="1410"&gt;
&lt;em&gt;Unfortunately i dont have suffiecient BNB to complete this token creation.😑&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  To make it show
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Go to trust wallet&lt;/li&gt;
&lt;li&gt;Click on the two sliders on the top right of the home page
-Scroll down to --&amp;gt; add custom token&lt;/li&gt;
&lt;li&gt;Select Network to Smart chain&lt;/li&gt;
&lt;li&gt;Fill in your network address&lt;/li&gt;
&lt;li&gt;Fill in the rest of the details&lt;/li&gt;
&lt;li&gt;Log out and Login and  see your token.
Congratulations you are now own your token. Start collecting payments to your token address.🤝&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In summary we have learnt &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Cyptocurrency is the native currency of a blockchain whilst a token is build untop an existing block chains network.&lt;/li&gt;
&lt;li&gt; Smart contracts are codes used to execute functions for a given token.&lt;/li&gt;
&lt;li&gt;For a token to be created on a Block chains network it needs to follow the token standards by specifying certain mandatory functions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the part 2 of this article I will be expounding on the solidity language which is used to write smart contracts.&lt;/p&gt;

&lt;p&gt;Follow me here and across my social media for more content like this &lt;a href="https://twitter.com/ElegberunDaniel?s=09" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; &lt;a href="https://www.linkedin.com/in/olugbenga-elegberun/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt; &lt;/p&gt;

</description>
      <category>blockchain</category>
    </item>
    <item>
      <title>Making Sense Of Blockchain And CryptoCurrency</title>
      <dc:creator>Daniel Elegberun</dc:creator>
      <pubDate>Mon, 31 May 2021 16:54:52 +0000</pubDate>
      <link>https://forem.com/gbengelebs/making-sense-of-blockchain-and-cryptocurrency-3kn9</link>
      <guid>https://forem.com/gbengelebs/making-sense-of-blockchain-and-cryptocurrency-3kn9</guid>
      <description>&lt;p&gt;This article is my attempt to make sense of blockchain and cyptocurrency. I will be demystifying blockchain technology and explaining various cryptocurrency lingua franca.&lt;/p&gt;

&lt;h3&gt;
  
  
  WHAT IS BLOCKCHAIN?
&lt;/h3&gt;

&lt;p&gt;A blockchain is an auditable database. A database in which data can only be added but not removed or changed. Data can be periodically added to the database in things called blocks. As the name implies, a series of these blocks chained together is called a Blockchain.&lt;/p&gt;

&lt;h3&gt;
  
  
  WHAT IS CRYPTOCURRENCY?
&lt;/h3&gt;

&lt;p&gt;This is a digital currency in which transactions are verified and records maintained by a decentralized system using cryptography. Combining blockchain and cryptocurrency together. A blockchain is a network of computers (nodes) that run software to confirm the security and validity of (digital currency)on the network. Blockchain is the network and cryptocurrency is what is being spent on the network. Bitcoin is currently the most popular Blockchain and cryptocurrency but other blockchains exist like Etherum with (ether)as the currency being spent on the network.&lt;/p&gt;

&lt;h3&gt;
  
  
  DECENTRALIZED VS CENTRALIZED
&lt;/h3&gt;

&lt;p&gt;Most legacy financial institutions use a centralized system wherein user data is stored and managed by a private entity or group of entities. All users connect to a single source of data in that sense. This sort of relationship is called a centralized network, a major downside to this is that it provides a single point of failure. If the centralized database is wiped out all the data is lost and because a single entity(central bank)has power over the system they can make changes as they please. On the other hand in a decentralized network, data is stored on different nodes(computers)in the network and none of the nodes is managed by a central authority, all of the nodes have to somewhat agree to trust each other, the participating nodes have the exact copy of the database. If one node is down other nodes can provide the data. This provides a redundant and resilient network that ensures high reliability.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does the blockchain work?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr179k43zydzw54hlhlzw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr179k43zydzw54hlhlzw.jpeg" alt="Centralized Vs Decentralized" width="800" height="558"&gt;&lt;/a&gt;&lt;/p&gt;
Centralized Vs Decentralized



&lt;h3&gt;
  
  
  HOW DOES THE BLOCKCHAIN WORK?
&lt;/h3&gt;

&lt;p&gt;Imagine a large hall with briefcases on one end and glass on the other end, each briefcase has a lock and a chain that connects it to the next briefcase. Everyone can see the briefcases through the glass. But only the person who has the key to a briefcase can open it. Supposing I want to transfer money(currency) from my briefcase to yours I will need my key(crypto) to open and sign the transaction. Everyone looking through the glass will see that the transaction belongs to me along with the details of the transaction; as soon as it gets to you, you broadcast to everyone that you have received your money so everyone takes a note of it. After a period of time, someone gathers all these mini transactions and collates them into blocks which are then added to the chain; at a simplistic level, this is how a blockchain works. It is a series of these blocks chained together; It consists essentially of two parts: A Block and a chain. I refer to a block as a collection of transactions and a chain as the linking mechanism which checks if the block's signatures are valid.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;We define a bitcoin as a chain of digital signatures. Each owner transfers bitcoin to the next by digitally signing a hash of the previous transaction and the public key of the next owner and adding these to the end of the coin. A payee can verify the signatures to verify the chain of ownership.&lt;/em&gt;&lt;br&gt;
-Satoshi Nakamoto, Bitcoin Whitepaper&lt;br&gt;
The blockchain is downloaded by all the nodes in the network; when a new block is added to the chain, verification is done to check if the block is valid. If valid, it makes a copy of that block and forwards it to the other nodes in the network till all nodes have that block added to their chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does the blockchain work?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyl27k0ud0vphhv64fdnv.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyl27k0ud0vphhv64fdnv.jpeg" alt="How does the blockchain work" width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;
How does the blockchain work



&lt;h3&gt;
  
  
  WHAT IS CRYPTO MINING?
&lt;/h3&gt;

&lt;p&gt;This process of verifying if a block is valid is done by nodes called miners. Cryptocurrency mining is a term that refers to the process of gathering cryptocurrency as a reward for work that you complete. (This is known as Bitcoin mining when talking about mining Bitcoins specifically.) Whenever transactions are made, all network nodes receive them and verify their validity. Miner nodes go to collect all these transactions from the memory pool and attempts to organize them into blocks. The nodes perform a series of hashing functions (hard mathematical problems)according to preset protocols by that crypto network until it finds a valid hash. When a valid hash is found, the node that finds the hash will broadcast the block to the network. All other nodes will check if the hash is valid and, if so, add the block into their copy of the blockchain. This process of hashing the transactions to form blocks requires a lot of computational power therefore the nodes that perform these hashes are rewarded for their efforts. Nodes can combine together to pool resources so the currency reward is shared amongst them.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13nau2erpkxsu7o8walj.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13nau2erpkxsu7o8walj.jpeg" alt="Mining Farm" width="258" height="195"&gt;&lt;/a&gt;&lt;/p&gt;
Mining Farm



&lt;h2&gt;
  
  
  CONSENSUS ALGORITHM
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Proof Of Work
&lt;/h3&gt;

&lt;p&gt;One of the challenges with distributed systems is ensuring honesty. How do we ensure that each node in the network is honest and the miners of these blocks do not just bring an invalid block without doing the proper work?. The answer can be found in a consensus algorithm. These are a series of algorithm mechanisms that govern miners in a blockchain, all the nodes know this algorithm so they can check for its validity. It is sorta like a lie detector in the chain. It verifies that the hashed block the miner is proposing is valid. If a miner brings forth an invalid hashed block. It would have wasted its computational time, resources, and reputation. If it brings a valid block it gets rewarded in the native coin. This type of consensus algorithm is called proof of work because miners have to prove that they have done the work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Proof Of Stake
&lt;/h3&gt;

&lt;p&gt;In proof of stake instead of sacrificing computation resources nodes sacrifice crypto coins in a process known as staking. A pseudo-random node is selected based on some conditions to forge a new block. The node then stakes a percentage of its coin as a down payment that it's going to forge the block correctly. When the node completes the block It gets rewarded with transaction fees for its work. If it tries to cheat by not forging the block correctly. It loses both its stake and its reputation.&lt;br&gt;
&lt;em&gt;HALVING&lt;/em&gt; is a process where by the reward miners get for mining is reduced. This is done to reduce the total value of its crypto coins in circulation.&lt;/p&gt;

&lt;h3&gt;
  
  
  A PRACTICAL EXAMPLE
&lt;/h3&gt;

&lt;p&gt;Gbenga and Ada are on the ecoin network. Gbenga wants to send 3 ecoins to Ada. Let's walk through the process.&lt;br&gt;
Address- Both Gbenga and Ada need an address. The first time Gbenga issues a transaction. A private and a public key is generated, the private key for Gbenga to sign the transaction, and a public key for other people to verify Gbengas signature. Ada will also need all these at her end. After solving the address problem Gbenga then issues a statement saying "I Gbenga belonging to this address(123) is sending 3 ecoins to Ada in this address (1234)". He issues this statement with a hash of his public key and his signature (private key).When the coin gets to Ada she can verify it is his signature because of his public key. Ada then signals to the rest of the network that she has gotten her coins. As other people on the network hear that message, each adds it to a queue of pending transactions that they've been told about, but which haven't yet been approved by the network. David "a miner" checks his copy of the blockchain, and can see that each transaction is valid. He would like to help out by broadcasting news of that validity to the entire network so it can be added as a block. However, before doing that, as part of the validation protocol David is required to solve a hard computational puzzle - the proof-of-work. Without the solution to that puzzle, the rest of the network won't accept his validation of the transaction.&lt;br&gt;
Once David solves this problem he is rewarded with a crypto coin and the block of transactions is added to the network.&lt;br&gt;
Head to this site bitcoin explorer. -&amp;gt; Latest Blocks -&amp;gt; View All -&amp;gt;Select a Block that has been mined. You can see all the transactions associated with that block. You can hover on each column to get the information on the transaction.&lt;/p&gt;

&lt;h3&gt;
  
  
  WHAT IF I WANT TO EXCHANGE CRYPTOCURRENCIES?
&lt;/h3&gt;

&lt;p&gt;I understand how the exchange is done within a blockchain. But what if I want to exchange an ecoin for a gcoin?. There are two main ways to do this Centralized Exchanges vs Decentralized.&lt;/p&gt;

&lt;h3&gt;
  
  
  Centralized Exchanges
&lt;/h3&gt;

&lt;p&gt;In this type of exchange, a centralized body helps you swap coins. It manages your blockchain's private keys and handles the responsibility involved in managing transactions. (It's funny having a centralized body manage a decentralized system🤔). Supposing I want to swap x amounts of coin A for y amounts of coin B. The exchange removes x amounts of coins A value from my coin A crypto wallet and records it on its ledger. It then creates a crypto B wallet (if I have none )to store coin B and purchase coin B on my behalf. After which it gives my coin A to other people willing to buy coin A. The more people that want to buy coin A the more coin As the value goes up. Popular examples of centralized exchanges are Binance and CoinBase.&lt;/p&gt;

&lt;h3&gt;
  
  
  Decentralized Exchanges
&lt;/h3&gt;

&lt;p&gt;In a way, these work similarly to the centralized exchanges except that you have the responsibility of storing your own private keys. Your keys are not managed by a "central entity". This essentially allows peer-to-peer (P2P) trading, enabling you to directly transfer funds to the interested buyer/seller, without having to go through middlemen.&lt;br&gt;
Decentralized exchanges work on agreements(smart contracts). The seller raises an order to sell and after filling in the necessary transaction details an advert is placed on a marketplace. Once a buyer agrees on terms with the seller a smart contract is created which cannot be changed until the payment is confirmed and both parties are settled.&lt;/p&gt;

&lt;h3&gt;
  
  
  SMART CONTRACTS
&lt;/h3&gt;

&lt;p&gt;A contract is an agreement between two parties what makes this one "smart" is that the third party(Lawyer, Bank) is replaced by a computer program that both parties understand. Why are smart contracts needed?. They can be used for a variety of reasons one of which is that they allow more systems to utilize an existing blockchains network. Supposing I want to create an app that can use blockchain technology to help me transfer music across a network in a secure way. I can go two ways&lt;br&gt;
Create my own blockchain network(Very stressful)&lt;br&gt;
Utilize an existing blockchains network(Less stressful)&lt;/p&gt;

&lt;p&gt;The blockchain owners give me a smart contract guideline to follow in my app. With this smart contract, I can create my own token and peg it to the blockchain's native currency I then give my users my own token to use on the platform. An example will be:&lt;br&gt;
Let's imagine I have a token called etoken. I want to use an existing blockchains network in our case let's say the Binance smart chain for my new project. To use it I need the blockchains native coins(BNBs). I decided that 5000 etoken is going to be worth 1BNB.I need 10,000 of these BNB tokens which will cost me 100,000 dollars. But there is a problem I cannot afford the BNB tokens. To raise money I go through a process known as an INITIAL COIN OFFERING.&lt;br&gt;
Basically, I tell people to give me their money for my huge project coming up, I then reward the people with my etoken which they can use on my app. People will need to trust my project to give me their cash. After I get the cash I buy the BNB tokens which I can then use on the blockchains network.&lt;br&gt;
Imagine Samuel a user on my app wants to buy music from Alice another user. An agreement is formed on the blockchain using a smart contract. This smart contract contains an agreement between Alice and Samuel. In the simplest terms, the agreement will look like this: "WHEN Samuel pays Alice 20 etokens, THEN Samuel will receive the music ". The blockchain checks if the smart contract is valid and then fulfills the transaction.&lt;/p&gt;

&lt;h3&gt;
  
  
  AUTOMATED MARKET MAKERS
&lt;/h3&gt;

&lt;p&gt;Automated market makers are like robots that give you the price of a currency using a formula. In traditional order books, let's say I have Ether and I want to trade it for Bitcoin. I will need to put out an advert that I am selling ETH for BTC. If I get a buyer we will then have to go through the hassle of negotiating till we come to a common agreement and the swap happens. But  AMMs cut out this hassle process. It uses a formula to calculate the price of each asset automatically, allowing for a very fast and seamless swap between assets. People often refer to it as P2C(Peer to Computer) as against P2P(Peer to Peer). The exact technicalities of how it does this are beyond the scope of this reading but in summary. &lt;br&gt;
-People submit their cryptocurrencies into a pool called a Liquidity pool. Anytime there is going to be a transaction with that cryptocurrency. The robots interact with that pool to get the currency to exchange.&lt;br&gt;
-The people that submit their cryptocurrencies into the pool are rewarded a percentage of each transaction that happens with that currency.&lt;br&gt;
-What price you get for an asset you want to buy or sell is determined by a formula. This formula can vary with each protocol. &lt;/p&gt;

&lt;h3&gt;
  
  
  COINS VS TOKENS
&lt;/h3&gt;

&lt;p&gt;With respect to my example on smart contracts, coins are native to their own blockchain. Whilst tokens have been built on top of another blockchain.&lt;/p&gt;

&lt;h3&gt;
  
  
  FORKING
&lt;/h3&gt;

&lt;p&gt;In the cryptocurrency world, a fork is when there is a change in the rules of the blockchain that the coin operates on or the nodes disagree on a historic transaction(s). Supposing you can your group of friends have been taking left on every turn and then you get to a particular turn and someone takes right. If no one joins him then he is left alone and excluded from the network. But if a minority of people go along he has created a new rule which can be said he has forked out of the original group. In cryptocurrency, if a lot of nodes agree with each other they can decide to fork out of the original network and create their own rules. A popular example is Bitcoin Cash which was forked out of the original Bitcoin.&lt;/p&gt;

&lt;h3&gt;
  
  
  NON FUNGIBLE TOKENS
&lt;/h3&gt;

&lt;p&gt;NFTS are unique digital assets. They are different from other cryptocurrencies because of one major reason. There are non-fungible. A fungible asset is one that is indistinguishable from one another. 1000 naira in your hand is the same value as it is in mine. With NFTS that is not the case. Its value is unique based on the NFT. I could digitize my painting into an NFT and then issue it out. People that purchase my NFTS now have a digital version of my painting. NFTS can be traded like other cryptocurrencies. But how do I assign value to my NFTS? As with all things in life, a value of a thing is determined by how much people deem it valuable.&lt;/p&gt;

&lt;h3&gt;
  
  
  STORE OF VALUE
&lt;/h3&gt;

&lt;p&gt;Some cryptocurrencies like Bitcoin are often referred to as digital gold due to their anti-inflationary nature. A pound of gold today is worth more than it was in 1970 which cannot be said about any other currency. Bitcoin bears similarities to gold in this regard. The value of 1BTC in 2021 is 1000 percent more than it was in 2011. Some may argue that the price of Bitcoin tends to crash from time to time. As with gold, the value is determined by how much people are willing to purchase it at that time.&lt;/p&gt;

&lt;p&gt;Blockchain technology has the potential to impact several domains- from voting to healthcare, social media, finance it comes with a lot of promises, some of which include transaction automation as in the case of smart contracts which can function without the need of middlemen. Solving the trust problem, the lack of trust is the reason why a lot of organizations spend a lot on security and data protection. Blockchain helps to increase trust within parties that do not currently trust one another. Transparency due to the open and immutable state of the blockchain. They are publicly viewable and can be audited. Blockchain technology allows users to share data, openly and securely having confidence that the data is protected and both parties can be trusted to deliver.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In this article, I have explained some concepts in the blockchain and cryptocurrency sphere and I do hope I have provided some useful information as you continue in your Blockchain journey.&lt;/p&gt;

&lt;h3&gt;
  
  
  REFERENCES AND FURTHER READING
&lt;/h3&gt;

&lt;p&gt;-&lt;a href="https://www.youtube.com/watch?v=0B3sccDYwuI&amp;amp;t=133s" rel="noopener noreferrer"&gt;How CryptoCurrency Works&lt;/a&gt;&lt;br&gt;
-&lt;a href="https://lifehacker.com/what-is-blockchain-1822094625" rel="noopener noreferrer"&gt;What is Block Chain&lt;/a&gt;&lt;br&gt;
-&lt;a href="https://academy.binance.com/en/articles/what-is-bitcoin#chapter-4-the-bitcoin-halving" rel="noopener noreferrer"&gt;What is Bitcoin ?&lt;/a&gt;&lt;br&gt;
-&lt;a href="https://michaelnielsen.org/ddi/how-the-bitcoin-protocol-actually-works/" rel="noopener noreferrer"&gt;how-the-bitcoin-protocol-actually-works&lt;/a&gt;&lt;br&gt;
-&lt;a href="https://academy.binance.com/en/articles/what-is-ethereum" rel="noopener noreferrer"&gt;what-is-ethereum&lt;/a&gt;&lt;br&gt;
-&lt;a href="https://www.bitdegree.org/crypto/tutorials/what-is-a-smart-contract" rel="noopener noreferrer"&gt;What Is a Smart Contract and How Does it Work?&lt;/a&gt;&lt;br&gt;
-&lt;a href="https://www.quora.com/How-do-smart-contracts-work" rel="noopener noreferrer"&gt;How-do-smart-contracts-work&lt;/a&gt;&lt;br&gt;
-&lt;a href="https://academy.binance.com/en/articles/what-is-cryptocurrency-mining" rel="noopener noreferrer"&gt;what-is-cryptocurrency-mining&lt;/a&gt;&lt;br&gt;
-&lt;a href="https://academy.binance.com/en/glossary/erc-20" rel="noopener noreferrer"&gt;ERC-20 Token Standards&lt;/a&gt;&lt;br&gt;
-&lt;a href="https://academy.binance.com/en/articles/what-is-cryptocurrency#centralized-exchanges-cex" rel="noopener noreferrer"&gt;a-guide-to-crypto-collectibles-and-non-fungible-tokens-nfts&lt;br&gt;
what-is-cryptocurrency#centralized-exchanges-cex&lt;/a&gt;&lt;br&gt;
-&lt;a href="https://qr.ae/pGTYqR" rel="noopener noreferrer"&gt;How does a decentralized exchange work and what are the most promising decentralized exchanges?&lt;/a&gt;&lt;br&gt;
-&lt;a href="https://www.investopedia.com/terms/b/binance-exchange.asp#:~:text=Binance%20is%20an%20exchange%20where,own%20token%20currency%2C%20Binance%20Coin." rel="noopener noreferrer"&gt;Binance Exchange&lt;/a&gt;&lt;br&gt;
-&lt;a href="https://medium.com/coinmonks/so-what-problems-does-blockchain-actually-solve-dc4446a550f6" rel="noopener noreferrer"&gt;So what problems does block chain actually solve?&lt;/a&gt;&lt;br&gt;
-&lt;a href="https://sectigostore.com/blog/what-is-crypto-mining-how-cryptocurrency-mining-works/" rel="noopener noreferrer"&gt;what-is-crypto-mining-how-does-cryptocurrency-mining-works&lt;/a&gt;&lt;br&gt;
-&lt;a href="https://academy.binance.com/en/articles/what-is-an-automated-market-maker-amm" rel="noopener noreferrer"&gt;What is an Automated Market Maker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow me here and across my social media for more content like this &lt;a href="https://twitter.com/ElegberunDaniel?s=09" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; &lt;a href="https://www.linkedin.com/in/olugbenga-elegberun/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt; &lt;/p&gt;

</description>
      <category>blockchain</category>
    </item>
    <item>
      <title>Exploring Azure Application Insights with Asp.NetCore</title>
      <dc:creator>Daniel Elegberun</dc:creator>
      <pubDate>Tue, 11 May 2021 17:15:26 +0000</pubDate>
      <link>https://forem.com/gbengelebs/exploring-azure-application-insights-with-asp-netcore-3one</link>
      <guid>https://forem.com/gbengelebs/exploring-azure-application-insights-with-asp-netcore-3one</guid>
      <description>&lt;p&gt;Having a way to monitor and measure application performance is essential to building high-quality, reliable software. To continuously improve performance and usability for users it is paramount to have some insight into the state of the application at all times.&lt;/p&gt;

&lt;p&gt;Application Insights is an application performance management service for software applications that enables you to monitor your application performance in Azure. With it, you can detect and diagnose application issues, track performance and gain insight into what users do with your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does It Work?
&lt;/h2&gt;

&lt;p&gt;Without going too much into the specifics. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You install the Application Insights SDK in your project.&lt;/li&gt;
&lt;li&gt;The SDK collects data from your project&lt;/li&gt;
&lt;li&gt;It then transfers these data to your custom Application Insights portal on Azure for better analysis. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, I am going to be walking through the process of setting up application insight for a demo Asp.NetCore MVC application.&lt;/p&gt;

&lt;h3&gt;
  
  
  PREREQUISITES
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;VS CODE &lt;a href="https://code.visualstudio.com/download" rel="noopener noreferrer"&gt;vscode&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;An Azure account. You can create it for free &lt;a href="https://portal.azure.com/free" rel="noopener noreferrer"&gt;here&lt;/a&gt;. 
&lt;em&gt;Ps you get 200dollars free Azure credits and 12month's pay as you go.&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  CREATING THE PROJECT
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a new asp.net core MVC project.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt; &lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;dotnet&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;mvc&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="n"&gt;ApplicationInsightsDemo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Enable Application Insights server-side
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Log on to Azure Portal &lt;/li&gt;
&lt;li&gt;Create a resource -&amp;gt; search for -&amp;gt; Application Insights
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwngh2i1n22ugtia7gm6f.png" alt="Appinsight Home Page" width="800" height="600"&gt;
&lt;/li&gt;
&lt;li&gt;Fill in the required details.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0g69ko8pkzi45forb05.png" alt="Alt Text" width="800" height="715"&gt;
&lt;/li&gt;
&lt;li&gt;Browse to the resource and copy your instrumentation key.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe0mwdmvtm5o6wliznypz.png" alt="Alt Text" width="800" height="176"&gt;
&lt;/li&gt;
&lt;li&gt;Add the Application Insights.NetCore SDK package to your application.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;dotnet&lt;/span&gt; &lt;span class="k"&gt;add&lt;/span&gt; &lt;span class="n"&gt;package&lt;/span&gt; &lt;span class="n"&gt;Microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ApplicationInsights&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AspNetCore&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In the startupClass inside the &lt;em&gt;ConfigureServices()&lt;/em&gt; method Add &lt;strong&gt;services.AddApplicationInsightsTelemetry()&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;      &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ConfigureServices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceCollection&lt;/span&gt; 
                                    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddApplicationInsightsTelemetry&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddControllersWithViews&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Specify the instrumentation key in appsettings.json as shown below. This key points to your specific app insight instance on azure.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s"&gt;"ApplicationInsights"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"InstrumentationKey"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"yourinstrumentationkeyhere"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="s"&gt;"Logging"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"LogLevel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s"&gt;"Default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Information"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s"&gt;"Microsoft"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Warning"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s"&gt;"Microsoft.Hosting.Lifetime"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Information"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="s"&gt;"AllowedHosts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"*"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Enabling Application Insights client-side
&lt;/h3&gt;

&lt;p&gt;We need to enable telemetry information for the client-side of the application to help us collect information from the client.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In _ViewImports.cshtml, add an injection
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;@inject&lt;/span&gt; &lt;span class="n"&gt;Microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ApplicationInsights&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AspNetCore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JavaScriptSnippet&lt;/span&gt; &lt;span class="n"&gt;JavaScriptSnippet&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This _ViewImports.cshtml page in ASP.NET is the base page for all the rest of the pages for the application, so adding this code here will add the code in the rest of the pages of the application at runtime.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In _Layout.cshtml, insert HtmlHelper at the end of the  section but before any other script.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt;  &lt;span class="n"&gt;@Html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JavaScriptSnippet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FullScript&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xetszwcoozqce8ahqos.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xetszwcoozqce8ahqos.png" alt="Alt Text" width="800" height="222"&gt;&lt;/a&gt;&lt;br&gt;
Now that we have set it up application insights in our application. Let's make some tweaks to the application to really see what application insights can help us with.&lt;/p&gt;

&lt;p&gt;I have modified my MVC app to add 3 things&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A call to a database service to load users. &lt;/li&gt;
&lt;li&gt;A call to an external API resource&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I also added buttons on the client to help interact with these different services. As we interact with the different services, we can see how application insights can help monitor our application's state.&lt;br&gt;
The full source code is &lt;a href="https://github.com/GbengaElebs/AzureApplicationInsights" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run the application and refresh it a couple of times.
Now go to your app insights instance on the Azure portal. 
Click on Live Metrics. You should see data from your application being displayed on the dashboard.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F03rjlikzyfj2swvhpol6.png" alt="Alt Text" width="800" height="413"&gt;
&lt;/li&gt;
&lt;li&gt;On the Application Insights portal navigate to the performance. You can drill into the operations to get a better insight.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fer4g8wttn3izu8z8nlnk.png" alt="Alt Text" width="800" height="419"&gt;
&lt;/li&gt;
&lt;li&gt;AI automatically tracks dependencies such as HTTP/HTTPS Calls, Calls made with SqlClient. You can see the full list &lt;a href="https://docs.microsoft.com/en-us/azure/azure-monitor/app/asp-net-dependencies" rel="noopener noreferrer"&gt;here&lt;/a&gt;.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxijdrvew6rchds11vi0.png" alt="Alt Text" width="800" height="441"&gt;
In my case, I am using a MySQL DB which AI does not track automatically. You can configure it for AI tracking by adding your own custom dependency tracking.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Adding Custom Dependency Tracking
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Inject a telemetry client instance in the constructor of the class you want to use it in.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;TelemetryClient&lt;/span&gt; &lt;span class="n"&gt;_telemetryClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Wrap your call to the MYSQL db like this.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_telemetryClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartOperation&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DependencyTelemetry&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"MySqlDb"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"SELECT UserName FROM Users"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Telemetry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Telemetry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$"server=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; - DB:&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;usersDataBase&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="c1"&gt;//sending details of the database call Application insights&lt;/span&gt;
                    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MySqlConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connString&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QueryFirstOrDefaultAsync&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CommandType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Telemetry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                        &lt;span class="c1"&gt;//informing Application Insights that the db call is successful&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="n"&gt;_telemetryClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StopOperation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;See this article for more details on tracking custom dependencies &lt;a href="https://docs.microsoft.com/en-us/azure/azure-monitor/app/api-custom-events-metrics#trackdependency" rel="noopener noreferrer"&gt;trackdependency&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Testing the Application
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Click on Call Database
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F06fytzt3co9a00axdj3d.png" alt="Alt Text" width="800" height="319"&gt;
&lt;/li&gt;
&lt;li&gt;Navigate to application insights -&amp;gt;Live Metrics-&amp;gt; check for the details.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F03rjlikzyfj2swvhpol6.png" alt="Alt Text" width="800" height="413"&gt;
&lt;/li&gt;
&lt;li&gt;You can see all application dependencies by going to the dependencies tab.
&lt;strong&gt;Note: There is a lag of about 5mins when viewing logs on other tabs. Only Live metrics provide the logs in real-time. So you will have to wait for about 5mins to analyze the logs.&lt;/strong&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8vat2kiiy3qcdxw4xion.png" alt="Alt Text" width="800" height="420"&gt;
See our custom dependency&lt;/li&gt;
&lt;li&gt;Click on view details -&amp;gt; investigate performance-&amp;gt; Drill Into and check for the details
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj61hg37gutzk7gik4q3u.png" alt="Alt Text" width="800" height="419"&gt;
&lt;/li&gt;
&lt;li&gt;We can see that application insight identifies the database service the operation was carried out on, with the exact SQL queries and the request and response times.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Exception when DB was not started
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr9y3ajwnkfvxtehbwaeh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr9y3ajwnkfvxtehbwaeh.png" alt="Alt Text" width="800" height="436"&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  When DB is up and running
&lt;/h3&gt;

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

&lt;ul&gt;
&lt;li&gt;You could even see what happened before this exception occurred by clicking on User flows.
The User Flows tool starts from an initial page view, custom event, or exception that you specify. Given this initial event, User Flows shows the events that happened before and afterward during user sessions.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz43stobdjldk5y3fyaxm.png" alt="Alt Text" width="800" height="393"&gt;
&lt;/li&gt;
&lt;li&gt;Let's test an external API call.
You can see the request and response times as well as the URL being called.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltfufegw9zto98gmnl7d.png" alt="Alt Text" width="800" height="439"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For client-side statistics, Go to -&amp;gt; Users.Check the number of users that have visited your site and the time. You could even filter by events or for properties like country name, browser version, device type.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz6ohnnorzr2hme4khrb8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz6ohnnorzr2hme4khrb8.png" alt="Alt Text" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Log Analytics.
&lt;/h2&gt;

&lt;p&gt;All the data for application insights is pushed to a place called Log analytics you can go there and query the logs directly using the Kusto language query syntax. You can access it by Clicking on -&amp;gt;Logs from the side menu. On the left-hand side of the log analytics monitor under tables, you will see the telemetry data which is being queried.&lt;/p&gt;
&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Let's query the number of exceptions that occurred in the last hour.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="n"&gt;exceptions&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ago&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fedq3ahgwd4nbcdtlej7m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fedq3ahgwd4nbcdtlej7m.png" alt="Alt Text" width="800" height="442"&gt;&lt;/a&gt;&lt;br&gt;
You could create alert rules for your logs. By clicking on &lt;em&gt;New Alert Rule&lt;/em&gt; So it alerts you when a certain event happens. In my case, I created an alert rule for when there are more than 9 exceptions in 5 minutes.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rg6836pajr4veb1gwtm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rg6836pajr4veb1gwtm.png" alt="Alt Text" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Play around with your own custom tweaks. Monitor, Measure and Optimize!&lt;/p&gt;

&lt;p&gt;RESOURCES&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://azuredevopslabs.com/labs/azuredevops/appinsights/" rel="noopener noreferrer"&gt;https://azuredevopslabs.com/labs/azuredevops/appinsights/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/azure/azure-monitor/app/asp-net-core" rel="noopener noreferrer"&gt;https://docs.microsoft.com/en-us/azure/azure-monitor/app/asp-net-core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=C4G1rRgY9OI" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=C4G1rRgY9OI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/azure/azure-monitor/app/api-custom-events-metrics#trackdependency" rel="noopener noreferrer"&gt;https://docs.microsoft.com/en-us/azure/azure-monitor/app/api-custom-events-metrics#trackdependency&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>azure</category>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Setting up a CI-CD Pipeline Using Azure DevOps</title>
      <dc:creator>Daniel Elegberun</dc:creator>
      <pubDate>Sun, 11 Apr 2021 18:52:04 +0000</pubDate>
      <link>https://forem.com/gbengelebs/setting-up-a-ci-cd-pipeline-using-azure-devops-4gb</link>
      <guid>https://forem.com/gbengelebs/setting-up-a-ci-cd-pipeline-using-azure-devops-4gb</guid>
      <description>&lt;p&gt;Continuous Integration is the process of merging all code changes into a central repository. Continuous Deployment on the other hand is the practice of automatically deploying code changes that have passed predefined checks to a specified environment. It uses a set of automated tools to run tests that ensure the codebase is stable and deployable. This approach helps deliver faster and efficient deployments.&lt;/p&gt;

&lt;p&gt;An azure pipeline is a fantastic tool for setting up CICD pipelines; in this article, I am going to be walking through how to set up a CI-CD pipeline using Azure DevOps Pipelines. This is a follow-up to my previous article on &lt;a href="https://dev.to/gbengelebs/deploying-an-asp-net-webapi-and-mysql-database-container-to-azure-kubernetes-service-3ca"&gt;Deploying An Asp.Net WebApi and MySql DataBase Container to Azure Kubernetes Service&lt;/a&gt;. I will be referring to some information discussed in that article. If you are already familiar with Azure Kubernetes deployments you can continue.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;VSCODE. Download &lt;a href="https://azure.microsoft.com/en-us/services/devops/pipelines/" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Azure DevOps &lt;a href="https://azure.microsoft.com/en-us/services/devops/pipelines/" rel="noopener noreferrer"&gt;Login&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;An Azure account. You can create it for free &lt;a href="https://portal.azure.com/free" rel="noopener noreferrer"&gt;here&lt;/a&gt;. 
&lt;em&gt;Ps you get 200dollars free Azure credits and 12month's pay as you go.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Docker &lt;a href="https://docs.docker.com/get-docker/" rel="noopener noreferrer"&gt;docker&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;VSCODE &lt;a href="https://code.visualstudio.com/download" rel="noopener noreferrer"&gt;vscode&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In my previous article, I discussed how to deploy a.NetCore web API and MySQL DB to azure Kubernetes service. I will be going one step further by automating the deployment process using an azure pipeline. The tool checks for changes in the git repository and automates the build and deployment process. I could also add a series of checks within the pipelines like approvals and tests. But for this article,I will just be setting up a basic build and deploy CI-CD pipeline.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2For4tcgop7thnru2mz5e6.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2For4tcgop7thnru2mz5e6.jpeg" alt="Azure Pipeline" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Download the source code from GitHub&lt;/strong&gt; &lt;a href="https://github.com/GbengaElebsDev/AksTutorial.git" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;2. Create a repository for the project and push your code to GitHub&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;3. If you followed the previous article revert the manual steps we did in the previous article by deleting the services and pod deployments and the images we pushed to Azure container registry.&lt;/strong&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deleting Container Images
To delete a container image login to Azure portal- &amp;gt; container registry -&amp;gt; repositories click on the three ellipses.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4jfb23omg3daq7kb1ohk.png" alt="Deleting Images" width="800" height="171"&gt;
&lt;/li&gt;
&lt;li&gt;Deleting Kubernetes Services and Pods
Run this command to get your current Kubernetes context
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl config get-contexts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ensure you are in your azure Kubernetes context&lt;br&gt;
Delete all the resources in that context&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl delete daemonsets,replicasets,services,deployments,pods,rc,pv,pvc --all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Check if it has been deleted&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get pods

No resources found in the default namespace.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;4. The deployment YAML files are in a folder called manifest&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This is to ensure that the pipeline can refer to all the deployments in one folder.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Login to Azure Pipelines&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://azure.microsoft.com/en-us/services/devops/pipelines/" rel="noopener noreferrer"&gt;Azure Pipelines&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to pipelines -&amp;gt; Create Pipeline
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5n4o5ofzli3ggudlpt8.png" alt="Azure Pipelines" width="800" height="230"&gt;
&lt;/li&gt;
&lt;li&gt;Connect to your GitHub and Authenticate&lt;/li&gt;
&lt;li&gt;Select your GitHub Project&lt;/li&gt;
&lt;li&gt;Select Deploy to Azure Kubernetes Service&lt;/li&gt;
&lt;li&gt;Login to your azure portal from the app&lt;/li&gt;
&lt;li&gt;Fill in your details like container registry and image name
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faievc8253o2oza72zzp7.png" alt="Alt Text" width="800" height="436"&gt;
&lt;/li&gt;
&lt;li&gt;A YAML file will be automatically generated.&lt;/li&gt;
&lt;li&gt;Edit the contents of the YAML file with this gist
&lt;strong&gt;Remember to replace the environment variables with your own details and credentials&lt;/strong&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Reviewing the YAML file
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;trigger&lt;/strong&gt;: This command tells the pipeline to listen to changes pushed to the main branch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;variables&lt;/strong&gt;: To store reusable entries things like the &lt;strong&gt;containerRegistry&lt;/strong&gt; and secrets that you want to reuse in multiple places in the pipeline.&lt;br&gt;
I define a &lt;strong&gt;mysqltag&lt;/strong&gt; to specify the MySQL version I want to be created.&lt;/p&gt;
&lt;h3&gt;
  
  
  Build Stage
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Stages&lt;/strong&gt;: are the major divisions in a pipeline: "build this app", "run these tests", and "deploy to pre-production" are good examples of stages. In our case, we have only "build" and "deploy".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Job&lt;/strong&gt;: A deployment job is a collection of steps that are run sequentially against the environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;pool&lt;/strong&gt;- is the server that your azure pipeline would be carrying out the operation. By default Azure assigns an agent for each pipeline. But you can create yours. In my case I created an agent called "ubuntu-latest".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;steps&lt;/strong&gt;- The build stage has a task of &lt;strong&gt;Docker@2&lt;/strong&gt; which will perform 2 tasks (Build &amp;amp; Push).&lt;br&gt;
This will build the service and then push it to my Azure container registry using the environment variables as defined. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We add two builds and deploy steps because we have two images we will like to build. The SQL and the API image&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;stages have jobs-&amp;gt; each job has a step -&amp;gt; each step has a task assigned to it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;publish&lt;/strong&gt;. This command tells the pipeline to find the manifest folder, create an artifact in the pipeline called manifest using the resources in the folder.&lt;/p&gt;
&lt;h3&gt;
  
  
  Deploy Stage
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;depends on&lt;/strong&gt; -It depends on the build stage. This means the build stage has to be completed before this can run.&lt;br&gt;
&lt;strong&gt;strategy&lt;/strong&gt; - How you want to deploy. &lt;strong&gt;Run once&lt;/strong&gt; means all the steps run sequentially. &lt;/p&gt;

&lt;p&gt;In the task section, there is a task: &lt;strong&gt;KubernetesManifest@0&lt;/strong&gt;&lt;br&gt;
Kubernetes manifest task command tells the pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To download the files from the manifest artifact
&lt;/li&gt;
&lt;li&gt;Apply the manifest artifact to the Kubernetes cluster&lt;/li&gt;
&lt;li&gt;Deploy the artifact to the Kubernetes cluster&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As with the build section, we define two deployment tasks because we have two images.&lt;/p&gt;

&lt;p&gt;Hit save and run and commit directly to the master branch. This will store your YAML file in your GitHub repo and it can be modified as needed.&lt;/p&gt;

&lt;p&gt;You should see this stage stating that the build has begun&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fos6hrnbw2vg305lfl7z3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fos6hrnbw2vg305lfl7z3.png" alt="BuildStage" width="800" height="325"&gt;&lt;/a&gt;&lt;br&gt;
-------------------------ERROR---------------------------&lt;br&gt;
&lt;strong&gt;This agent request is not running because you have reached the maximum number of requests that can run for parallelism type 'Microsoft-hosted Private'. Current position in queue: 1&lt;/strong&gt;&lt;br&gt;
-------------------------ERROR---------------------------&lt;br&gt;
You will probably run into this error and the root cause of the issue is that the pipeline Microsoft-hosted agent for public and private projects in new organizations on Azure DevOps has been restricted in the latest update. The summary of this is that Microsoft has temporarily restricted agents from running your jobs.&lt;/p&gt;
&lt;h3&gt;
  
  
  To resolve this for a private project
&lt;/h3&gt;

&lt;p&gt;Private Project:&lt;/p&gt;

&lt;p&gt;You could send an email to &lt;a href="mailto:azpipelines-freetier@microsoft.com"&gt;azpipelines-freetier@microsoft.com&lt;/a&gt; in order to get your free tier.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your name&lt;/li&gt;
&lt;li&gt;Name of the Azure DevOps organization&lt;/li&gt;
&lt;li&gt;Private Project:&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  To resolve this for a public project
&lt;/h3&gt;

&lt;p&gt;You could send an email to &lt;a href="mailto:azpipelines-ossgrant@microsoft.com"&gt;azpipelines-ossgrant@microsoft.com&lt;/a&gt; in order to get your free tier.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your name&lt;/li&gt;
&lt;li&gt;Azure DevOps organization for which you are requesting the free grant&lt;/li&gt;
&lt;li&gt;Links to the repositories that you plan to build&lt;/li&gt;
&lt;li&gt;Brief description of your project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are impatient like moi. Watch this&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/psa8xfJ0-zI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Self Hosted private Agent on Linux (Ubuntu) for Azure Pipelines on how to create your own self-hosted agents and link them to run your pipelines.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After you create the agent. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add it to the project&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4sp4b6vdkcth945ntdzr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4sp4b6vdkcth945ntdzr.png" alt="Create Agent" width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy the name and edit this section with your pool name so that agent runs it.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe85rbnvqasofcazfmp4o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe85rbnvqasofcazfmp4o.png" alt="Alt Text" width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install docker on your self hosted agent using this the first step in this &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04" rel="noopener noreferrer"&gt;How To Install and Use Docker on Ubuntu 18.04&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cd into your agent and restart the agent.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see all our Build processes are running similar to what we did before. But right now everything is running automatically in the Pipeline. Once there is a push to the main branch the pipeline triggers a build and it is deployed.&lt;/p&gt;

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

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The build and deploy stages have been completed.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frzfrfvavoyp6g91en28q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frzfrfvavoyp6g91en28q.png" alt="build and Deploy Completed" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to pipelines -&amp;gt; Runs -&amp;gt; View Environment -&amp;gt; Resources -&amp;gt;Services&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

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

&lt;ul&gt;
&lt;li&gt;Navigate through the deployment and explore the resources created.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select the Test-API service External IP&lt;br&gt;
Copy the external IP and navigate to the URL**&lt;br&gt;
(&lt;a href="http://external-ip:8080/swagger/index.html" rel="noopener noreferrer"&gt;http://external-ip:8080/swagger/index.html&lt;/a&gt;)&lt;br&gt;
Mine is (&lt;a href="http://20.62.158.83:8080/swagger/index.html" rel="noopener noreferrer"&gt;http://20.62.158.83:8080/swagger/index.html&lt;/a&gt;). Test the API deployment using the swagger page as shown. Our containerized API is now running inside the Azure Kubernetes service and exposed to the internet via the Load Balancer Service. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujvq49qqnzfzvhtzo7cc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujvq49qqnzfzvhtzo7cc.png" alt="Alt Text" width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We have successfully set up an azure pipeline to build and deploy our containerized application to both Azure Container Registry and Azure Kubernetes Service.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Add The Azure Pipeline built successfully badge to the git repo
&lt;/h2&gt;

&lt;p&gt;-In your Azure DevOps. Select the pipeline -&amp;gt; Runs -&amp;gt; Click on the 3 Elipses&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzlpltf373qbuud584q1w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzlpltf373qbuud584q1w.png" alt="Alt Text" width="800" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select Status Badge -&amp;gt; Copy the Sample markdown.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzb4w9qgpixupa0a9stwg.png" alt="Alt Text" width="800" height="811"&gt;
&lt;/li&gt;
&lt;li&gt;Create a README.md file in your GitHub repo and paste the markdown there.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvw3g42jfolueopviav1.png" alt="Alt Text" width="800" height="206"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Follow me here and across my social media for more content like this &lt;a href="https://twitter.com/ElegberunDaniel?s=09" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; &lt;a href="https://www.linkedin.com/in/olugbenga-elegberun/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt; &lt;/p&gt;

</description>
      <category>azureapril</category>
      <category>kubernetes</category>
      <category>docker</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
