<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Maria Zayed</title>
    <description>The latest articles on DEV Community by Maria Zayed (@mariazayed).</description>
    <link>https://dev.to/mariazayed</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%2F1189378%2F6594a83c-9df0-4e0e-a504-9b3a6c844829.png</url>
      <title>DEV Community: Maria Zayed</title>
      <link>https://dev.to/mariazayed</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mariazayed"/>
    <language>en</language>
    <item>
      <title>Understanding Neural Networks: A Comprehensive Guide</title>
      <dc:creator>Maria Zayed</dc:creator>
      <pubDate>Tue, 28 Nov 2023 07:03:37 +0000</pubDate>
      <link>https://dev.to/mariazayed/understanding-neural-networks-a-comprehensive-guide-28cg</link>
      <guid>https://dev.to/mariazayed/understanding-neural-networks-a-comprehensive-guide-28cg</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Neural networks get their ideas from our brains. Like our brain uses many cells to think and learn, neural networks use many small parts to handle information. This makes computers smarter in some ways, like us!&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore neural networks in easy steps. First, we’ll learn the basics, then look at how they work, and finally see how they’re used in different things like phones, computers, and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Basics of Neural Networks
&lt;/h2&gt;

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

&lt;p&gt;Did you know that computers can learn like our brains? Our brain has neurons that talk to each other. When we learn, these connections grow stronger. Neural networks in computers work in a similar way. They have artificial neurons that get information, process it, and pass it on. The more they work with data, the better they get at tasks, like how we learn from doing things.&lt;/p&gt;

&lt;h3&gt;
  
  
  Neural Network Layers
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxt3xei7zyryb7g1k95ep.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxt3xei7zyryb7g1k95ep.png" alt="A-typical-two-layer-neural-network-Input-layer-does-not-count-as-the-number-of-layers-of"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The neural network has 3 layers, each layer has a special job in handling information.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Input Layer&lt;/strong&gt;: It’s the starting point where you give the network information. For example, in a picture, each point of light in the picture goes into this layer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hidden Layers&lt;/strong&gt;: These are the main part of the network. They work on the information from the input layer quietly. They do the calculations and pass the results on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output Layer&lt;/strong&gt;: This is where the network gives us the answer. If the network is deciding if a picture is of a cat or a dog, the output layer tells us the answer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Nodes
&lt;/h3&gt;

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

&lt;p&gt;Nodes are like small checkpoints in the network. Each node looks at a piece of data and decides what to do with it. They are like tiny helpers, each doing a small part of a big job.&lt;/p&gt;

&lt;h3&gt;
  
  
  Activation functions
&lt;/h3&gt;

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

&lt;p&gt;Activation functions are like rules for the nodes. They tell the nodes when to act or when to wait. This helps the network focus on the important information. There are a few common types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sigmoid&lt;/strong&gt;: This function is smooth and changes input values into a range from 0 to 1. It’s good for deciding things like yes or no.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tanh (Hyperbolic Tangent)&lt;/strong&gt;: This is like sigmoid, but it works with values from -1 to 1. It’s useful when dealing with both positive and negative data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ReLU (Rectified Linear Unit)&lt;/strong&gt;: This one is simple. It turns all negative values to zero and keeps positive values. It’s popular because it’s straightforward and works well.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Weights
&lt;/h3&gt;

&lt;p&gt;Weights are like scales. They decide how important each piece of information is to the network. They change how much each piece of information affects the final decision.&lt;/p&gt;

&lt;h3&gt;
  
  
  Biases
&lt;/h3&gt;

&lt;p&gt;Biases are like extra nudges that help the network make decisions. Even when the information seems not enough, biases can help the network to come up with an answer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Neural Network Example
&lt;/h3&gt;

&lt;p&gt;Let’s go through an example of a simple neural network with layers, nodes, activation functions, weights, and biases to illustrate how these components work together.&lt;/p&gt;

&lt;p&gt;Let’s consider a neural network with the following configuration:&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;1 Input Layer&lt;/li&gt;
&lt;li&gt;1 Hidden Layer&lt;/li&gt;
&lt;li&gt;1 Output Layer&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Input Layer: 2 Nodes (Node1, Node2)&lt;/li&gt;
&lt;li&gt;Hidden Layer: 3 Nodes (Node3, Node4, Node5)&lt;/li&gt;
&lt;li&gt;Output Layer: 1 Node (Node6)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Activation Functions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hidden Layer: ReLU (Rectified Linear Unit)&lt;/li&gt;
&lt;li&gt;Output Layer: Sigmoid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Weights and Biases:&lt;/strong&gt;&lt;br&gt;
Initial weights and biases are often randomly assigned. Let’s assume the following for simplicity:&lt;br&gt;
Weights from Input to Hidden Layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;W1: 0.5 (from Node1 to Node3)&lt;/li&gt;
&lt;li&gt;W2: 0.3 (from Node1 to Node4)&lt;/li&gt;
&lt;li&gt;W3: 0.9 (from Node1 to Node5)&lt;/li&gt;
&lt;li&gt;W4: 0.8 (from Node2 to Node3)&lt;/li&gt;
&lt;li&gt;W5: 0.2 (from Node2 to Node4)&lt;/li&gt;
&lt;li&gt;W6: 0.1 (from Node2 to Node5)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Weights from Hidden to Output Layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;W7: 0.3 (from Node3 to Node6)&lt;/li&gt;
&lt;li&gt;W8: 0.6 (from Node4 to Node6)&lt;/li&gt;
&lt;li&gt;W9: 0.9 (from Node5 to Node6)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Biases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;B1: 0.1 (for Node3)&lt;/li&gt;
&lt;li&gt;B2: 0.2 (for Node4)&lt;/li&gt;
&lt;li&gt;B3: 0.3 (for Node5)&lt;/li&gt;
&lt;li&gt;B4: 0.4 (for Node6)&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Let’s say our input vector is &lt;a href="https://dev.tovalues%20for%20Node1%20and%20Node2"&gt;1, 0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calculations in Hidden Layer:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node3 = ReLU(Node1 input * W1 + Node2 input * W4 + B1) = ReLU(1 * 0.5 + 0 * 0.8 + 0.1) = ReLU(0.6) = 0.6&lt;/li&gt;
&lt;li&gt;Node4 = ReLU(Node1 input * W2 + Node2 input * W5 + B2) = ReLU(1 * 0.3 + 0 * 0.2 + 0.2) = ReLU(0.5) = 0.5&lt;/li&gt;
&lt;li&gt;Node5 = ReLU(Node1 input * W3 + Node2 input * W6 + B3) = ReLU(1 * 0.9 + 0 * 0.1 + 0.3) = ReLU(1.2) = 1.2&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Note: ReLU function is max(0, x), so all negative values become 0)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calculations in Output Layer:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node6 = Sigmoid(Node3 output * W7 + Node4 output * W8 + Node5 output * W9 + B4) = Sigmoid(0.6 * 0.3 + 0.5 * 0.6 + 1.2 * 0.9 + 0.4) = Sigmoid(1.96)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Note: Sigmoid function outputs a value between 0 and 1, useful for binary classification)&lt;/p&gt;

&lt;p&gt;This is a simplified example. In a real-world scenario, the network would be more complex with more layers and nodes. Also, during training, these weights and biases would be adjusted iteratively to reduce prediction error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Training the Neural Network
&lt;/h2&gt;

&lt;p&gt;Training a neural network helps it learn from data and get better at making predictions or decisions. The two key players in this process are &lt;strong&gt;backpropagation&lt;/strong&gt; and &lt;strong&gt;gradient descent&lt;/strong&gt;. They sound complex, but let’s break them down into simpler terms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Backpropagation: Learning from Mistakes
&lt;/h3&gt;

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

&lt;p&gt;Backpropagation is all about learning from errors. When a neural network makes a prediction, it might not always be right. Backpropagation measures how far off the prediction is from the correct answer. It then sends this error information back through the network. This is like the network looking back at its work and seeing where it went wrong.&lt;/p&gt;

&lt;p&gt;As this error information travels back, the network adjusts its weights and biases. This adjustment is crucial as it helps the network learn from its mistakes. The next time it encounters similar data, it’s more likely to make a better prediction. It’s a continuous cycle of predicting, learning from errors, and improving.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gradient Descent: Finding the Best Path
&lt;/h3&gt;

&lt;p&gt;Gradient descent is the method the network uses to change its weights and biases effectively. It finds the steepest path in terms of error reduction and takes small steps along that path.&lt;/p&gt;

&lt;p&gt;In technical terms, gradient descent calculates the gradient (or slope) of the network’s error with respect to each weight and bias. It then adjusts these weights and biases to minimize the error.&lt;/p&gt;

&lt;p&gt;By combining backpropagation and gradient descent, we get a powerful training process. It enables neural networks to learn from data, adjust their parameters, and improve their accuracy over time. This training is what makes neural networks so valuable in tasks like image recognition, language processing, and much more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning and Loss Functions
&lt;/h2&gt;

