P-some: Wait for A Specified Number Of Promises to Be Fulfilled

p-some

Wait for a specified number of promises to be fulfilled

Useful when you need the fastest of multiple promises.

Install

$ npm install p-some

Usage

Checks 4 websites and logs the 2 fastest.

import got from 'got';
import pSome from 'p-some';

const input = [
	got.head('github.com').then(() => 'github'),
	got.head('google.com').then(() => 'google'),
	got.head('twitter.com').then(() => 'twitter'),
	got.head('medium.com').then(() => 'medium')
];

const [first, second] = await pSome(input, {count: 2});

console.log(first, second);
//=> 'google twitter'

API

pSome(input, options)

Returns a cancelable Promise that is fulfilled when count promises from input are fulfilled. The fulfilled value is an Array of the values from the input promises in the order they were fulfilled. If it becomes impossible to satisfy count, for example, too many promises rejected, it will reject with an AggregateError error.

If you pass in cancelable promises, specifically promises with a .cancel() method, that method will be called for the promises that are still unfulfilled when the returned Promise is either fulfilled or rejected.

input

Type: Iterable<Promise | unknown>

An Iterable collection of promises/values to wait for.

options

Type: object

count

Required
Type: number
Minimum: 1

Number of promises from input that have to be fulfilled until the returned promise is fulfilled.

filter

Type: Function

Receives the value resolved by the promise. Used to filter out values that doesn't satisfy a condition.

AggregateError

Exposed for instance checking.

FilterError

Exposed for instance checking.

Related

  • p-any - Wait for any promise to be fulfilled
  • p-one - Return true if any promise passes a testing function, similar to Array#some
  • More…

Author: Sindresorhus
Source Code: https://github.com/sindresorhus/p-some 
License: MIT License

#typescript #javascript #node

What is GEEK

Buddha Community

P-some: Wait for A Specified Number Of Promises to Be Fulfilled
Sofia  Maggio

Sofia Maggio

1649260800

Cl-online-learning: online Learning Algorithms

Cl-Online-Learning

A collection of machine learning algorithms for online linear classification written in Common Lisp.

Implemented algorithms

Binary classifier

  • Perceptron
  • AROW (Crammer, Koby, Alex Kulesza, and Mark Dredze. “Adaptive regularization of weight vectors.” Advances in neural information processing systems. 2009.)
  • SCW-I (Soft Confidence Weighted) (Wang, Jialei, Peilin Zhao, and Steven C. Hoi. “Exact Soft Confidence-Weighted Learning.” Proceedings of the 29th International Conference on Machine Learning (ICML-12). 2012.)
  • Logistic Regression with SGD or ADAM optimizer (Kingma, Diederik, and Jimmy Ba. “Adam: A method for stochastic optimization.” ICLR 2015)

Multiclass classifier

  • one-vs-rest ( K binary classifier required )
  • one-vs-one ( K*(K-1)/2 binary classifier required )

Command line tools

Installation

cl-online-learning is available from Quicklisp.

(ql:quickload :cl-online-learning)

When install from github repository,

cd ~/quicklisp/local-projects/
git clone https://github.com/masatoi/cl-online-learning.git

When using Roswell,

ros install masatoi/cl-online-learning

Usage

Prepare dataset

A data point is a pair of a class label (+1 or -1) and a input vector. Both of them have to be declared as single-float.

And dataset is represented as a sequence of data points. READ-DATA function is available to make a dataset from a sparse format used in LIBSVM (http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/). This function requires the number of features of that dataset.

;; Number of features
(defparameter a1a-dim 123)

;; Read dataset from file
(defparameter a1a
  (clol.utils:read-data
   (merge-pathnames #P"t/dataset/a1a" (asdf:system-source-directory :cl-online-learning))
   a1a-dim))

;; A data point
(car a1a)

; (-1.0
;  . #(0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0
;     1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
;     0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
;     1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
;     1.0 0.0 1.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
;     0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
;     0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0))

Define learner

A learner object is just a struct, therefore their constructor is available to make it.

(defparameter arow-learner (clol:make-arow a1a-dim 10))

Update and Train

To update the model destructively with one data point, use an update function corresponding to the model type.

(clol:arow-update arow-learner
                  (cdar a1a)  ; input
                  (caar a1a)) ; label

TRAIN function can be used to learn the dataset collectively.

