Book Image

Building Data-Driven Applications with Danfo.js

By : Rising Odegua, Stephen Oni
Book Image

Building Data-Driven Applications with Danfo.js

By: Rising Odegua, Stephen Oni

Overview of this book

Most data analysts use Python and pandas for data processing for the convenience and performance these libraries provide. However, JavaScript developers have always wanted to use machine learning in the browser as well. This book focuses on how Danfo.js brings data processing, analysis, and ML tools to JavaScript developers and how to make the most of this library to build data-driven applications. Starting with an overview of modern JavaScript, you’ll cover data analysis and transformation with Danfo.js and Dnotebook. The book then shows you how to load different datasets, combine and analyze them by performing operations such as handling missing values and string manipulations. You’ll also get to grips with data plotting, visualization, aggregation, and group operations by combining Danfo.js with Plotly. As you advance, you’ll create a no-code data analysis and handling system and create-react-app, react-table, react-chart, Draggable.js, and tailwindcss, and understand how to use TensorFlow.js and Danfo.js to build a recommendation system. Finally, you’ll build a Twitter analytics dashboard powered by Danfo.js, Next.js, node-nlp, and Twit.js. By the end of this app development book, you’ll be able to build and embed data analytics, visualization, and ML capabilities into any JavaScript app in server-side Node.js or the browser.
Table of Contents (18 chapters)
1
Section 1: The Basics
3
Section 2: Data Analysis and Manipulation with Danfo.js and Dnotebook
10
Section 3: Building Data-Driven Applications

Overview of scopes and closures

In the Understanding the difference between let and var section, we discussed scope and talked about how var is available in the global scope, as well as in the function scope. In this section, we will be moving into scope and closures in a little more depth.

Scope

To understand scope, let's start with the following code:

let food = "sandwich" 
function data() {
}

The food variables and data function are both assigned to the global scope; hence, they are termed a global variable and global function. These global variables and functions are always accessible to every other scope and program in the JavaScript file.

The local scope can further be grouped as follows:

  • Function scope
  • Block scope

Function scope is only available within a function. That is, all variables and functions created within a function scope are not accessible outside the function, and only exist when the function scope is available, for example:

function func_scope(){
// function scope exist here
}

The block scope exists in specific contexts only. For instance, it can exist within a curly brace, { }, along with the if statement, for loop, and while loop. Two more examples are presented in the following code snippets:

if(true){
// if block scope
}

In the preceding if statement, you can see that the block scope only exists inside the curly braces, and all variables declared inside the if statement are local to it. Another example is a for loop, as shown in the following code snippet:

for(let i=0; i< 5; i++){
//for loop's block scope
}

The block scope also exists inside the curly braces of a for...loop. Here, you have access to the i counter, and any variables declared inside cannot be accessed outside the block.

Next, let's understand the concept of closures.

Closure

Closure makes use of the idea of scope within functions. Remember we agreed that the variables declared within a function scope are not accessible outside the function scope. Closure gives us the ability to make use of these private properties (or variables).

Let's say we want to create a program that will always add the values 2 and 1 to an estimate variable representing a population estimate. One way to do this is shown in the following code:

let estimate = 6000;
function add_1() {
    return estimate + 1
}
function add_2() {
    return estimate + 2;
}
console.log(add_1()) // 60001 
console.log(add_2()) // 60002

There's nothing wrong with the preceding code, but as the code base becomes very big, we might lose track of the estimate value, perhaps a function along the line to update the value, and we may also want to make the global scope clean by making the global estimate variable a local variable.

Hence, we can create a function scope to do this for us and ultimately, clean the global scope. Here is an example in the following code snippet:

function calc_estimate(value) { 
  let estimate = value; 
  function add_2() { 
    console.log('add two', estimate + 2); 
  } 
  function add_1() { 
    console.log('add one', estimate + 1) 
  } 
  add_2(); 
  add_1(); 
}
calc_estimate(6000) //output: add two 60002 , add one 60001

The preceding code snippet is similar to the first one we defined, with just a tiny difference, that is, the function accepts the estimate value and then creates the add_2 and add_1 functions inside the calc_estimate function.

A better way to showcase closure using the preceding code is to have the ability to update the estimate value whenever we want and not at the instance where the function is called. Let's see an example of this:

function calc_estimate(value) { 
  let estimate = value; 
  function add_2() { 
    estimate += 2 
    console.log('add 2 to estimate', estimate); 
  } 
  return add_2; 
}
let add_2 = calc_estimate(50);
// we have the choice to add two to the value at any time in our code 
add_2() // add 2 to estimate 52 
add_2() // add 2 to estimate 54 
add_2() // add 2 to estimate 56

In the preceding code snippet, the inner function, add_2, will add the value 2 to the estimate variable, thereby changing the value. calc_estimate is called and assigned to a variable, add_2. With this, whenever we call add_2, we update the estimated value by 2.

We update the add_2 function inside calc_estimate to accept a value that can be used to update the estimate value:

function calc_estimate(value){ 
  let estimate = value; 
  function add_2(value2){ 
    estimate +=value2 
    console.log('add 2 to estimate', estimate); 
  } 
  return add_2; 
}
let add_2 = calc_estimate(50);
// we have the choice to add two to the value at any time in our code
 
add_2(2) // add 2 to estimate 52
add_2(4) // add 2 to estimate 56
add_2(1) // add 2 to estimate 5

Now that you've learned about scopes and closures, we will move to arrays, objects, and string methods in the following section.

Further reading

To go into closures in greater detail, check out the book Mastering JavaScript, by Ved Antani.