&lt;p&gt;The learning process of a neural network involves adjusting its weights and biases based on the input data it receives and the output it’s supposed to produce. This adjustment happens during the network’s training phase. When a neural network is given data, it makes predictions or decisions based on its current state. It then compares its predictions to the actual, desired outcome and learns from any differences.&lt;/p&gt;

&lt;p&gt;This process is a bit like a feedback loop. The network tries, learns from its mistakes, and tries again, but this time a bit smarter. Over time, through many rounds of this loop, the neural network becomes more and more accurate in its predictions or decisions.&lt;/p&gt;

&lt;p&gt;A crucial part of this learning process is the use of loss functions. These functions measure how far off a neural network’s predictions are from the actual results. Think of them as scoring systems – they tell you how well the network is doing. Two common loss functions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mean Squared Error (MSE)&lt;/strong&gt;: This is often used in regression problems, where the goal is to predict continuous values. MSE calculates the average of the squares of the differences between the predicted values and the actual values. It’s like measuring the average distance from the target in a game of darts. The smaller the distance (or error), the better the neural network is at hitting the target.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-Entropy&lt;/strong&gt;: This one is popular in classification problems, where the goal is to choose between different categories (like identifying whether an image shows a cat or a dog). Cross-entropy measures the difference between two probability distributions – the actual distribution and the predicted distribution. It’s like measuring how well the network’s guess matches the real answer in terms of probability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both of these loss functions provide a way for the network to understand and quantify its mistakes. By minimizing these errors (as measured by the loss functions) through training, the neural network becomes more accurate and reliable in its predictions or classifications.&lt;/p&gt;

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

&lt;p&gt;To provide a numerical example that illustrates training, backpropagation, and loss functions in a neural network, let’s consider a simple scenario. We’ll use a small neural network with one input layer, two hidden layers, and one output layer. We’ll focus on a regression problem using Mean Squared Error (MSE) as our loss function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Task&lt;/strong&gt;: Predict the output value based on the input.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Input&lt;/strong&gt;: A single value (for simplicity).
Output: A single predicted value.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;True Output&lt;/strong&gt;: The actual value we want to predict.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Input Value (X)&lt;/strong&gt;: 2&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;True Output (Y)&lt;/strong&gt;: 6&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Initial Weights&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Input to Hidden Layer&lt;/strong&gt;: W1 = 0.5, W2 = 0.5&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hidden to Output Layer&lt;/strong&gt;: W3 = W4 = 0.5&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Biases&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hidden Layer&lt;/strong&gt;: B1 = 1, B2 = 1&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output Layer&lt;/strong&gt;: B3 = 1&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flia22jsp2f04phws4f84.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flia22jsp2f04phws4f84.png" alt="numerical-example-that-illustrates-training-backpropagation-and-loss-functions-1024x683"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Forward Pass (Initial Prediction)&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Hidden Layer Calculations&lt;/strong&gt; (using a simple linear activation for simplicity):

&lt;ul&gt;
&lt;li&gt;Node2 = (X * W1) + B1 = (2 * 0.5) + 1 = 2&lt;/li&gt;
&lt;li&gt;Node3 = (X * W2) + B2 = (2 * 0.5) + 1 = 2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output Layer Calculation&lt;/strong&gt;:
Output = (Node2 * W3) + (Node3 * W4) + B3 = (2 * 0.5) + (2 * 0.5) + 1 = 3&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Loss Calculation (Mean Squared Error)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MSE: (True Output – Predicted Output)^2 = (6 – 3)^2 = 9&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Backpropagation and Weight Update (Simplified)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Adjust weights to reduce loss. This is a complex calculation involving partial derivatives, but let’s simplify, suppose we adjust the weights slightly based on the error:&lt;/p&gt;

&lt;p&gt;New W1 = 0.55, New W2 = 0.55, New W3 = 0.55&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ficvjxw7lj68p73t2njq1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ficvjxw7lj68p73t2njq1.png" alt="numerical-example-that-illustrates-training-backpropagation-and-loss-functions2-1024x683"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;New Prediction After Weight Update&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Repeat the forward pass with new weights:

&lt;ul&gt;
&lt;li&gt;New Node2 = old Node2 output * W3 + B1 = (2 * 0.55) + 1 = 2.1&lt;/li&gt;
&lt;li&gt;New Node3 = old Node3 output * W4 + B2 = (2 * 0.55) + 1 = 2.1&lt;/li&gt;
&lt;li&gt;New Output = New Node2 * W1 + New Node3 * W2 + B = (2.1 * 0.55) + (2.1 * 0.55) + 1 = 3.31&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;New MSE:

&lt;ul&gt;
&lt;li&gt;(True Output – New Predicted Output)^2 = (6 – 3.31)^2 = 7.2361&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The loss (MSE) has decreased from 9 to 7.2361, showing improvement in the prediction after adjusting the weights.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Applications of Neural Networks
&lt;/h2&gt;

&lt;p&gt;Neural networks, a fascinating aspect of artificial intelligence, have found their way into various domains, revolutionizing the way we approach problems and solutions. Let’s dive into the diverse applications of neural networks, highlighting their adaptability and potential future trends.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Image Recognition&lt;/strong&gt;: One of the most striking uses of neural networks is in image recognition. They can identify patterns and objects in images with remarkable accuracy. From unlocking your phone with facial recognition to diagnosing diseases from medical images, neural networks are making significant contributions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Natural Language Processing (NLP)&lt;/strong&gt;: Neural networks are also at the forefront of understanding and processing human language. Whether it’s translating languages, powering voice assistants like Siri or Alexa, or enabling chatbots for customer service, NLP relies heavily on neural networks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Finance&lt;/strong&gt;: In the financial sector, neural networks are used for predictive analysis, such as forecasting stock prices or identifying fraudulent activities. Their ability to analyze vast amounts of data helps in making informed decisions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Healthcare&lt;/strong&gt;: The healthcare industry benefits immensely from neural networks. They assist in early disease detection, drug discovery, and personalized medicine, contributing to more efficient and effective patient care.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;One such application is the &lt;a href="https://www.codester.com/items/46073/clearcut-ai-background-remover-python?ref=DevEasyLearn" rel="noopener noreferrer"&gt;&lt;strong&gt;AI Background Remover&lt;/strong&gt;&lt;/a&gt;, a handy tool for anyone looking to effortlessly remove backgrounds from images. This application, leveraging the power of AI, simplifies a task that traditionally requires complex editing skills.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;In conclusion, we’ve learned a lot about neural networks. These are smart systems in technology that work like the human brain. We looked at how they are made, how they learn, and how they make decisions. We also saw how important they are in different areas like recognizing pictures, understanding language, and helping in finance, and healthcare.&lt;/p&gt;

&lt;p&gt;Neural networks are changing how we solve problems in many fields. They are becoming more important every day. In the future, they will do even more amazing things.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;👉 Visit my &lt;a href="https://bit.ly/m/DevEasyLearn" rel="noopener noreferrer"&gt;blog&lt;/a&gt; 👈&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>datascience</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Exploring the New Control Flow Syntax in Angular 17</title>
      <dc:creator>Maria Zayed</dc:creator>
      <pubDate>Sun, 19 Nov 2023 12:23:46 +0000</pubDate>
      <link>https://dev.to/mariazayed/exploring-the-new-control-flow-syntax-in-angular-17-339g</link>
      <guid>https://dev.to/mariazayed/exploring-the-new-control-flow-syntax-in-angular-17-339g</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Angular is a tool many people use to build websites. It’s known for being strong and flexible, which means it helps developers make good, powerful websites easily.&lt;/p&gt;

&lt;p&gt;Now, Angular has a new version called Angular 17. This new version shows that Angular keeps getting better, adding new things to help developers. One exciting part of Angular 17 is its new control flow syntax. This is a big change in how we make parts of websites in Angular.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the @-Syntax
&lt;/h2&gt;

&lt;p&gt;The @-syntax in Angular 17 is a fresh way to write control structures like if/else, loops, and switches directly in your templates. It’s a shorthand that makes coding more intuitive. For instance, instead of the traditional directives, you now use a syntax that resembles standard JavaScript, making it easier for developers to adapt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding &lt;code&gt;ngIf&lt;/code&gt;, &lt;code&gt;ngFor&lt;/code&gt;, and &lt;code&gt;ngSwitch&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Previously, Angular used directives like &lt;code&gt;*ngIf&lt;/code&gt;, &lt;code&gt;*ngFor&lt;/code&gt;, and &lt;code&gt;*ngSwitch&lt;/code&gt;. These directives were powerful but sometimes made templates complex and hard to read.&lt;/p&gt;

&lt;h3&gt;
  
  
  ngIf/if
&lt;/h3&gt;

&lt;p&gt;Used for conditional rendering. For instance, if you wanted to display a message only when a certain condition is true, you’d write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div *ngIf="condition"&amp;gt;Show this if the condition is true&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Angular 17, this becomes more straightforward with the @-syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div&amp;gt; @if (condition) { Show this if the condition is true } &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ngFor/for
&lt;/h3&gt;