(clol:train arow-learner a1a)

It may be necessary to call this function several times until learning converges. For now, the convergence test has not been implemented yet.

Predict and Test

(clol:arow-predict arow-learner (cdar a1a))
; => -1.0

(clol:test arow-learner a1a)
; Accuracy: 84.85981%, Correct: 1362, Total: 1605

Multiclass classification

For multiclass data, the label of the data point is an integer representing the index of the class. READ-DATA function with MULTICLASS-P keyword option is available for make such a dataset.

(defparameter iris-dim 4)

; A dataset in which a same label appears consecutively need to be shuffled
(defparameter iris
  (clol.utils:shuffle-vector
   (coerce (clol.utils:read-data
            (merge-pathnames #P"t/dataset/iris.scale"
                             (asdf:system-source-directory :cl-online-learning))
            iris-dim :multiclass-p t)
	   'simple-vector)))

(defparameter iris-train (subseq iris 0 100))
(defparameter iris-test (subseq iris 100))

ONE-VS-REST and ONE-VS-ONE are available for multiclass classification by using multiple binary classifiers. In many cases, ONE-VS-ONE is more accurate, but it requires more computational resource as the number of classes increases.

;; Define model
(defparameter arow-1vs1
  (clol:make-one-vs-one iris-dim      ; Input data dimension
                        3             ; Number of class
                        'arow 0.1)) ; Binary classifier type and its parameters

;; Train and test model
(clol:train arow-1vs1 iris-train)
(clol:test  arow-1vs1 iris-test)
; Accuracy: 98.0%, Correct: 49, Total: 50

Sparse data

For sparse data (most elements are 0), the data point is a pair of a class label and a instance of SPARSE-VECTOR struct, and a learner with SPARSE- prefix is used. READ-DATA function with SPARSE-P keyword option is available for make such a dataset.

For example, news20.binary data has too high dimensional features to handle with normal learners. However, by using the sparse version, the learner can be trained with practical computational resources.

(defparameter news20.binary-dim 1355191)
(defparameter news20.binary (clol.utils:read-data "/path/to/news20.binary" news20.binary-dim :sparse-p t))

(defparameter news20.binary.arow (clol:make-sparse-arow news20.binary-dim 10))
(time (loop repeat 20 do (clol:train news20.binary.arow news20.binary)))
;; Evaluation took:
;;   1.527 seconds of real time
;;   1.526852 seconds of total run time (1.526852 user, 0.000000 system)
;;   100.00% CPU
;;   5,176,917,149 processor cycles
;;   11,436,032 bytes consed
(clol:test news20.binary.arow news20.binary)
; Accuracy: 99.74495%, Correct: 19945, Total: 19996

In a similar way, the sparse version learners are also available in multiclass classification.

(defparameter news20-dim 62060)
(defparameter news20-train (clol.utils:read-data "/path/to/news20.scale" news20-dim :sparse-p t :multiclass-p t))
(defparameter news20-test (clol.utils:read-data "/path/to/news20.t.scale" news20-dim :sparse-p t :multiclass-p t))
(defparameter news20-arow (clol:make-one-vs-rest news20-dim 20 'sparse-arow 10))
(loop repeat 12 do (clol:train news20-arow news20-train))
(clol:test news20-arow news20-test)
; Accuracy: 86.90208%, Correct: 3470, Total: 3993

Save/Restore model

For saving a learner model to a file or restoring from the model file, SAVE and RESTORE function are available respectively. For the above multiclass classification example, saving / restoring code would be:

;; Save
(clol:save arow-1vs1 #P"/tmp/iris.model")
;; Restore
(defparameter restored-learner (clol:restore #P"/tmp/iris.model"))

(clol:test restored-learner iris-test)
; Accuracy: 98.0%, Correct: 49, Total: 50

Author: masatoi
Source Code: https://github.com/masatoi/cl-online-learning
License: MIT License
#machine-learning #algorithm 

Nellie  Kemmer

Nellie Kemmer

1669844640

Supply Chain Applications with R & Shiny

In this tutorial, we will learn Supply Chain Management Strategy with R and Shiny. During the pandemic, the supply chain and its management strategy burst into the spotlight. Supply chain management (SCM) became a household topic as its disruptions began to directly impact people’s lives and the global economy.

But the truth is, good supply chain strategies are the ones that are aligned with business strategy. And in this complex environment, there is a trade-off between responsive versus efficient strategies.

Spreadsheets, R, and Supply Chain Management

A spreadsheet solution enables a lot of flexibility but it comes at the expense of reproducibility and error pruning. ERP is a very mature system and has strict rules that make it reliable and efficient but adds little opportunity for newer designs.

This is an extreme example, but it’s a valid one:

Where IT products are not flexible enough nor have the required development speed for business needs, having spreadsheet solutions where an IT product should be used is a common source of strategy misalignment. And one that causes visibility issues in the supply chain.

This is where R comes into play. It’s great for solutions that require a certain degree of development speed and flexible design but are also reproducible with the building blocks of IT maturity. Knowing the requirements that allow an R solution to shine also depends on a proper understanding of where you stand with IT requirements and the business environment.

In this post, we depict the general understanding of business strategy and supply chain as a subsidy to strategic alignment and why using R sustains the visibility and reproducibility required for SCM strategy.

We’ll also show use cases for R and Shiny in SCM and how to add additional value. 


Strategy and the Supply Chain

Porter has a great definition of strategy: “the creation of fit between activities, where each activity is consistent, mutually reinforcing, and the fit is done optimally for competitive advantage.”

This fit can have different perspectives such as:

  • Internal fit: Organization structure
  • External fit: Competition
  • Dynamic fit: Demand behavior 

Also, Shapiro and Heskett state that strategy has a set of dichotomies that creates tension on each perspective, therefore, strategy decisions will always inherit a set of trade-offs.

This is an extensive field, and for this post, this is an essential concept. If you want to go further, I highly recommend Wharton’s free  Strategic Management program.

Supply Chain Overview

The supply chain is a big topic and can be explained through a variety of viewpoints. Below is a condensed summary of the SCOR Model and other descriptions. 

Supply Chain Score model

An additional summation:

Supply Chain Management is an art

Strategic fit in the Supply Chain

A strategic fit occurs when the competitive strategy and supply chain strategy align goals. Its success is connected to several factors:

  1. Adjustment between the competitive strategy and functional supply chain strategies
  2. Proper design of the processes and resources of different functions
  3. Alignment between supply chain design and the role of each stage

A company can fail because of a lack of strategic fit or because the overall design, supply chain processes, and resources do not provide enough to support the desired strategic outcome.

There are three basic steps to achieve this and overcome potential failure:

  1. Understand client uncertainty
  2. Understand the supply chain capacities
  3. Implement/Set the strategic fit

In summary, these steps ensure that there is an appropriate supply chain strategy for each product/service. And functional products have an efficient supply chain strategy while innovative products should fit with a responsive supply chain design. This is called the zone of strategic fit.

Supply Chain zone of strategic fit

Staying competitive

It is important to note that products have a lifecycle, and the supply chain should account for that. Also, the real world is a dynamic system. That’s why alignment with the business strategy is important. It ensures the correct approach under each state of change.

Supply Chain strategy responsive vs efficiency competitive strategy pyramid

Being able to understand what the drivers of change are and leverage them is what makes supply chain a field of both science and art. This means your supply chain strategy should leverage the theory, but also be fine-tuned for unique situations.

Therefore, using analytic solutions that can leverage both real data and theory into actionable insights provides huge value for supply chain strategists. Reproducibility is a key factor of success because it enhances visibility and enforces alignment between the scope of strategy and operations, as well as maintains sustainability.

For further studies on the supply chain, audit the free MITx program

R and Supply Chain Models

When we’re abstracting a model or testing a specific problem, using spreadsheets seems a great way to get the work done. Because it is at its core, flexible. But, in this situation, it’s can be difficult to explain the solution to others and make sure that the appropriate workflow is being followed.

Another drawback of spreadsheets is complex logic. When it comes to more complex problems it becomes harder to set the appropriate logic to design the solution in a steady state. Whereas in R, you can leverage a set of best practices and cutting-edge solutions from packages that are maintained by CRAN. This extends the level of quality that R grants to its users.

Note: CRAN is not without its risks. To ensure your project remains secure, you should explore the Isoband Incident and how to mitigate risks.

SCM in spreadsheets vs R example

Let’s take a look at an example by comparing the two solutions: spreadsheets vs R.

For each of the metrics in the data, you are asked to calculate the change in the sum of all countries in the ongoing previous month and previous year against the current one:

SCM spreadsheet vs r example

The concept is straightforward, we basically have to:

  1. Group the data by date and sum each metric to account for all countries
  2. Calculate the lag from the ongoing previous month and previous year
  3. Calculate the difference between the lagged previous month/year and the current date.

To do this in spreadsheets, there are many approaches you could work on. One such example:

Grouping data in SCM spreadsheet example

In this example, we can see that on the 1st of January 2016 56 items were produced while on the 1st of December 2015 it produced 80 items. This is a change in production by -24 items. The same logic applies to the year metric.

The data transformation that was asked for is complete. So what’s the issue then?

Reproducibility with spreadsheets

Basically, this approach adds too many manual insertions and each calculation must be checked and updated by the user. There is also the risk of mixing different cells in the calculation, this is the reproducibility problem.

Let’s not forget that we also need 6 other metrics on the data; the same approach is to be repeated 6 times in the spreadsheet.

Imagine for instance that data changes or another metric should be included later on. You will soon enter the spreadsheet productivity dilemma. It was fast to design, became hard to maintain, and now is harder to keep adding features. Soon enough, most of your daily work will revolve around spreadsheet issues instead of focusing on business value.

For the business strategy, this is also a problem. Because it compromises the overall strategy, especially in the supply chain regarding information flow. This issue, therefore, impacts the physical and financial flow. It also makes it harder for businesses to quickly detect changes in the supply chain.

This example is a rather common issue in business. Even beautifully designed dashboards sometimes source an entangled web of spreadsheet data transformations that are connected in non obvious ways and are very hard to understand the data pipeline.

R solution to the reproducibility problem

This same problem can be solved in R, in a very elegant solution provided by the tidyverse package:


cols <- c(
  "produced_items", "orders_count", "revenue",
  "cost", "salvage_value", "profit", "complaints_opened",
  "complaints_closed", "users_active", "users_dropped_out"
)
 
daily_stats <- dataset_df %>%
  group_by(date) %>%
  summarise(across(all_of(cols), sum, .names = "{col}")) %>%
  mutate(
    across(
      all_of(cols),
      list(
        prev_month = ~ lag(.x, n = 30),
        change_prev_month = ~ .x - lag(.x, n = 30),
        prev_year = ~ lag(.x, n = 365),
        change_prev_year = ~  .x - lag(.x, n = 365)
      ),
    .names = "{col}.{fn}"
    )
  )

In this example, we can see that all the required steps for this data transformation are kept in the code. This means that understanding and debugging the applications is much easier and faster. And if anything changes in the source, it has a steady-state structure that can be easily updated. 

supply chain data view in r output

supply chain data analysis output using r, daily_stats

But R does not only allow you to make reproducible pipelines for dashboards as in the example above. It also allows you to create beautiful dashboards to share this data in a more consumable fashion. With R, you can create a new set of value by designing apps for specific problems – all without needing the skills of a web developer. 

We’ll show you how with a solution for the use case scenario below.

Supply Chain Management in R use case

Let’s start by presenting a very traditional supply chain design problem as the multiple-commodity transshipment problem.

R in supply chain design use case - transshipment problem

In this problem, you minimize the total cost of fulfilling the demand for a set of products at each point of sales, while sharing capacity constraints on plants and distribution centers.

transshipment model

Data

For this problem, we have a template-ready dataset from a spreadsheet, this will have the following structure:

  1. Node: Set of each entity of the model with their names
  2. Flow cost: The cost related to sending each product to plant x DC and DC x region
  3. Capacity: The total capacity of the Plants and DCs
  4. Node Arcs: The demand per region/product and capacity of production of each plant/product

path <- "Transshipment_template.xlsx"
 
data <- path %>%
  readxl::excel_sheets() %>%
  purrr::set_names() %>%
  purrr::map(readxl::read_excel, path = path)

To run the model, we must set it to the appropriate structure of R for optimization, this requires a set of data wrangling:


transship_wrang <- function(data){
 
  Product <- dplyr::filter(data$Nodes, Entity == "Product")$Name
  Plant <-  dplyr::filter(data$Nodes, Entity == "Plant")$Name
  DC <-  dplyr::filter(data$Nodes, Entity == "DC")$Name
  Region <-  dplyr::filter(data$Nodes, Entity == "Region")$Name
 
  incost <- dplyr::filter(data$flow_cost, type == "inflow")
 
  incst <- array(
	as.matrix(incost$value),
	dim = c(length(Product), length(Plant), length(DC)),
	dimnames = list(Product, Plant, DC)
  )
 
  outcost <- dplyr::filter(data$flow_cost, type == "outflow")
 
  outcst <- array(
	as.matrix(outcost$value),
	dim = c(length(Product), length(DC),length(Region)),
	dimnames = list(Product, DC, Region)
  )
 
  PlCapacity <- matrix(
	dplyr::filter(data$Capacity, Node == "Plant")$Value,
	ncol = 1,
	dimnames = list(Plant, "PlCapacity")
  )
 
  DCCapacity <- matrix(
	dplyr::filter(data$Capacity, Node == "DC")$Value,
	ncol = 1,
	dimnames = list(DC, "DCCapacity")
  )
 
  PlPrCapacity <- array(
	dplyr::filter(data$NodeARCs, Type == "Restriction")$Value,
	dim = c(length(Plant),length(Product)),
	dimnames = list(Plant, Product)
  )
 
  Demand <- array(
	dplyr::filter(data$NodeARCs, Type == "Demand")$Value,
	dim = c(length(Region),length(Product)),
	dimnames = list(Region, Product)
  )
 
  return(
	list(
  	Product = Product,
  	Plant = Plant,
  	DC = DC,
  	Region = Region,
  	incst = incst,
  	outcst = outcst,
  	PlPrCapacity = PlPrCapacity,
  	PlCapacity = PlCapacity,
  	DCCapacity = DCCapacity,
  	Demand = Demand
	)
  )
}
 
clean_data <- transship_wrang(data)

Modeling the transshipment problem in R

To set this model, we’ll use ompr since it relates to the mathematical formulation of MILP models, this eases the code x model barrier:


transship_model <- function(
	Product, Plant, DC, Region, incst, outcst,
	PlPrCapacity, PlCapacity, DCCapacity, Demand) {
 
  require(ROI)
  require(ROI.plugin.glpk)
 
  l <- length(Product) # Number of Products
  i <- length(Plant) #Number of Plants
  k <- length(DC) #Number of transhipments (CDs)
  j <- length(Region) #Number of cities (POS)
 
model <- ompr::MIPModel() %>%
	
  # Variable of inflow
  ompr::add_variable(xinf[l,i,k], l = 1:l, i = 1:i, k=1:k, type = "integer", lb = 0) %>%
	
  # Variable of outflow
  ompr::add_variable(xout[l,k,j], l = 1:l, k = 1:k, j=1:j, type = "integer", lb = 0) %>%
	
  ompr::set_objective(
	ompr::sum_expr(xinf[l,i,k] * incst[l,i,k], l = 1:l, i = 1:i, k=1:k) +  #Inbound Cost
	ompr::sum_expr(xout[l,k,j] * outcst[l,k,j], l = 1:l, k = 1:k, j=1:j) #Outbound Cost
  ) %>%
    
    #Plant Production Capacity
ompr::add_constraint(ompr::sum_expr(xinf[l,i,k], k=1:k) <= PlPrCapacity[i,l], l=1:l, i=1:i) %>%
	
  #Plant Total Capacity
  ompr::add_constraint(ompr::sum_expr(xinf[l,i,k], l=1:l, k=1:k) <= PlCapacity[i], i=1:i) %>%
	
  #DC Total Capacity
  ompr::add_constraint(ompr::sum_expr(xinf[l,i,k], l=1:l, i=1:i) <= DCCapacity[k], k=1:k) %>%
	
  #Fulfill Demand
  ompr::add_constraint(ompr::sum_expr(xout[l,k,j], k=1:k) >= Demand[j,l], l=1:l, j=1:j) %>%
	
  #Flow Constraint
  ompr::add_constraint(
    ompr::sum_expr(xinf[l,i,k], i=1:i) == ompr::sum_expr(xout[l,k,j], j=1:j),
    l=1:l, k=1:k
  )
 
  #Solve
  result <- ompr::solve_model(model, ompr.roi::with_ROI(solver = "glpk"))
 
  # Results
 
  objective <- result$objective_value
 
 Infl <- ompr::get_solution(result, xinf[l,i,k]) %>%
    dplyr::mutate(product = Product[l], source = Plant[i], destiny = DC[k], type = "Inflow") %>%
    dplyr::select(type, product, source, destiny, value)
 
 Outfl <- ompr::get_solution(result, xout[l,k,j]) %>%
  dplyr::mutate(product = Product[l], source = DC[k], destiny = Region[j], type = "Outflow") %>%
   dplyr::select(type, product, source, destiny, value)
 
  Dcs_Flow <- Infl %>%
	dplyr::group_by(destiny, product) %>%
	dplyr::summarise(Amount = sum(value)) %>%
	as.data.frame()
 
  Plants_Product <- Infl %>%
	dplyr::group_by(source, product) %>%
	dplyr::summarise(Amount = sum(value)) %>%
	as.data.frame()
 
  Products_flow <- rbind(Infl, Outfl)
 
  return(
	list(
  	objective = objective,
  	inflow = Infl,
  	outflow = Outfl,
  	Products_flow = Products_flow,
  	Dcs_Flow = Dcs_Flow,
  	Plants_Product = Plants_Product
	)
  )
}
 
model <- transship_model(
  Product = clean_data$Product,
  Plant = clean_data$Plant,
  DC = clean_data$DC,
  Region = clean_data$Region,
  incst = clean_data$incst,
  outcst = clean_data$outcst,
  PlPrCapacity = clean_data$PlPrCapacity,
  PlCapacity = clean_data$PlCapacity,
  DCCapacity = clean_data$DCCapacity,
  Demand = clean_data$Demand
)

Results


bootstrap <- c("striped", "hover", "responsive") glue::glue("Total Cost: {model$objective}") knitr::kable(model$Plants_Product, caption = "Plants Production") %>%
  kableExtra::kable_styling(bootstrap_options = bootstrap, full_width = F, font_size = 20, position = "float_left")
 
knitr::kable(model$Dcs_Flow, caption = "DCs Flow") %>%
  kableExtra::kable_styling(bootstrap_options = bootstrap, full_width = F, font_size = 20, position = "right")
 
knitr::kable(model$inflow, caption = "Inflow") %>%
  kableExtra::kable_styling(bootstrap_options = bootstrap, full_width = F, font_size = 20, position = "float_left")
 
knitr::kable(model$outflow, caption = "Outflow") %>%
  kableExtra::kable_styling(bootstrap_options = bootstrap, full_width = F, font_size = 20, position = "right")

Total Cost: 9250

R transshipment problem modeling result

Sharing SCM results using R Shiny

You and your team developed a great model and now have valuable insight for the company. How do you share this info with your peers? And can you make this insight interactive, letting them tweak values or set new input data?

You can do this and more by using R Shiny – an interactive web framework for R (and Python).

Are you more of a Python fan? See what’s currently possible with our Shiny for Python demo.

Continue below for the full code to build your own Shiny application for your SCM model.

Aesthetic functions


sankey_chart <- function(data, product) { data %>%
    dplyr::filter(product == !!product) %>%
    echarts4r::e_charts() %>%
    echarts4r::e_sankey(source, destiny, value) %>%
    echarts4r::e_title(glue::glue("Product {product} flow")) %>%
    echarts4r::e_tooltip() %>%
    echarts4r::e_theme("dark")
}
 
reactablefmtr <- function(data, args = TRUE, ...) { data %>%
    dplyr::select(...) %>%
    reactable::reactable(.,
      filterable = args, searchable = args, resizable = args,
      onClick = "select", outlined = TRUE, bordered = TRUE, borderless = TRUE,
      striped = args, highlight = TRUE, compact = args, showSortable = TRUE,
      theme = reactablefmtr::slate()
    )
}

Shiny UI


ui <- bs4Dash::dashboardPage(
 ui <- bs4Dash::dashboardPage(
  title = "Trasshipment Model",
  fullscreen = TRUE,
  dark = T,
  scrollToTop = T,
  header = bs4Dash::dashboardHeader(
    status = "gray-dark",
    title = bs4Dash::dashboardBrand(
      title = "Transshipment Model",
      color = "primary"
    )
  ),
  sidebar = bs4Dash::dashboardSidebar(
    collapsed = T,
    bs4Dash::sidebarMenu(
      bs4Dash::menuItem(
        text = "Transshipment",
        tabName = "transshipment",
        icon = icon("project-diagram")
      )
    )
  ),
  footer = bs4Dash::dashboardFooter(
    right = a(
      href = "https://appsilon.com/",
      "Built with ❤ by Appsilon"
    ),
    left = div(
      icon("calendar"),
      Sys.Date()
    ),
    fixed = T
  ),
  body = bs4Dash::dashboardBody(
    bs4Dash::tabItems(
      bs4Dash::tabItem(
        tabName = "transshipment",
        bs4Dash::tabBox(
          width = 12,
          collapsible = FALSE,
          maximizable = TRUE,
          tabPanel(
            "Model",
            fluidRow(
              column(
                4,
                bs4Dash::box(
                  status = "purple",
                  collapsible = F,
                  width = 12,
                  div(
                    class = "d-flex justify-content-center",
                    a(
                      tags$i(class = "fa fa-database"),
                      href = "www/files/Transshipment_template.xlsx",
                      "Download template",
                      class = "btn btn-default m-1",
                      download = NA, target = "_blank"
                    )
                  ),
                  hr(),
                  fileInput("uploadmodel", "Upload Data"),
                  hr(),
                  div(
                    class = "d-flex justify-content-center",
                    shiny::actionButton(
                      inputId = "model_run",
                      class = "btn btn-success action-button m-1 shiny-bound-input",
                      icon = icon("magic"),
                      label = "Run Model"
                    )
                  )
                )
              ),
              column(
                8,
                bs4Dash::tabBox(
                  width = 12,
                  collapsible = T,
                  maximizable = T,
                  collapsed = F,
                  tabPanel(
                    "Model Info",
                    div(
                      fluidRow(
                        bs4Dash::bs4ValueBoxOutput("products", width = 3),
                        bs4Dash::bs4ValueBoxOutput("plants", width = 3),
                        bs4Dash::bs4ValueBoxOutput("dcs", width = 3),
                        bs4Dash::bs4ValueBoxOutput("regions", width = 3)
                      ),
                      hr(),
                      selectInput(
                        "url_db",
                        label = h5("Choose the data"),
                        choices = c("Nodes", "flow_cost", "Capacity", "NodeARCs")
                      ),
                      shinycssloaders::withSpinner(
                        reactable::reactableOutput("data"),
                        type = 8
                      )
                    )
                  ),
                  tabPanel(
                    "Results",
                    uiOutput("ui_output")
                  )
                )
              )
            )
          )
        )
      )
    )
  )
)

Server – Deploying your Supply Chain Management Shiny app


server <- function(input, output) {
  data <- reactive({
    path <- input$uploadmodel$datapath path %>%
      readxl::excel_sheets() %>%
      purrr::set_names() %>%
      purrr::map(readxl::read_excel, path = path)
  })
 
  data_info <- reactive(
    transship_wrang(data())
  )
 
  output$products <- bs4Dash::renderbs4ValueBox({
    req(input$uploadmodel$datapath)
    bs4Dash::bs4ValueBox(length(data_info()$Product), subtitle = "Products", color = "primary")
  })
 
  output$plants <- bs4Dash::renderbs4ValueBox({
    req(input$uploadmodel$datapath)
    bs4Dash::bs4ValueBox(length(data_info()$Plant), subtitle = "Plants", color = "primary")
  })
 
  output$dcs <- bs4Dash::renderbs4ValueBox({
    req(input$uploadmodel$datapath)
    bs4Dash::bs4ValueBox(length(data_info()$DC), subtitle = "DCs", color = "primary")
  })
 
  output$regions <- bs4Dash::renderbs4ValueBox({
    req(input$uploadmodel$datapath)
    bs4Dash::bs4ValueBox(length(data_info()$Region), subtitle = "Regions", color = "primary")
  })
 
  output$data <- reactable::renderReactable({
    req(input$uploadmodel$datapath)
    reactablefmtr(data()[input$url_db][[1]], args = FALSE, everything())
  })
 
  observeEvent(input$model_run, {
    
    if (is.null(input$uploadmodel$datapath)) {
      shinyWidgets::sendSweetAlert(
        title = "Upload a file",
        type = "error",
        text = "Please, Upload a file first"
      )
    } else {   
      model <- transship_model(
          Product = data_info()$Product,
          Plant = data_info()$Plant,
          DC = data_info()$DC,
          Region = data_info()$Region,
          incst = data_info()$incst,
          outcst = data_info()$outcst,
          PlPrCapacity = data_info()$PlPrCapacity,
          PlCapacity = data_info()$PlCapacity,
          DCCapacity = data_info()$DCCapacity,
          Demand = data_info()$Demand
        )
        
      output$total_value <- renderText({
        glue::glue("Total Cost: {model$objective}")
      })
        
      output$sankey_chart <- echarts4r::renderEcharts4r({
        sankey_chart(model$Products_flow, input$product)
      })
        
      output$results_data <- reactable::renderReactable({
        reactablefmtr(model[input$result_data][[1]], args = FALSE, everything())
      })
      
      output$ui_output <- renderUI({
 
        tagList(
          div(
            class = "d-flex justify-content-center",
            h2(textOutput("total_value"))
          ),
          selectInput(
            "product",
            label = h5("Choose Product"),
            choices = data_info()$Product
          ),
          echarts4r::echarts4rOutput("sankey_chart"),
          selectInput(
            "result_data",
            label = h5("Choose view"),
            choices = c("inflow", "outflow", "Dcs_Flow", "Plants_Product")
          ),
          reactable::reactableOutput("results_data")
        )
      })
    }
  })
}

Running the application

shinyApp(ui = ui, server = server)

Summing up R and Shiny in Supply Chain Management

Supply chain management has many layers of solutions and models designed for each scope of the business strategy. The intrinsic trade-off between those strategies requires visibility, and by being reproducible, R is capable of delivering value to each step in the strategy spectrum.

There are solutions where a spreadsheet definitely shines, especially while designing an idea from scratch. But with R you can extend this to a business-friendly solution in a production-ready state without compromising the flexibility you require for your business life cycle.

There are many other topics in supply chain and applications that can be used with R, but the main insight for this post is that reproducibility is a key factor for success in the alignment between the scope of strategies. This is vital for businesses and makes a significant difference in sustainable and successful solutions. 


Original article sourced at: https://appsilon.com

#r #programming #shiny 

Promise.allSettled() vs Promise.all()

Promise.allSetlled() is recently introduced in ECMA 2020.
Check out how it is different from Promise.all()

https://www.geekstutorialpoint.com/2020/05/promiseallsettled-vs-promiseall.html

#javascript #promise.all #promise.allsettled #ecma #promise #jquery

Perfect Number Program In Python: How to check if a number is perfect or not?

Introduction

A number is said to be the perfect number if the sum of its proper divisors (not including the number itself) is equal to the number.

To get a better idea let’s consider an example, proper divisors of 6 are 1, 2, 3. Now the sum of these divisors is equal to 6 (1+2+3=6), so 6 is said to be a perfect number. Whereas if we consider another number like 12, proper divisors of 12 are 1, 2, 3, 4, 6. Now the sum of these divisors is not equal to 12, so 12 is not a perfect number.

Programming in Python is relatively simpler and more fun when compared to other languages because of its simpler syntax, good readability. Now that we are clear with the concept of perfect number let’s write a python program to check if a number is a perfect number or not. Let’s build a python code for checking if the given user input is a perfect number or not and explore the fun in coding with python.

#data science #how to check if a number is perfect #perfect number #perfect number in python #perfect number program in python #python

Ray  Patel

Ray Patel

1619607900

Perfect Number Program In Python: How to check if a number is perfect or not?

Introduction

A number is said to be the perfect number if the sum of its proper divisors (not including the number itself) is equal to the number.

To get a better idea let’s consider an example, proper divisors of 6 are 1, 2, 3. Now the sum of these divisors is equal to 6 (1+2+3=6), so 6 is said to be a perfect number. Whereas if we consider another number like 12, proper divisors of 12 are 1, 2, 3, 4, 6. Now the sum of these divisors is not equal to 12, so 12 is not a perfect number.

Programming in Python is relatively simpler and more fun when compared to other languages because of its simpler syntax, good readability. Now that we are clear with the concept of perfect number let’s write a python program to check if a number is a perfect number or not. Let’s build a python code for checking if the given user input is a perfect number or not and explore the fun in coding with python.

#data science #how to check if a number is perfect #perfect number #perfect number in python #perfect number program in python #python