&lt;p&gt;This directive helped in looping over arrays. To display a list of items:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- Loop through items array and display each item --&amp;gt;
&amp;lt;ul&amp;gt;
  &amp;lt;li *ngFor="let item of items"&amp;gt;{{ item }}&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Angular 17’s new syntax, the same functionality is achieved 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;&amp;lt;!-- Loop through items array and display each item --&amp;gt;
&amp;lt;ul&amp;gt;
  &amp;lt;div&amp;gt; @for (let item of items) { &amp;lt;li&amp;gt;{{ item }}&amp;lt;/li&amp;gt; } &amp;lt;/div&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ngSwitch/switch
&lt;/h3&gt;

&lt;p&gt;Similar to a switch statement in programming, it conditionally displays elements based on a value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- Display content based on the value of userRole --&amp;gt;
&amp;lt;div [ngSwitch]="userRole"&amp;gt;
  &amp;lt;p *ngSwitchCase="'admin'"&amp;gt;Admin Access Granted&amp;lt;/p&amp;gt;
  &amp;lt;p *ngSwitchCase="'user'"&amp;gt;User Access&amp;lt;/p&amp;gt;
  &amp;lt;p *ngSwitchDefault&amp;gt;No Access&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Angular 17, the new syntax might look 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;&amp;lt;!-- Display content based on the value of userRole --&amp;gt;
&amp;lt;div&amp;gt; 
  @switch (userRole) {
    case 'admin': &amp;lt;p&amp;gt;Admin Access Granted&amp;lt;/p&amp;gt; 
    case 'user': &amp;lt;p&amp;gt;User Access&amp;lt;/p&amp;gt;
    default: &amp;lt;p&amp;gt;No Access&amp;lt;/p&amp;gt;
  } 
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Deferred Loading Blocks and Performance
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;@defer&lt;/code&gt; element represents a leap forward in how we approach performance and efficiency in Angular applications. Let’s explore what &lt;code&gt;@defer&lt;/code&gt; is, how it enables lazy-loading, and the advantages it brings in terms of performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introducing the &lt;a class="mentioned-user" href="https://dev.to/defer"&gt;@defer&lt;/a&gt; Control Block
&lt;/h3&gt;

&lt;p&gt;The &lt;a class="mentioned-user" href="https://dev.to/defer"&gt;@defer&lt;/a&gt; block in Angular 17 is a powerful tool for managing how and when certain parts of your webpage load. In simpler terms, it allows you to control the loading of specific content, deferring it until needed. This approach is a contrast to the traditional method where everything loads at once, regardless of whether it’s immediately necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lazy-Loading with &lt;a class="mentioned-user" href="https://dev.to/defer"&gt;@defer&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Lazy-loading is a technique where content loads only when it’s required. For example, consider a webpage with multiple sections, but the user initially sees only the top part. With &lt;code&gt;@defer&lt;/code&gt;, the rest of the sections can load later, when the user scrolls to them or when certain conditions are met.&lt;/p&gt;

&lt;p&gt;Here’s a basic example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- Deferred content block --&amp;gt;
&amp;lt;div&amp;gt; 
  @defer (userScrollsDown) {
    &amp;lt;p&amp;gt;More content loads as you scroll down.&amp;lt;/p&amp;gt;
  } 
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this code, the &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag’s content won’t load immediately when the page loads. Instead, it waits until the user scrolls down (as indicated by &lt;code&gt;userScrollsDown&lt;/code&gt;).&lt;/p&gt;

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

&lt;p&gt;The primary benefit of using &lt;code&gt;@defer&lt;/code&gt; is improved performance. By loading content only when it’s needed, you reduce the initial load time of your webpage, which is crucial for user experience and SEO. This is especially beneficial for sites with heavy content or applications that need to perform well on devices with limited resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Image Galleries&lt;/strong&gt;: Load images as the user scrolls, rather than all at once.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;E-Commerce Sites&lt;/strong&gt;: Product descriptions or reviews can load when a user shows interest in a specific item.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Social Media Feeds&lt;/strong&gt;: New posts can load as the user reaches the end of the currently loaded content.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://angular.io/guide/control_flow"&gt;Angular: Built-in control flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deveasylearn.com/complete-guide-angular-lifecycle-hooks/"&gt;Complete Guide: Angular lifecycle hooks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deveasylearn.com/introducing-required-inputs-in-angular/"&gt;Required Inputs in Angular&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deveasylearn.com/understanding-angular-signals-a-comprehensive-guide/"&gt;Angular Signals: A Comprehensive Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deveasylearn.com/standalone-components-in-angular-a-comprehensive-guide/"&gt;Standalone Components in Angular: A Comprehensive Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;In conclusion, we have learned a lot about Angular 17’s new features. The @-syntax makes writing code in Angular simpler. It’s different from older ways like ngIf and ngFor, and it helps make your code clearer. We also talked about &lt;a class="mentioned-user" href="https://dev.to/defer"&gt;@defer&lt;/a&gt;, which helps your website load faster by only showing content when needed.&lt;/p&gt;

&lt;p&gt;These updates are very important for people who make websites using Angular. They make coding easier and help websites work better and faster. If you use Angular, you should try these new features. They can help you write better code and make better websites. &lt;strong&gt;Happy coding!&lt;/strong&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;👉 Visit my &lt;a href="https://bit.ly/m/DevEasyLearn"&gt;blog&lt;/a&gt; 👈&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>frontend</category>
      <category>angular</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Understanding Array Shapes in NumPy</title>
      <dc:creator>Maria Zayed</dc:creator>
      <pubDate>Sat, 18 Nov 2023 18:19:24 +0000</pubDate>
      <link>https://dev.to/mariazayed/understanding-array-shapes-in-numpy-4j9m</link>
      <guid>https://dev.to/mariazayed/understanding-array-shapes-in-numpy-4j9m</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Numpy is a handy tool, which stands for Numerical Python, is super useful for doing math stuff with data. But let’s focus on one big idea: &lt;strong&gt;array shapes&lt;/strong&gt;. Understanding array shapes is like knowing how the puzzle fits together – it’s important so that everything works smoothly. Just like you can’t put together puzzles with different numbers of pieces, you can’t do certain things if arrays don’t have the right shapes.&lt;/p&gt;

&lt;p&gt;Why do these shapes matter? Well, they help us change how data looks for making pictures, combine info in cool ways, and do specific math things. Knowing about array shapes makes it easier to move around and work with data.&lt;/p&gt;

&lt;p&gt;In this article, we’re going to dive into why array shapes are important. Let’s start exploring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basics of Array Shapes
&lt;/h2&gt;

&lt;p&gt;Data analysis often requires handling vast amounts of information, and it’s crucial to understand how this data is organized. Enter the world of array shapes in NumPy. Think of array shapes as a way of arranging and understanding your data, much like organizing books on different shelves based on their sizes or genres.&lt;/p&gt;

&lt;h3&gt;
  
  
  One-dimensional Array
&lt;/h3&gt;

&lt;p&gt;A one-dimensional array is the simplest form. It’s like a single line of data, similar to a row of books on a shelf. Each book (or piece of data) is called an “&lt;strong&gt;element&lt;/strong&gt;”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XL1sQed1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28jgyrt7057eiap4cbv6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XL1sQed1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28jgyrt7057eiap4cbv6.png" alt="numpy_arrays" width="304" height="314"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np
one_dim_array = np.array([7, 2, 9, 10])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives us a line of numbers, starting from 7 and ending at 10.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two-dimensional Array
&lt;/h3&gt;

&lt;p&gt;Imagine stacking multiple rows of books one above the other; each row is like a one-dimensional array, but now we’ve added another dimension – the columns!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GCL9e6hy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5evv97q8umx50wwftlkd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GCL9e6hy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5evv97q8umx50wwftlkd.png" alt="numpy_arrays 2d" width="293" height="398"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;two_dim_array = np.array([[5.2, 3, 4.5], [9.1, 0.1, 0,3]])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we have two rows and three columns, forming a 2×3 grid of numbers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Three-dimensional Array
&lt;/h3&gt;

&lt;p&gt;For a three-dimensional array, imagine a bookshelf where you have multiple sections, each with its own set of rows and columns of books. This is like having multiple matrices stacked behind one another.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ogb5BCOr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zxmzbo4dsn1gz876n2se.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ogb5BCOr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zxmzbo4dsn1gz876n2se.png" alt="numpy_arrays 3d" width="338" height="572"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;three_dim_array = np.array([
    [[9, 6, 9], [1, 3, 0], [2, 9, 7], [1, 4, 7]], 
    [[9, 6, 8], [1, 3, 2], [2, 9, 5], [2, 3, 4]]
])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we’ve got two “sections” (or matrices). Each section has four rows and three columns of numbers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Higher-dimensional Arrays
&lt;/h3&gt;

&lt;p&gt;NumPy isn’t just limited to one, two, or three dimensions. It’s incredibly versatile and can handle even more complex structures. As you move into advanced data analysis, you might encounter situations where such multidimensional arrays come into play. For now, just remember that with NumPy, the sky is the limit!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;higher_dim_array = np.array([
    [
        [[1, 2], [3, 4]], 
        [[5, 6], [7, 8]]
    ], 
    [
        [[9, 10], [11, 12]], 
        [[13, 14], [15, 16]]
    ]
])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Attributes of NumPy Arrays
&lt;/h2&gt;

&lt;p&gt;Let’s take a moment to focus on some vital attributes that help describe our data’s organization. NumPy arrays have characteristics that give us insight into their structure: &lt;code&gt;shape&lt;/code&gt;, &lt;code&gt;ndim&lt;/code&gt;, and &lt;code&gt;size&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shape (&lt;code&gt;shape&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;shape&lt;/code&gt; attribute provides a tuple representing the dimensionality of the array. It’s like measuring how many rows of books we have and how many books are in each row.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np
data = np.array([[1, 2, 3], [4, 5, 6]])
print(data.shape) # (2, 3)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells us that our array has 2 rows and 3 columns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Number of Dimensions (&lt;code&gt;ndim&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ndim&lt;/code&gt; attribute gives us the number of array dimensions or axes. Think of it as counting how many ways we can navigate through our collection of data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np
data = np.array([[1, 2, 3], [4, 5, 6]])
print(data.ndim) # 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This confirms that our data has two dimensions, which makes sense as we saw with our shape example.&lt;/p&gt;

&lt;p&gt;Size (&lt;code&gt;size&lt;/code&gt;)&lt;br&gt;
The &lt;code&gt;size&lt;/code&gt; attribute tells us the total number of elements in the array. Imagine counting every single book on a large bookshelf, regardless of the row or section it’s in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np
data = np.array([[1, 2, 3], [4, 5, 6]])
print(data.size) # 6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This indicates there are 6 elements in total in our array, again aligning with our previous understanding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reshaping and Manipulating Array Shapes
&lt;/h2&gt;

&lt;p&gt;Think of reshaping as rearranging puzzle pieces. Even though the pieces are the same, they can be organized differently to create unique pictures.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;reshape&lt;/code&gt; Method
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;reshape&lt;/code&gt; allows us to change the structure of our array without changing the data itself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wPQU3_DF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tkquekaflsch6vou2ac2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wPQU3_DF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tkquekaflsch6vou2ac2.png" alt="numpy-manipulation-reshape-function-image-1" width="273" height="534"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np
original_array = np.array([[2, 3, 4], [5, 6, 7]])
reshaped_array = original_array.reshape(3, 2)
print(reshaped_array)

# Output
[[2 3]
 [4 5]
 [6 7]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how the 2×3 grid transferred into a 3×2 grid, while the numbers themselves remained the same!&lt;/p&gt;

&lt;h3&gt;
  
  
  The Magic Number: &lt;code&gt;-1&lt;/code&gt; in Reshaping
&lt;/h3&gt;

&lt;p&gt;Sometimes, we might want to reshape an array but let NumPy decide one of the dimensions for us. This is where the special value &lt;code&gt;-1&lt;/code&gt; comes in. When used in the &lt;code&gt;reshape&lt;/code&gt; method, &lt;code&gt;-1&lt;/code&gt; basically tells NumPy: “&lt;em&gt;Hey, I’m not sure about this dimension, can you figure it out for me?&lt;/em&gt;“&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np
original_array = np.array([1, 2, 3, 4, 5, 6])
reshaped_with_negative = original_array.reshape(3, -1)
print(reshaped_with_negative)

# Output
[[1 2]
 [3 4]
 [5 6]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we specified that we wanted 3 rows, but left the number of columns to NumPy’s discretion by using &lt;code&gt;-1&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flattening and Transposing Arrays
&lt;/h2&gt;

&lt;p&gt;Let’s discuss two more powerful features that can make our data exploration even more interesting concepts: flattening and transposing arrays.&lt;/p&gt;

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

&lt;p&gt;Flattening, as the name suggests, is the process of converting a multi-dimensional array into a one-dimensional array. In NumPy, we’ve got two handy methods to achieve this: &lt;code&gt;ravel()&lt;/code&gt; and &lt;code&gt;flatten()&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;ravel()&lt;/code&gt; Method
&lt;/h4&gt;

&lt;p&gt;This method provides a flattened array. However, it gives a “view” of the original array whenever possible. This means if you change the flat array, the original might change too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np

multi_dim_array = np.array([[1, 2, 3], [4, 5, 6]])
flat_using_ravel = multi_dim_array.ravel()

print(flat_using_ravel) # [1 2 3 4 5 6]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s see how &lt;code&gt;ravel()&lt;/code&gt; change the original data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np

# Creating a 2x3 array
array_1 = np.array([[1, 2, 3], [4, 5, 6]])

# Using ravel() to flatten the array
raveled_array = array_1.ravel()

# Let's modify the flattened array
raveled_array[0] = 100

# Display the modified flattened array
print("Modified raveled array:", raveled_array)

# Now, let's check the original array
print("Original array after modification:", array_1)

# Output
Modified raveled array: [100   2   3   4   5   6]
Original array after modification: [[100   2   3]
                                    [  4   5   6]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, changing the flattened array returned by &lt;code&gt;ravel()&lt;/code&gt; also changes the original array.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;flatten()&lt;/code&gt; Method
&lt;/h4&gt;

&lt;p&gt;Unlike &lt;code&gt;ravel()&lt;/code&gt;, the &lt;code&gt;flatten()&lt;/code&gt; method always returns a fresh copy of the data. So, if you modify this flat version, the original stays the same.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np
multi_dim_array = np.array([[1, 2, 3], [4, 5, 6]])
flat_using_flatten = multi_dim_array.flatten()
print(flat_using_flatten) # [1 2 3 4 5 6]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s see how &lt;code&gt;flatten()&lt;/code&gt; not change the original data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Resetting our original array
array_1 = np.array([[1, 2, 3], [4, 5, 6]])

# Using flatten() to get a flattened array
flattened_array = array_1.flatten()

# Modifying the flattened array
flattened_array[0] = 100

# Display the modified flattened array
print("Modified flattened array:", flattened_array)

# Checking the original array
print("Original array after modification:", array_1)

# Output
Modified flattened array: [100   2   3   4   5   6]
Original array after modification: [[1 2 3]
                                    [4 5 6]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that even after modifying the array returned by &lt;code&gt;flatten()&lt;/code&gt;, the original array remains unchanged.&lt;/p&gt;

&lt;h3&gt;
  
  
  Changing Directions with &lt;code&gt;T&lt;/code&gt;: Transposing Arrays
&lt;/h3&gt;

&lt;p&gt;The transposition of an array is like flipping its content over its diagonal. Rows become columns, and columns become rows. With NumPy, this magical switch is achieved with the &lt;code&gt;T&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UOpATmbh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oiafw9gq7oi4sfq0ag37.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UOpATmbh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oiafw9gq7oi4sfq0ag37.png" alt="numpy-transpose" width="800" height="330"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np
multi_dim_array = np.array([[1, 2, 3], [4, 5, 6]])
transposed_array = multi_dim_array.T
print(transposed_array)

# Output
[[1 4]
 [2 5]
 [3 6]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how our original 2×3 array has transformed into a 3×2 array!&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.w3schools.com/python/numpy/numpy_array_shape.asp"&gt;W3Schools; NumPy Array Shape&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deveasylearn.com/a-comprehensive-guide-to-numpy-arrays/"&gt;A Comprehensive Guide to NumPy Arrays&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deveasylearn.com/understanding-array-broadcasting-in-numpy/"&gt;Understanding Array Broadcasting in NumPy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deveasylearn.com/masking-and-boolean-indexing-a-smart-data-filtering-in-python/"&gt;Masking and Boolean Indexing: A Smart Data Filtering in Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deveasylearn.com/navigating-the-numpy-universe-a-beginner-guide-to-data-manipulation-in-python/"&gt;A Beginner Guide to Data Manipulation in Python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;In conclusion, understanding shapes in NumPy is like knowing how to build with blocks. It helps you work better with data. But just reading won’t make you an expert. You need to try it yourself, play with it, and learn from any mistakes. Keep practicing and trying new things in NumPy. Soon, you’ll get good at it. &lt;strong&gt;Happy coding!&lt;/strong&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;👉 Visit my &lt;a href="https://bit.ly/m/DevEasyLearn"&gt;blog&lt;/a&gt; 👈&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>python</category>
      <category>datascience</category>
      <category>programming</category>
      <category>coding</category>
    </item>
    <item>
      <title>A Comprehensive Guide to NumPy Arrays</title>
      <dc:creator>Maria Zayed</dc:creator>
      <pubDate>Fri, 03 Nov 2023 13:29:50 +0000</pubDate>
      <link>https://dev.to/mariazayed/a-comprehensive-guide-to-numpy-arrays-2onk</link>
      <guid>https://dev.to/mariazayed/a-comprehensive-guide-to-numpy-arrays-2onk</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Python has become a preferred language for data analysis due to its simplicity and robust library ecosystem. Among these, &lt;a href="https://numpy.org/"&gt;NumPy&lt;/a&gt; stands out with its efficient handling of numerical data. Let’s say you’re working with numbers for large data sets—something Python’s native data structures may find challenging. That’s where NumPy arrays come into play, making numerical computations seamless and speedy.&lt;/p&gt;

&lt;p&gt;In this guide, we’ll explore the world of NumPy arrays, starting from the basics, and then advancing to more complex uses. You’ll find this tool essential for tasks like forecasting sales, analyzing climate patterns, or making sense of today’s data-heavy world.&lt;/p&gt;

&lt;p&gt;So, are you ready to master NumPy arrays and boost your data analysis skills? Let’s dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction to NumPy
&lt;/h2&gt;

&lt;p&gt;NumPy, or Numerical Python, is a Python library that performs magic with arrays. While Python’s lists are versatile, they’re not always the most efficient for large numerical data sets. This is where NumPy comes in, making the process efficient and straightforward.&lt;/p&gt;

&lt;p&gt;Here’s why NumPy is a star:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt;: NumPy handles large data volumes way faster than native Python data structures.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Convenience&lt;/strong&gt;: It offers a broad range of mathematical functions, all in one place.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: NumPy smoothly handles everything from simple arithmetic to complex equations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To get started, you first need to install it. You can do this with a simple pip command in your command line or terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install numpy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once it’s installed, you can invite NumPy into your Python script by importing it, typically under the alias &lt;code&gt;np&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that, NumPy is all geared up and ready to assist you in your data analysis journey! &lt;/p&gt;

&lt;h2&gt;
  
  
  Basics of NumPy Arrays
&lt;/h2&gt;

&lt;p&gt;Creating a NumPy array is as simple. You can create one from a Python list or tuple using the array function, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np

# Create a Python list
my_list = [1, 2, 3, 4, 5]

# Turn the list into a NumPy array
my_array = np.array(my_list)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Voila! You’ve just created your first NumPy array. It wasn’t so hard, was it?&lt;/p&gt;

&lt;p&gt;Now, one of the reasons NumPy arrays are so special is their ability to handle different dimensions of data. They’re shape-shifters! You can have a one-dimensional array (like the one we just created), a two-dimensional array (think of it as a matrix), or even more dimensions if you’re feeling adventurous.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Create a 2D array
my_2D_array = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Array Initialization and Attributes
&lt;/h2&gt;

&lt;p&gt;Initializing a NumPy array is simple and straightforward. In Python, all we need is a sequence-like object such as a list or a tuple, and voila, you have your NumPy array!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np

# Start with a Python list
python_list = [10, 20, 30, 40, 50]

# Convert it into a NumPy array
numpy_array = np.array(python_list)

print(numpy_array)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run this, it will output: &lt;code&gt;[10 20 30 40 50]&lt;/code&gt;. Just like that, you’ve created your first NumPy array!&lt;/p&gt;

&lt;p&gt;Now, you might be wondering, “What’s the big deal? It looks just like a list!” Well, my friends, it’s what’s inside that counts. NumPy arrays come equipped with a whole bunch of attributes that make them more than just a list. These attributes are like secret superpowers that let you know more about your array.&lt;/p&gt;

&lt;p&gt;Some of the main attributes you will use are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ndim&lt;/strong&gt;: This tells you the number of dimensions of your array. It’s like knowing how many floors a building has!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;shape&lt;/strong&gt;: This provides the size of each dimension. It’s similar to knowing how many rooms are on each floor!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;size&lt;/strong&gt;: This tells you the total number of elements in the array. Like knowing how many people are in the building!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;dtype&lt;/strong&gt;: This reveals the type of elements stored in the array. It’s akin to knowing if the people in the building are adults, children, or pets!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s bring this to life with our &lt;code&gt;numpy_array&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;print("Dimensions: ", numpy_array.ndim)
print("Shape: ", numpy_array.shape)
print("Size: ", numpy_array.size)
print("Data type: ", numpy_array.dtype)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this gives us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dimensions: 1
Shape: (5,)
Size: 5
Data type: int64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there you have it! We have a 1-dimensional array (a building with one floor), with 5 elements (five rooms on that floor), totaling 5 elements (five people in the building), and they’re all integers (all adults, perhaps).&lt;/p&gt;

&lt;p&gt;The power of NumPy arrays lies in their simplicity and functionality. They’re not just containers for numbers; they’re versatile tools that provide valuable information about your data, making your journey into data analysis that much smoother.&lt;/p&gt;

&lt;h2&gt;
  
  
  NumPy Array Operations
&lt;/h2&gt;

&lt;p&gt;Remember how, in the old days, performing arithmetic operations on multiple data points required loops, resulting in long-winded and complex codes? Well, with NumPy, you can bid those days goodbye! It lets you perform element-wise operations, which are both time-saving and efficient. Let’s see it in action!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np

# Let's create two NumPy arrays
array1 = np.array([1, 2, 3])
array2 = np.array([4, 5, 6])

# We'll add them
array_add = array1 + array2

print("Added array: ", array_add) # [5 7 9]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As simple as adding two numbers, right? The plus operator performed an element-wise addition between two arrays. And the best part? It’s not just limited to addition; you can subtract (-), multiply (*), divide (/), and even find modulus (%) and perform integer division (//). NumPy really does make math fun, doesn’t it?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Subtract the arrays
array_subtract = array1 - array2
print("Subtracted array: ", array_subtract)

# Multiply the arrays
array_multiply = array1 * array2
print("Multiplied array: ", array_multiply)

# Divide the arrays
array_divide = array1 / array2
print("Divided array: ", array_divide)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These operations will output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Subtracted array: [-3 -3 -3]
Multiplied array: [ 4 10 18]
Divided array: [0.25 0.4  0.5 ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it’s not just arithmetic operations, NumPy supports a range of logical operations too. Ever wanted to compare two datasets and see which elements are greater, lesser, or equal? NumPy Arrays got you covered! Just use the comparison operators (&amp;lt;, &amp;gt;, ==, !=, etc.), and you’re set.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Compare the arrays
array_compare = array1 &amp;gt; array2

print("Comparison Result: ", array_compare)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will output &lt;code&gt;Comparison Result: [False False False]&lt;/code&gt; meaning all elements in &lt;code&gt;array1&lt;/code&gt; are not greater than &lt;code&gt;array2&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mathematical Functions with Arrays
&lt;/h2&gt;

&lt;p&gt;Think of mathematical functions in NumPy as a fantastic array of spices in your kitchen. They add that ‘extra something‘ to make your data taste just right. From calculating square roots to logarithms, these built-in mathematical functions are here to simplify your life. Let’s cook up some examples!&lt;/p&gt;

&lt;p&gt;First, let’s create a NumPy array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np

# Create a NumPy array
array = np.array([1, 4, 9, 16, 25])

print("Our array: ", array)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll get Our array: &lt;code&gt;[ 1 4 9 16 25]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Say we want to find the square root of each element. Instead of creating a loop and calling the sqrt function individually for each element, we can just use &lt;code&gt;np.sqrt()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np

array = np.array([1, 4, 9, 16, 25])

# Apply the square root function
sqrt_array = np.sqrt(array)

print("Square root: ", sqrt_array)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will output &lt;code&gt;Square root: [1.0, 2.0, 3.0, 4.0, 5.0]&lt;/code&gt; – the square root of each element.&lt;/p&gt;

&lt;p&gt;Similarly, we can calculate the logarithm of each element using &lt;code&gt;np.log()&lt;/code&gt;, exponentiate with &lt;code&gt;np.exp()&lt;/code&gt;, or find the sine with &lt;code&gt;np.sin()&lt;/code&gt;. The possibilities are almost endless!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Apply the log function
log_array = np.log(array)
print("Natural Logarithm: ", log_array)

# Apply the exponential function
exp_array = np.exp(array)
print("Exponential: ", exp_array)

# Apply the sine function
sin_array = np.sin(array)
print("Sine values: ", sin_array)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running these functions will give you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Natural Logarithm: [0.         1.38629436 2.19722458 2.77258872 3.21887582]
Exponential: [2.71828183e+00 5.45981500e+01 8.10308393e+03 8.88611052e+06 7.20048993e+10]
Sine values: [ 0.84147098 -0.7568025   0.41211849 -0.28790332 -0.13235175]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s a lot of powerful mathematics done in just a few lines of code, wouldn’t you agree? These mathematical functions, when paired with the power of NumPy arrays, make complex calculations a breeze.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aggregation Functions
&lt;/h2&gt;

&lt;p&gt;Consider aggregation functions as your personal magnifying glass into the world of data. They help you zoom out and view the big picture by providing summaries of the data. Whether it’s finding the maximum, minimum, sum, or average, these functions get you insights in no time. So, let’s dive in and see them in action.&lt;/p&gt;

&lt;p&gt;First, let’s whip up a NumPy array for us to explore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np

# Let's create a NumPy array
array = np.array([1, 2, 3, 4, 5])

print("Our array: ", array)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will output: &lt;code&gt;Our array: [1 2 3 4 5]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, say we’re keen to find the maximum value in our array. In comes &lt;code&gt;np.max()&lt;/code&gt;, our maximum-finding wizard!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Find the maximum
max_value = np.max(array)

print("Maximum value: ", max_value)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will return: &lt;code&gt;Maximum value: 5&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the same way, we can find the minimum value using &lt;code&gt;np.min()&lt;/code&gt;, the sum of all elements using &lt;code&gt;np.sum()&lt;/code&gt;, and the average value using &lt;code&gt;np.mean()&lt;/code&gt;. Here’s how:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Find the minimum
min_value = np.min(array)
print("Minimum value: ", min_value)

# Find the sum
sum_value = np.sum(array)
print("Sum: ", sum_value)

# Find the average
average_value = np.mean(array)
print("Average: ", average_value)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running these lines will give:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Minimum value: 1
Sum: 15
Average: 3.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But wait, there’s more! Aggregation functions are not limited to just one-dimensional arrays. They work wonderfully with multi-dimensional arrays too, giving you the flexibility to aggregate across specific dimensions using the axis parameter. Let’s take an example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np

# Create a 2D NumPy array
array_2D = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

print("Our 2D array: \n", array_2D)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this code will give us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Our 2D array: 

 [[1 2 3]
 [4 5 6]
 [7 8 9]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when you use the same aggregation functions as before, they operate on the entire array. Let’s find the sum of all elements in this 2D array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Sum all elements
sum_value_2D = np.sum(array_2D)

print("Sum of all elements: ", sum_value_2D)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will return &lt;code&gt;Sum of all elements: 45&lt;/code&gt;, which is the sum of all numbers from 1 to 9.&lt;/p&gt;

&lt;p&gt;Here’s where things get interesting. What if you want to find the sum of each row or each column separately? This is where the axis parameter comes into play.&lt;/p&gt;

&lt;p&gt;When you set &lt;code&gt;axis=0&lt;/code&gt;, the function will calculate the aggregate for each column. When you set &lt;code&gt;axis=1&lt;/code&gt;, it will do so for each row. Let’s see this in action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Sum each column
sum_value_columns = np.sum(array_2D, axis=0)
print("Sum of each column: ", sum_value_columns)

# Sum each row
sum_value_rows = np.sum(array_2D, axis=1)
print("Sum of each row: ", sum_value_rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These will output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sum of each column: [12 15 18]
Sum of each row: [ 6 15 24]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the axis parameter gives you more control over how the aggregation functions operate. This feature can prove incredibly useful when you’re working with large, multi-dimensional datasets, allowing you to obtain targeted summaries of your data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Array Manipulation
&lt;/h2&gt;

&lt;p&gt;Array manipulation is the set of tools that allows us to change the array into any shape we desire. Whether you need to reshape, split, or merge your data, array manipulation has got you covered.&lt;/p&gt;

&lt;p&gt;We’ll start by creating a NumPy array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np

# Create a NumPy array
array = np.array([1, 2, 3, 4, 5, 6])

print("Our array: ", array)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output will be &lt;code&gt;Our array: [1 2 3 4 5 6]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, suppose we want to reshape this array into a 2×3 matrix. That’s where &lt;code&gt;np.reshape()&lt;/code&gt; comes into play:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Reshape the array
reshaped_array = np.reshape(array, (2, 3))

print("Reshaped array: \n", reshaped_array)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will result in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reshaped array: 
 [[1 2 3]
 [4 5 6]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like that, we’ve reshaped our array! But what if you have two separate arrays that you need to combine into one? NumPy provides functions like &lt;code&gt;np.concatenate()&lt;/code&gt;, &lt;code&gt;np.vstack()&lt;/code&gt;, and &lt;code&gt;np.hstack()&lt;/code&gt; for just such occasions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Create two NumPy arrays
array_1 = np.array([1, 2, 3])
array_2 = np.array([4, 5, 6])

# Concatenate the arrays
concat_array = np.concatenate((array_1, array_2))

print("Concatenated array: ", concat_array)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will give you &lt;code&gt;Concatenated array: [1 2 3 4 5 6]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But what if you need to go in the opposite direction and split your data? You’re in luck! Functions like &lt;code&gt;np.split()&lt;/code&gt; can help you do just that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Split the array into three equal parts
split_array = np.split(concat_array, 3)

print("Split array: ", split_array)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will output &lt;code&gt;Split array: [array([1, 2]), array([3, 4]), array([5, 6])]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Array manipulation provides a versatile toolkit for modifying your data to better suit your needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt; &lt;a href="https://numpy.org/doc/stable/reference/generated/numpy.array.html"&gt;Numpy: numpy.array&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deveasylearn.com/understanding-array-shapes-in-numpy/"&gt;Understanding Array Shapes in NumPy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deveasylearn.com/understanding-array-broadcasting-in-numpy/"&gt;Understanding Array Broadcasting in NumPy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deveasylearn.com/masking-and-boolean-indexing-a-smart-data-filtering-in-python/"&gt;Masking and Boolean Indexing: A Smart Data Filtering in Python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;In conclusion, we’ve explored NumPy arrays and discussed array attributes, operations, math functions, and the power of aggregation functions.&lt;/p&gt;

&lt;p&gt;NumPy’s simplicity and power make it a must-have tool for anyone diving into data analysis. Whether reshaping data, performing calculations on multi-dimensional arrays, or swiftly analyzing data, NumPy has you covered.&lt;/p&gt;

&lt;p&gt;But don’t just take my word for it. Continue to practice and play with these tools, and you’ll see for yourself what you can achieve. &lt;strong&gt;Happy coding!&lt;/strong&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;👉 Visit my personal &lt;a href="https://bit.ly/m/DevEasyLearn"&gt;blog&lt;/a&gt; 👈&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>python</category>
      <category>datascience</category>
      <category>programming</category>
      <category>coding</category>
    </item>
    <item>
      <title>Subjects and BehaviorSubjects in Angular: A Deep Dive</title>
      <dc:creator>Maria Zayed</dc:creator>
      <pubDate>Sat, 28 Oct 2023 14:21:45 +0000</pubDate>
      <link>https://dev.to/mariazayed/subjects-and-behaviorsubjects-in-angular-a-deep-dive-4kf2</link>
      <guid>https://dev.to/mariazayed/subjects-and-behaviorsubjects-in-angular-a-deep-dive-4kf2</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hello developers, today we will discuss two important tools in Angular: Subjects and BehaviorSubjects. They are crucial for sharing data smoothly in your app, which is essential for modern web developers.&lt;/p&gt;

&lt;p&gt;Web development has grown a lot, and now users expect very interactive and responsive apps. Angular is a helpful tool that lets developers meet these expectations. A big part of this help comes from how Angular handles data using Subjects and BehaviorSubjects.&lt;/p&gt;

&lt;p&gt;In the next sections, we will explore Subjects and BehaviorSubjects more, see how they work with examples&lt;/p&gt;

&lt;h2&gt;
  
  
  Observables
&lt;/h2&gt;

&lt;p&gt;Subjects are fundamental in ensuring seamless data flow across your application. Before diving into Subjects, it’s essential to grasp the basics of Observables and Observers, as Subjects are an extension of these concepts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://rxjs.dev/guide/observable" rel="noopener noreferrer"&gt;Observables&lt;/a&gt; are like radio stations, broadcasting data, while Observers are like radio listeners, tuned in to receive this data. In Angular, Observables dispatch data streams, and Observers subscribe to these streams, reacting to any new data emitted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subjects
&lt;/h2&gt;

&lt;p&gt;Now, after we have a brief understanding of what observables are, let’s imagine a scenario where you wish to share a single data source among multiple parts of your application. This is where &lt;a href="https://rxjs.dev/guide/subject" rel="noopener noreferrer"&gt;Subjects&lt;/a&gt; come into play. Subjects are a special type of Observable that can multicast data to many Observers at once. They ensure that all subscribers share the same data stream, promoting real-time data consistency across your app.&lt;/p&gt;

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

&lt;p&gt;Subjects have two key attributes, multicasting, and their nature as “hot” observables. Let’s talk about each one in detail&lt;/p&gt;

&lt;h3&gt;
  
  
  Multicasting
&lt;/h3&gt;

&lt;p&gt;Multicasting is a term used to describe a scenario where a single data emission is shared with multiple subscribers. Unlike unicast operations, where each subscriber gets an independent version of the data stream, multicasting ensures that all subscribers share the same data stream. This is especially useful when you have multiple parts of your application that need to react to or process the same data in real time.&lt;/p&gt;

&lt;p&gt;In the context of Subjects within Angular, multicasting is a native capability. When a Subject emits a new data value, this value is sent to all subscribers simultaneously. This shared nature of data emission facilitates real-time data consistency across various parts of your application, ensuring that every subscriber receives and processes the same data.&lt;/p&gt;

&lt;p&gt;Let’s take the following example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Subject } from 'rxjs';

// Create a new Subject
const mySubject = new Subject&amp;lt;number&amp;gt;();

// Subscribe two observers to the Subject
mySubject.subscribe(value =&amp;gt; {
  console.log(`Observer 1 received: ${value}`);
});

mySubject.subscribe(value =&amp;gt; {
  console.log(`Observer 2 received: ${value}`);
});

// Emit values through the Subject
mySubject.next(10);
mySubject.next(20);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the following output&lt;/p&gt;

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

&lt;p&gt;In this example, we create a Subject &lt;code&gt;mySubject&lt;/code&gt;. We then subscribe two observers to &lt;code&gt;mySubject&lt;/code&gt;. When we emit values using &lt;code&gt;mySubject.next(value)&lt;/code&gt;, both observers receive the emitted values simultaneously. This showcases the multicasting nature of Subjects.&lt;/p&gt;

&lt;h3&gt;
  
  
  “Hot” Observables
&lt;/h3&gt;

&lt;p&gt;The concept of “hot” and “cold” observables is foundational in understanding how data streams behave in &lt;a href="https://www.techtarget.com/searchapparchitecture/definition/reactive-programming" rel="noopener noreferrer"&gt;reactive programming&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cold Observables&lt;/strong&gt;: A cold observable starts emitting data only when it has a subscriber. Each subscriber gets its own independent execution of the observable, meaning the data stream is started afresh for each subscriber.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hot Observables&lt;/strong&gt;: On the contrary, hot observables begin emitting data as soon as they are created, irrespective of whether or not they have subscribers. The data is emitted in real-time, and any subscriber that hooks into a hot observable receives data from the point of subscription onwards. They do not get the data that was emitted before they subscribed.
Let’s demonstrate both, the hot and cold observables in practical examples respectively
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Hot observable example

import { Subject } from 'rxjs';

// Create a new Subject
const mySubject = new Subject&amp;lt;number&amp;gt;();

// Emit a value before any observer has subscribed
mySubject.next(10);

// Subscribe an observer to the Subject
mySubject.subscribe(value =&amp;gt; {
  console.log(`Received: ${value}`);
});

// Emit another value
mySubject.next(20);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see this output: &lt;code&gt;Received: 20&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In this example, even though a value is emitted before any observer has subscribed, the observer only receives the value emitted after it subscribed, not the value emitted before. This behavior is typical of hot observables. They are active even before subscription and the data is emitted in real-time, but subscribers only get the data from the point they subscribed onwards.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Cold observable example

import { Observable } from 'rxjs';

// Create a cold observable
const coldObservable = new Observable&amp;lt;number&amp;gt;(observer =&amp;gt; {
  console.log('Observable execution');
  observer.next(Math.random());
});

// Subscribe observer 1 to the cold observable
coldObservable.subscribe(value =&amp;gt; {
  console.log(`Observer 1 received: ${value} (random number)`);
});

// Subscribe observer 2 to the cold observable
coldObservable.subscribe(value =&amp;gt; {
  console.log(`Observer 2 received: ${value} (random number)`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see this output&lt;/p&gt;

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

&lt;p&gt;In this example, we create a cold observable &lt;code&gt;coldObservable&lt;/code&gt; that emits a random number when an observer subscribes to it. We then subscribe two separate observers to &lt;code&gt;coldObservable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The output shows that each observer triggers the observable’s execution separately, and each observer receives a different random number. This is characteristic of cold observables, where each subscriber triggers a new execution of the observable and receives a unique set of emitted values.&lt;/p&gt;

&lt;p&gt;This behavior contrasts with hot observables (like Subjects), where all observers share the same execution of the observable and receive the same values.&lt;/p&gt;

&lt;p&gt;To summarize, Subjects are categorized as hot observables because they start emitting data right away upon creation. This characteristic of Subjects ensures that data is emitted in real-time, making them a suitable choice for scenarios that demand real-time data handling, such as live updates or real-time monitoring systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  BehaviorSubjects
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubject" rel="noopener noreferrer"&gt;BehaviorSubject&lt;/a&gt; is a special kind of Subject, it comes with the unique feature of holding onto the most recent value. This feature is powerful that helps in managing the state of your application effectively.&lt;/p&gt;

&lt;p&gt;When we create a BehaviorSubject, we start with an initial value. Unlike Subjects, BehaviorSubjects remember the last value they held, which is very useful.&lt;/p&gt;

&lt;p&gt;BehaviorSubjects are good at holding onto a value and sharing it across different parts of a website. When the value changes, BehaviorSubjects ensures every part of the website knows about the new value.&lt;/p&gt;

&lt;p&gt;Here’s a simple example to show how BehaviorSubjects work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { BehaviorSubject } from 'rxjs';

// Create a BehaviorSubject with a starting value of 0
const behaviorSubject = new BehaviorSubject&amp;lt;number&amp;gt;(0);

// A part of the website subscribes to the BehaviorSubject
behaviorSubject.subscribe(value =&amp;gt; {
  console.log(`Part 1 received: ${value}`);
});

// Change the value to 1
behaviorSubject.next(1);

// Another part of the website subscribes
behaviorSubject.subscribe(value =&amp;gt; {
  console.log(`Part 2 received: ${value}`);
});

// Change the value to 2
behaviorSubject.next(2);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see this output&lt;/p&gt;

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

&lt;p&gt;Let’s break it down&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We create a BehaviorSubject with a starting value of 0.&lt;/li&gt;
&lt;li&gt;Part 1 of the website subscribes to the BehaviorSubject and knows the value is 0.&lt;/li&gt;
&lt;li&gt;When we change the value to 1, Part 1 knows about it.&lt;/li&gt;
&lt;li&gt;When Part 2 of the website subscribes, it immediately knows the value is 1, not 0.&lt;/li&gt;
&lt;li&gt;When we change the value to 2, both parts know about it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This shows how BehaviorSubjects share values across different parts of a website.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparing Subjects and BehaviorSubjects
&lt;/h2&gt;

&lt;p&gt;In Angular, Subjects and BehaviorSubjects are tools that help us manage and share data in our apps. Although they seem similar, they have some differences. Let’s talk about these differences in a simple way and see when to use which tool.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Subjects&lt;/strong&gt;: Ideal for scenarios where multicasting is required but there’s no need for an initial value or to remember the last emitted value. Subjects are simpler and are a great fit for handling events or multicast notifications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BehaviorSubjects&lt;/strong&gt;: Perfect for state management purposes where the initial state is important, or whenever you need to ensure new subscribers receive the last emitted value. They are invaluable when parts of your app need to stay updated with the current value.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;In conclusion, we learned about two helpful tools in Angular: Subjects and BehaviorSubjects.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Subjects&lt;/strong&gt;: They help share data quickly with many parts of your app at once.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BehaviorSubjects&lt;/strong&gt;: They do the same, but also remember the last value shared, which is helpful in many situations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tools are very useful in making sure your app works smoothly and keeps data organized. There’s a lot you can do with Subjects and BehaviorSubjects in Angular, and using them can make handling data in your app much easier. &lt;strong&gt;Happy coding!&lt;/strong&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;👉 Visit my personal &lt;a href="https://bit.ly/m/DevEasyLearn" rel="noopener noreferrer"&gt;blog&lt;/a&gt; 👈&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>angular</category>
      <category>frontend</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Send Parallel API Calls in Angular</title>
      <dc:creator>Maria Zayed</dc:creator>
      <pubDate>Fri, 20 Oct 2023 16:28:01 +0000</pubDate>
      <link>https://dev.to/mariazayed/how-to-send-parallel-api-calls-in-angular-kp8</link>
      <guid>https://dev.to/mariazayed/how-to-send-parallel-api-calls-in-angular-kp8</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hello developers, today we will discuss how to make our Angular apps run faster and smoother. We all know, that when using an app, if it takes too long to load, we might not like it. So, we are going to talk about solving this problem by using something called parallel API calls.&lt;/p&gt;

&lt;p&gt;In simple words, when our apps need to collect different pieces of information, doing this one by one can be slow. But with parallel API calls, it’s like having many helpers who are fetching different things all at the same time. This way, our apps can run faster and our users will be happy.&lt;/p&gt;

&lt;p&gt;In this article, we will implement both sequential and parallel API calls to see the differences in a practical example (see the full working code from here)&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up our project
&lt;/h2&gt;

&lt;p&gt;Starting off, we create a new Angular project. It’s pretty simple, just open up your terminal or command prompt, and type in the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ng new ng-paraller-api-calls&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command asks Angular to create a new project for us named ng-parallel-api-calls. Once you run it, Angular does all the hard work, setting up a new folder with all the files we need!&lt;/p&gt;

&lt;p&gt;Now, we make two components – one for the sequential calls and another for the parallel call&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ng generate component sequential&lt;br&gt;
ng generate component parallel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;By following these steps, we’ve created the base of our Angular project. We’ve got our components, and a helpful service – all set to build upon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Sequential API Call Component
&lt;/h2&gt;

&lt;p&gt;Now that we’ve got our Angular project up and running, let’s start building our Sequential API Call Component. This component will make one API call, wait for it to finish, and then make the next call.&lt;/p&gt;

&lt;p&gt;Let’s start by writing the code for our &lt;code&gt;SequentialComponent&lt;/code&gt;. We will use &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjsonplaceholder.typicode.com%2F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjsonplaceholder.typicode.com%2F" alt="JSONPlaceholder"&gt;&lt;/a&gt; as our mock API for fetching data, as it provides realistic endpoints for testing. Here’s how our component’s TypeScript file will look:&lt;/p&gt;

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

// sequential.component.ts

export class SequentialComponent {
    postData!: PostInterface;
    userData!: UserInterface;
    isLoading = false;

    constructor(private http: HttpClient) {
    }

    ngOnInit() {
        this.isLoading = true;
        this.http.get&amp;lt;PostInterface&amp;gt;('https://jsonplaceholder.typicode.com/posts/1').subscribe(
            (data: PostInterface) =&amp;gt; {
                this.postData = data;
                this.http.get&amp;lt;UserInterface&amp;gt;('https://jsonplaceholder.typicode.com/users/1').subscribe(
                    (data: UserInterface) =&amp;gt; {
                        this.userData = data;
                        this.isLoading = false;
                    },
                    (error) =&amp;gt; {
                        console.error('Error in second API call', error);
                        this.isLoading = false;
                    }
                );
            },
            (error) =&amp;gt; {
                console.error('Error in first API call', error);
                this.isLoading = false;
            }
        );
    }
}


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

&lt;/div&gt;

&lt;p&gt;In this code, we are telling our component to fetch some post data first and, once received, fetch some user data. We are also managing a loading state to show whether our component is busy fetching data. Also, we created &lt;code&gt;PostInterface&lt;/code&gt; and &lt;code&gt;UserInterface&lt;/code&gt; to enhance type safety, ensure data consistency, and reduce runtime errors by catching issues at compile time.&lt;/p&gt;

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

// post.interface.ts

export interface PostInterface {
    id: number;
    userId: number;
    title: string;
    body: string;
}


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

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

// user.interface.ts

export interface UserInterface {
    id: string
    name: string
    username: string
    email: string
    address: {
        street: string
        suite: string
        city: string
        zipcode: string
        geo: {
            lat: string
            lng: string
        }
    },
    phone: string
    website: string
    company: {
        name: string
        catchPhrase: string
        bs: string
    }
}


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

&lt;/div&gt;

&lt;p&gt;And following is our simple UI&lt;/p&gt;

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

// sequential.component.html

&amp;lt;div *ngIf="isLoading" class="alert alert-info"&amp;gt;Loading data...&amp;lt;/div&amp;gt;

&amp;lt;div *ngIf="!isLoading" class="row"&amp;gt;
    &amp;lt;div class="col-md-6"&amp;gt;
        &amp;lt;div class="card mb-3"&amp;gt;
            &amp;lt;div class="card-header fw-bold"&amp;gt;Post Data&amp;lt;/div&amp;gt;
            &amp;lt;div class="card-body"&amp;gt;
                &amp;lt;h5 class="card-title"&amp;gt;{{ postData.title }}&amp;lt;/h5&amp;gt;
                &amp;lt;br&amp;gt;
                &amp;lt;p class="card-text"&amp;gt;{{ postData.body }}&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div class="col-md-6"&amp;gt;
        &amp;lt;div class="card mb-3"&amp;gt;
            &amp;lt;div class="card-header fw-bold"&amp;gt;User Data&amp;lt;/div&amp;gt;
            &amp;lt;div class="card-body"&amp;gt;
                &amp;lt;h5 class="card-title"&amp;gt;{{ userData.name }}&amp;lt;/h5&amp;gt;
                &amp;lt;br&amp;gt;
                &amp;lt;p class="card-text"&amp;gt;&amp;lt;strong&amp;gt;Username:&amp;lt;/strong&amp;gt; {{ userData.username }}&amp;lt;/p&amp;gt;
                &amp;lt;p class="card-text"&amp;gt;&amp;lt;strong&amp;gt;Email:&amp;lt;/strong&amp;gt; {{ userData.email }}&amp;lt;/p&amp;gt;
                &amp;lt;p class="card-text"&amp;gt;&amp;lt;strong&amp;gt;Phone:&amp;lt;/strong&amp;gt; {{ userData.phone }}&amp;lt;/p&amp;gt;
                &amp;lt;p class="card-text"&amp;gt;&amp;lt;strong&amp;gt;Address:&amp;lt;/strong&amp;gt; {{ userData.address.street }}
                    , {{ userData.address.city }}&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;


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

&lt;/div&gt;

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

&lt;h3&gt;
  
  
  The problem
&lt;/h3&gt;

&lt;p&gt;While this approach is quite straightforward, it has a few downsides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance:&lt;/strong&gt; Since we are waiting for the first call to complete before making the second, it takes more time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Readability:&lt;/strong&gt; The code becomes harder to read as we nest more calls inside each other.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Handling:&lt;/strong&gt; If any call fails, managing errors becomes tricky, especially when we have several nested calls.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Building the Parallel API Call Component
&lt;/h2&gt;

&lt;p&gt;Let’s explore how to build the Parallel API Call Component in Angular. This approach allows us to send multiple requests at the same time, making our app faster and more efficient.&lt;/p&gt;

&lt;p&gt;To begin, we’ll make parallel API calls using a handy tool in Angular called &lt;code&gt;forkJoin&lt;/code&gt;. &lt;a href="https://www.learnrxjs.io/learn-rxjs/operators/combination/forkjoin" rel="noopener noreferrer"&gt;forkJoin&lt;/a&gt; is an RxJS operator that “&lt;em&gt;Wait for Observables to complete and then combines the last values they emitted&lt;/em&gt;”. In other words, &lt;code&gt;forkJoin&lt;/code&gt; allows you to wait for multiple Observables to complete and then emit their latest values as an array.&lt;/p&gt;

&lt;p&gt;Here’s the code snippet for our &lt;code&gt;ParallelComponent&lt;/code&gt;:&lt;/p&gt;

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

// parallel.component.ts

export class ParallelComponent implements OnInit {

    postData!: PostInterface;
    userData!: UserInterface;
    isLoading = false;

    constructor(private http: HttpClient) {
    }

    ngOnInit() {
        this.isLoading = true;

        forkJoin({
            postData: this.http.get('https://jsonplaceholder.typicode.com/posts/1'),
            userDate: this.http.get('https://jsonplaceholder.typicode.com/users/1')
        }).subscribe(
            (results: any) =&amp;gt; {
                this.postData = results.postData;
                this.userData = results.userDate;
                this.isLoading = false;
            },
            (error) =&amp;gt; {
                console.error('Error in API calls', error);
                this.isLoading = false;
            }
        );
    }
}


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

&lt;/div&gt;

&lt;p&gt;We will use the same UI as in &lt;code&gt;SequentialComponent&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In this approach, &lt;code&gt;forkJoin&lt;/code&gt; helps us make API calls in parallel. We’re not waiting for the first call to complete to start the next one. Instead, we’re kicking off both at the same time!&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages Over the Sequential Approach
&lt;/h3&gt;

&lt;p&gt;This parallel method comes with several benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speed:&lt;/strong&gt; Because we’re not waiting around, our app gets the data faster.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Readability:&lt;/strong&gt; The code is cleaner and easier to understand, without the nesting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Handling:&lt;/strong&gt; Managing errors is simpler since forkJoin helps us catch issues in any of the calls.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Demonstrating the Performance Improvement
&lt;/h2&gt;

&lt;p&gt;When you run both components, you’ll notice that the &lt;code&gt;ParallelComponent&lt;/code&gt; fetches and displays data noticeably faster than the &lt;code&gt;SequentialComponent&lt;/code&gt;. This speed-up is because we’re not waiting for one task to finish to start the next, showcasing the efficiency of parallel API calls.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/bb-tutorials-and-thoughts/how-to-make-parallel-api-calls-in-angular-applications-4b99227e7458" rel="noopener noreferrer"&gt;Medium: How To Make Parallel API calls in Angular Applications&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;In conclusion, we looked at how making one call at a time can slow us down. It’s like waiting in a long line. But, by using parallel API calls, we can speed things up! We used something called &lt;code&gt;forkJoin&lt;/code&gt; in Angular to do many things at once. This change made our app faster. The code is now easier to read and manage.&lt;/p&gt;

&lt;p&gt;So, to all the developers reading, think about using parallel API calls in your Angular apps. It’s a way to make your apps better and your coding more fun. &lt;strong&gt;Happy coding!&lt;/strong&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;👉 Visit my personal &lt;a href="https://bit.ly/m/DevEasyLearn" rel="noopener noreferrer"&gt;blog&lt;/a&gt; 👈&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>angular</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
