问:
Ordination of vowels of a sentence in descending order
Suppose I enter the following string:

```<code>" Hello party"
</code>```

How could you order only the vowels of that chain, but in a descending way?

to example:

```<code>"Halle porty"
</code>```

In the following way I have tried to solve the problem, but when I run it tells me that I have an ExeptionBounce 5. How could I correct it? I am also told that the responsible line is the following:

```<code>if(cad[i].equalsIgnoreCase(vocal[j])

       private String[]cad;
       private String[]vocal={"a","e","i","o","u"};
       private String resp="";
      private String aux="":
      private String []sort;
      private int cont=0;

    public String ordenar(String cadena)
    {
     cad= cadena.split("");

     for(int i=0; i<cad.legth; i++)
     {

       for(int j=i, j<vocal.legth; j++)
         {

            if(cad[i].equalsIgnoreCase(vocal[j])
             {

            aux+=cad[i];
            sort= aux.Split("");
            Arrays.sort(sort);

           for(int i=0; i<cad.legth; i++)
           {

             cad[i] = sort[k];
             resp+=cad[i];

           }
           }
          }

       return resp;
        }
</code>```

答:
Your code would not even compile - how are you running it ?

To answer your question, here is a piece of code which given a string will return the string with the vowels sorted:

```<code>    public static boolean isVowel(char c) {
        return "AEIOUaeiou".indexOf(c) != -1;
    }
    public static String sortVowelsOnly(String input) {
        if (input == null) {
            return input;
        }
        StringBuilder result = new StringBuilder(input);

        //keep track at all positions where we saw a vowel
        ArrayList<Integer> vowelPositions = new ArrayList<>();
        //keep track of all vowels we saw so far
        ArrayList<Character> vowels = new ArrayList<>();
        for (int charPosition = 0; charPosition < input.length(); charPosition++) {
            char currentChar = input.charAt(charPosition);
            if(isVowel(currentChar)) {
                vowelPositions.add(charPosition);
                vowels.add(currentChar);
            }
        }

        Collections.sort(vowels);

        //now just iterate over all positions where we saw a vowel, and populate it with the vowels from the sorted list
        for(Integer vowelPosition : vowelPositions) {
            char vowel = vowels.remove(0);
            result.setCharAt(vowelPosition, vowel);
        }
        return result.toString();
    }
</code>```

Body:
Suppose I enter the following string:

" Hello party"

How could you order only the vowels of that chain, but in a descending way?

to example:

"Halle porty"

In the following way I have tried to solve the problem, but when I run it tells me that I have an ExeptionBounce 5. How could I correct it? I am also told that the responsible line is the following:

if(cad[i].equalsIgnoreCase(vocal[j])

       private String[]cad;
       private String[]vocal={"a","e","i","o","u"};
       private String resp="";
      private String aux="":
      private String []sort;
      private int cont=0;

    public String ordenar(String cadena)
    {
     cad= cadena.split("");

     for(int i=0; i<cad.legth; i++)
     {

       for(int j=i, j<vocal.legth; j++)
         {

            if(cad[i].equalsIgnoreCase(vocal[j])
             {

            aux+=cad[i];
            sort= aux.Split("");
            Arrays.sort(sort);

           for(int i=0; i<cad.legth; i++)
           {

             cad[i] = sort[k];
             resp+=cad[i];

           }
           }
          }

       return resp;
        }

Body:
Your code would not even compile - how are you running it ?

To answer your question, here is a piece of code which given a string will return the string with the vowels sorted:

    public static boolean isVowel(char c) {
        return "AEIOUaeiou".indexOf(c) != -1;
    }
    public static String sortVowelsOnly(String input) {
        if (input == null) {
            return input;
        }
        StringBuilder result = new StringBuilder(input);

        //keep track at all positions where we saw a vowel
        ArrayList<Integer> vowelPositions = new ArrayList<>();
        //keep track of all vowels we saw so far
        ArrayList<Character> vowels = new ArrayList<>();
        for (int charPosition = 0; charPosition < input.length(); charPosition++) {
            char currentChar = input.charAt(charPosition);
            if(isVowel(currentChar)) {
                vowelPositions.add(charPosition);
                vowels.add(currentChar);
            }
        }

        Collections.sort(vowels);

        //now just iterate over all positions where we saw a vowel, and populate it with the vowels from the sorted list
        for(Integer vowelPosition : vowelPositions) {
            char vowel = vowels.remove(0);
            result.setCharAt(vowelPosition, vowel);
        }
        return result.toString();
    }


来源: stackexchange

问:
What is different between webpack production and development regarding tree shaking
in my webpack config

when

```<code>mode: "development"
</code>```

if I use

```<code>import { pick, flattenDeep, chunk, fromPairs } from 'lodash-es';
</code>```

or

```<code>import _ from 'lodash-es';
</code>```

the bundle size is the same at about  3.27 mb.

but when I set mode to production in my webpack config, I get a bundle size of 1.52mb for the first import syntax, but I get 2.5mb for the second syntax, which leads my to believe that in development the tree shaking is not occuring.

I read on another stack overflow question that the lodash-es was an es6 module and that webpack could only tree shake on those, and not common js, and I also read that in development for the webpack config I would need

```<code>plugins: [
    new webpack.optimize.ModuleConcatenationPlugin()
],
</code>```

which I have had the whole time.

So I am curious what I am missing and why the bundle size is not reduced in development when using  that plugin mentioned.

I am experimenting these changes in an example project I created at  https://github.com/JordanKlaers/vueWebpackPlayground

答:
By default webpack's tree-shaking mechanism works on the minification phase (by terser-webpack-plugin), this phase is enabled by default only on production mode, therefore, you don't see any changes in bundle size when you are on development.

Module concat plugin works only on es6 modules, and it can improve the tree-shaking process.

ContentLicense: CC BY-SA 4.0

Body:
in my webpack config

when

mode: "development"

if I use

import { pick, flattenDeep, chunk, fromPairs } from 'lodash-es';

or

import _ from 'lodash-es';

the bundle size is the same at about  3.27 mb.

but when I set mode to production in my webpack config, I get a bundle size of 1.52mb for the first import syntax, but I get 2.5mb for the second syntax, which leads my to believe that in development the tree shaking is not occuring.

I read on another stack overflow question that the lodash-es was an es6 module and that webpack could only tree shake on those, and not common js, and I also read that in development for the webpack config I would need

plugins: [
    new webpack.optimize.ModuleConcatenationPlugin()
],

which I have had the whole time.

So I am curious what I am missing and why the bundle size is not reduced in development when using  that plugin mentioned.

I am experimenting these changes in an example project I created at  https://github.com/JordanKlaers/vueWebpackPlayground


问:
Get HTML after Javascript execution/modification with WKWebView and Regex in Swift 4+
I have been trying to retrieve some data from a website which seems like javascript performs a modification before/after load

I want to find a specific DIV into HTML, and it just doesn't appear to be there the way I'm doing this, it loads only a part of the HTML but don't the one I need to.

Here is my code:

```<code>let url = URL(string: "https://www.spaceweatherlive.com")

        let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
            if error != nil{
                print(error)
            }else{
//                let htmlcontent = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
                let htmlcontent = String(data: data!, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))
//                let regex = try? NSRegularExpression(pattern: "<h4 class=\"text-center\">Kp[0-9]</h4>", options: .caseInsensitive)
                let substring = "<h4 class=\"text-center\">Kp[0-9]"

                let matched = self.matches(for: substring, in: htmlcontent!)
                print(matched)
                if htmlcontent!.contains(substring){
                    print("Substring FOUND!!")
                }else{
//                    print("Nope, printing whole html:")
//                    print(htmlcontent)
                }
//                print(htmlcontent)

            }

        }
        task.resume()
</code>```

Function to search for substring

```<code>func matches(for regex: String, in text: String) -> [String] {

    do {
        let regex = try NSRegularExpression(pattern: regex)
        let results = regex.matches(in: text,
                                    range: NSRange(text.startIndex..., in: text))
        return results.map {
            String(text[Range($0.range, in: text)!])
        }
    } catch let error {
        print("invalid regex: \(error.localizedDescription)")
        return []
    }
}
</code>```

Thanks! any help or advice to try is very appreciated

This is the DIV which I need to retrieve (KP[0-9] value)

答:
We can maybe start with a simple expression and capture the SVG highchart part of the indicator that we have in the question:

```<code>(<div id="Kp_gauge".+?<\/div><\/div><\/div><\/div>)
</code>```

Then, the title part can be written or attached to it with another similar expression.

Here, we are saying that start from:

```<code><div id="Kp_gauge"
</code>```

collect everything (.+?) to closest:

```<code><\/div><\/div><\/div><\/div>
</code>```

We can do the same for the title, if we wish, or we can just on the top of that write or add Kp-index and the problem may be solved.

The h3` title is always going to be:

```<code><h3 class="card-header text-center">Kp-index <span class="text-primary" data-toggle="tooltip" title="" data-original-title="The Kp-index is a geomagnetic activity index based on data from magnetometers around the world. The gauge below shows the most recently observed Kp-value from the Planetary K-index of the NOAA SWPC and can be used to make a rough estimate of the current global geomagnetic conditions."><svg class="svg-inline--fa fa-info-circle fa-w-16" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="info-circle" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" data-fa-i2svg=""><path fill="currentColor" d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"></path></svg><!-- <i class="fas fa-info-circle" aria-hidden="true"></i> --></span></h3>
</code>```

which can be simply added.

DEMO

const regex = /(<div id="Kp_gauge".+?<\/div><\/div><\/div><\/div>)/gm;
const str = `

<svg version="1.1" class="highcharts-root" style="font-family:"Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif;font-size:12px;" xmlns="http://www.w3.org/2000/svg" width="448" height="170" viewBox="0 0 448 170"><desc>Created with Highcharts 7.1.1</desc><defs><clipPath id="highcharts-c5v532c-28-"><rect x="0" y="0" width="428" height="145" fill="none"></rect></clipPath></defs><rect fill="none" class="highcharts-background" x="0" y="0" width="448" height="170" rx="0" ry="0"></rect><rect fill="none" class="highcharts-plot-background" x="10" y="10" width="428" height="145"></rect><g class="highcharts-pane-group" data-z-index="0"><path fill="#eee" d="M 108 140.5 A 116 116 0 0 1 339.9999420000048 140.38400001933334 L 293.5999652000029 140.4304000116 A 69.6 69.6 0 0 0 154.4 140.5 Z" class="highcharts-pane " stroke="#cccccc" stroke-width="1"></path></g><g class="highcharts-grid highcharts-yaxis-grid" data-z-index="1"><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 108 140.5" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 114.99565598883464 100.82566337422242" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 135.13884459819855 65.93663727636142" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 165.99999999999997 40.041053161005124" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 203.8568113906361 26.262300650583867" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 244.14318860936393 26.262300650583867" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 282 40.04105316100511" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 312.86115540180145 65.93663727636144" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 333.00434401116536 100.82566337422242" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 340 140.5" opacity="1"></path></g><rect fill="none" class="highcharts-plot-border" data-z-index="1" x="10" y="10" width="428" height="145"></rect><g class="highcharts-axis highcharts-yaxis" data-z-index="2"><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 108 140.5 L 118 140.5" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 114.99565598883464 100.82566337422242 L 124.39258219669372 104.24586480747911" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 135.13884459819855 65.93663727636142 L 142.79928902938835 72.36451337322681" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 165.99999999999997 40.041053161005124 L 170.99999999999997 48.701307198849506" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 203.8568113906361 26.262300650583867 L 205.59329316730538 36.11037818070595" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 244.14318860936393 26.262300650583867 L 242.40670683269462 36.11037818070595" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 282 40.04105316100511 L 277 48.70130719884949" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 312.86115540180145 65.93663727636144 L 305.2007109706117 72.36451337322683" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 333.00434401116536 100.82566337422242 L 323.60741780330625 104.24586480747911" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 340 140.5 L 330 140.5" opacity="1"></path><path fill="none" class="highcharts-axis-line" data-z-index="7" d="M 108 140.5 A 116 116 0 0 1 339.9999420000048 140.38400001933334 M 224 140.5 A 0 0 0 0 0 224 140.5 "></path></g><g data-z-index="2" class="highcharts-data-labels highcharts-series-0 highcharts-solidgauge-series  highcharts-tracker" transform="translate(10,10) scale(1 1)"><g class="highcharts-label highcharts-data-label highcharts-data-label-color-0 highcharts-tracker" data-z-index="1" transform="translate(181,84)"></g></g><g class="highcharts-series-group" data-z-index="3"><g data-z-index="0.1" class="highcharts-series highcharts-series-0 highcharts-solidgauge-series  highcharts-tracker" transform="translate(10,10) scale(1 1)" clip-path="url(#highcharts-c5v532c-28-)"><path fill="rgb(85,191,59)" d="M 98 130.5 A 116 116 0 0 1 155.89957006990173 30.09910338080769 L 179.13974204194105 70.25946202848462 A 69.6 69.6 0 0 0 144.4 130.5 Z" sweep-flag="0" stroke-linecap="round" stroke-linejoin="round" class="highcharts-point highcharts-color-0"></path></g><g data-z-index="0.1" class="highcharts-markers highcharts-series-0 highcharts-solidgauge-series " transform="translate(10,10) scale(1 1)" clip-path="none"></g></g><text x="10" class="highcharts-title" data-z-index="4" style="color:#333333;font-size:18px;fill:#333333;" y="24"></text><text x="224" text-anchor="middle" class="highcharts-subtitle" data-z-index="4" style="color:#666666;fill:#666666;" y="24"></text><g class="highcharts-legend" data-z-index="7"><rect fill="none" class="highcharts-legend-box" rx="0" ry="0" x="0" y="0" width="8" height="8" visibility="hidden"></rect><g data-z-index="1"><g></g></g></g><g class="highcharts-axis-labels highcharts-yaxis-labels" data-z-index="7"><text x="98" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="144.49999999999997" opacity="1">0</text><text x="105.59872978097555" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="101.40546194096572" opacity="1">1</text><text x="127.47840016700879" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="63.50876117949602" opacity="1">2</text><text x="160.99999999999997" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="35.38079912316074" opacity="1">3</text><text x="202.1203296139668" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="20.414223120461784" opacity="1">4</text><text x="245.87967038603324" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="20.414223120461784" opacity="1">5</text><text x="287" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="35.38079912316073" opacity="1">6</text><text x="320.5215998329912" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="63.508761179496034" opacity="1">7</text><text x="342.40127021902447" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="101.40546194096574" opacity="1">8</text><text x="350" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="144.5" opacity="1">9</text></g></svg>
Loading…

Kp3

18-21 UTC

`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }

    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}```
</div>
</div>
</p>
<hr />
<h3>Edit</h3>
<p>For getting the <code>Kp</code> we can simply use an expression similar to:</p>
```<h[1-6] class="text-center">(Kp[0-9]+)<\/h[1-6]>
```
<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>const regex = /<h[1-6] class="text-center">(Kp[0-9]+)<\/h[1-6]>/gm;
const str = `<span data-z-index="1" style="position: absolute; font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif; font-size: 11px; white-space: nowrap; font-weight: bold; color: rgb(0, 0, 0); margin-left: 0px; margin-top: 0px; left: 5px; top: 5px;"><h4 class="text-center">Kp3</h4><div class="text-center" style="font-size:10px;color:silver">18-21 UTC</div></span>`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }

    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}</code>```

DEMO

Body:
I have been trying to retrieve some data from a website which seems like javascript performs a modification before/after load

I want to find a specific DIV into HTML, and it just doesn't appear to be there the way I'm doing this, it loads only a part of the HTML but don't the one I need to.

Here is my code:

let url = URL(string: "https://www.spaceweatherlive.com")

        let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
            if error != nil{
                print(error)
            }else{
//                let htmlcontent = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
                let htmlcontent = String(data: data!, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))
//                let regex = try? NSRegularExpression(pattern: "
Kp[0-9]
", options: .caseInsensitive)
                let substring = "
Kp[0-9]"

                let matched = self.matches(for: substring, in: htmlcontent!)
                print(matched)
                if htmlcontent!.contains(substring){
                    print("Substring FOUND!!")
                }else{
//                    print("Nope, printing whole html:")
//                    print(htmlcontent)
                }
//                print(htmlcontent)

            }

        }
        task.resume()

Function to search for substring

func matches(for regex: String, in text: String) -> [String] {

    do {
        let regex = try NSRegularExpression(pattern: regex)
        let results = regex.matches(in: text,
                                    range: NSRange(text.startIndex..., in: text))
        return results.map {
            String(text[Range($0.range, in: text)!])
        }
    } catch let error {
        print("invalid regex: \(error.localizedDescription)")
        return []
    }
}

Thanks! any help or advice to try is very appreciated

This is the DIV which I need to retrieve (KP[0-9] value)

Body:
We can maybe start with a simple expression and capture the SVG highchart part of the indicator that we have in the question:

(<div id="Kp_gauge".+?<\/div><\/div><\/div><\/div>)

Then, the title part can be written or attached to it with another similar expression.

Here, we are saying that start from:

<div id="Kp_gauge"

collect everything (.+?) to closest:

<\/div><\/div><\/div><\/div>

We can do the same for the title, if we wish, or we can just on the top of that write or add Kp-index and the problem may be solved.

The h3` title is always going to be:

<h3 class="card-header text-center">Kp-index <span class="text-primary" data-toggle="tooltip" title="" data-original-title="The Kp-index is a geomagnetic activity index based on data from magnetometers around the world. The gauge below shows the most recently observed Kp-value from the Planetary K-index of the NOAA SWPC and can be used to make a rough estimate of the current global geomagnetic conditions."><svg class="svg-inline--fa fa-info-circle fa-w-16" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="info-circle" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" data-fa-i2svg=""><path fill="currentColor" d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"></path></svg><!-- <i class="fas fa-info-circle" aria-hidden="true"></i> --></span></h3>

which can be simply added.

DEMO

const regex = /(<div id="Kp_gauge".+?<\/div><\/div><\/div><\/div>)/gm;
const str = `<div id="Kp_gauge" style="height: 170px; overflow: hidden;" data-highcharts-chart="6"><div id="highcharts-c5v532c-27" dir="ltr" class="highcharts-container " style="position: relative; overflow: hidden; width: 448px; height: 170px; text-align: left; line-height: normal; z-index: 0; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><svg version="1.1" class="highcharts-root" style="font-family:&quot;Lucida Grande&quot;, &quot;Lucida Sans Unicode&quot;, Arial, Helvetica, sans-serif;font-size:12px;" xmlns="http://www.w3.org/2000/svg" width="448" height="170" viewBox="0 0 448 170"><desc>Created with Highcharts 7.1.1</desc><defs><clipPath id="highcharts-c5v532c-28-"><rect x="0" y="0" width="428" height="145" fill="none"></rect></clipPath></defs><rect fill="none" class="highcharts-background" x="0" y="0" width="448" height="170" rx="0" ry="0"></rect><rect fill="none" class="highcharts-plot-background" x="10" y="10" width="428" height="145"></rect><g class="highcharts-pane-group" data-z-index="0"><path fill="#eee" d="M 108 140.5 A 116 116 0 0 1 339.9999420000048 140.38400001933334 L 293.5999652000029 140.4304000116 A 69.6 69.6 0 0 0 154.4 140.5 Z" class="highcharts-pane " stroke="#cccccc" stroke-width="1"></path></g><g class="highcharts-grid highcharts-yaxis-grid" data-z-index="1"><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 108 140.5" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 114.99565598883464 100.82566337422242" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 135.13884459819855 65.93663727636142" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 165.99999999999997 40.041053161005124" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 203.8568113906361 26.262300650583867" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 244.14318860936393 26.262300650583867" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 282 40.04105316100511" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 312.86115540180145 65.93663727636144" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 333.00434401116536 100.82566337422242" opacity="1"></path><path fill="none" data-z-index="1" class="highcharts-grid-line" d="M 224 140.5 L 340 140.5" opacity="1"></path></g><rect fill="none" class="highcharts-plot-border" data-z-index="1" x="10" y="10" width="428" height="145"></rect><g class="highcharts-axis highcharts-yaxis" data-z-index="2"><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 108 140.5 L 118 140.5" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 114.99565598883464 100.82566337422242 L 124.39258219669372 104.24586480747911" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 135.13884459819855 65.93663727636142 L 142.79928902938835 72.36451337322681" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 165.99999999999997 40.041053161005124 L 170.99999999999997 48.701307198849506" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 203.8568113906361 26.262300650583867 L 205.59329316730538 36.11037818070595" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 244.14318860936393 26.262300650583867 L 242.40670683269462 36.11037818070595" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 282 40.04105316100511 L 277 48.70130719884949" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 312.86115540180145 65.93663727636144 L 305.2007109706117 72.36451337322683" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 333.00434401116536 100.82566337422242 L 323.60741780330625 104.24586480747911" opacity="1"></path><path fill="none" class="highcharts-tick" stroke="#ccd6eb" stroke-width="2" d="M 340 140.5 L 330 140.5" opacity="1"></path><path fill="none" class="highcharts-axis-line" data-z-index="7" d="M 108 140.5 A 116 116 0 0 1 339.9999420000048 140.38400001933334 M 224 140.5 A 0 0 0 0 0 224 140.5 "></path></g><g data-z-index="2" class="highcharts-data-labels highcharts-series-0 highcharts-solidgauge-series  highcharts-tracker" transform="translate(10,10) scale(1 1)"><g class="highcharts-label highcharts-data-label highcharts-data-label-color-0 highcharts-tracker" data-z-index="1" transform="translate(181,84)"></g></g><g class="highcharts-series-group" data-z-index="3"><g data-z-index="0.1" class="highcharts-series highcharts-series-0 highcharts-solidgauge-series  highcharts-tracker" transform="translate(10,10) scale(1 1)" clip-path="url(#highcharts-c5v532c-28-)"><path fill="rgb(85,191,59)" d="M 98 130.5 A 116 116 0 0 1 155.89957006990173 30.09910338080769 L 179.13974204194105 70.25946202848462 A 69.6 69.6 0 0 0 144.4 130.5 Z" sweep-flag="0" stroke-linecap="round" stroke-linejoin="round" class="highcharts-point highcharts-color-0"></path></g><g data-z-index="0.1" class="highcharts-markers highcharts-series-0 highcharts-solidgauge-series " transform="translate(10,10) scale(1 1)" clip-path="none"></g></g><text x="10" class="highcharts-title" data-z-index="4" style="color:#333333;font-size:18px;fill:#333333;" y="24"></text><text x="224" text-anchor="middle" class="highcharts-subtitle" data-z-index="4" style="color:#666666;fill:#666666;" y="24"></text><g class="highcharts-legend" data-z-index="7"><rect fill="none" class="highcharts-legend-box" rx="0" ry="0" x="0" y="0" width="8" height="8" visibility="hidden"></rect><g data-z-index="1"><g></g></g></g><g class="highcharts-axis-labels highcharts-yaxis-labels" data-z-index="7"><text x="98" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="144.49999999999997" opacity="1">0</text><text x="105.59872978097555" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="101.40546194096572" opacity="1">1</text><text x="127.47840016700879" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="63.50876117949602" opacity="1">2</text><text x="160.99999999999997" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="35.38079912316074" opacity="1">3</text><text x="202.1203296139668" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="20.414223120461784" opacity="1">4</text><text x="245.87967038603324" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="20.414223120461784" opacity="1">5</text><text x="287" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="35.38079912316073" opacity="1">6</text><text x="320.5215998329912" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="63.508761179496034" opacity="1">7</text><text x="342.40127021902447" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="101.40546194096574" opacity="1">8</text><text x="350" style="color:#666666;cursor:default;font-size:11px;fill:#666666;" text-anchor="middle" transform="translate(0,0)" y="144.5" opacity="1">9</text></g></svg><div class="highcharts-loading highcharts-loading-hidden" style="position: absolute; background-color: rgb(255, 255, 255); opacity: 0; text-align: center; z-index: 10; left: 10px; top: 10px; width: 428px; height: 145px; display: none;"><span class="highcharts-loading-inner" style="font-weight: bold; position: relative; top: 45%;">Loading…</span></div><div class="highcharts-data-labels highcharts-series-0 highcharts-solidgauge-series  highcharts-tracker" style="position: absolute; left: 10px; top: 10px; opacity: 1; visibility: inherit;"><div class="highcharts-label highcharts-data-label highcharts-data-label-color-0 highcharts-tracker" style="position: absolute; left: 181px; top: 84px; opacity: 1;"><span data-z-index="1" style="position: absolute; font-family: &quot;Lucida Grande&quot;, &quot;Lucida Sans Unicode&quot;, Arial, Helvetica, sans-serif; font-size: 11px; white-space: nowrap; font-weight: bold; color: rgb(0, 0, 0); margin-left: 0px; margin-top: 0px; left: 5px; top: 5px;"><h4 class="text-center">Kp3</h4><div class="text-center" style="font-size:10px;color:silver">18-21 UTC</div></span></div></div></div></div>`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }

    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

Edit

For getting the Kp we can simply use an expression similar to:

<h[1-6] class="text-center">(Kp[0-9]+)<\/h[1-6]>

const regex = /<h[1-6] class="text-center">(Kp[0-9]+)<\/h[1-6]>/gm;
const str = `<span data-z-index="1" style="position: absolute; font-family: &quot;Lucida Grande&quot;, &quot;Lucida Sans Unicode&quot;, Arial, Helvetica, sans-serif; font-size: 11px; white-space: nowrap; font-weight: bold; color: rgb(0, 0, 0); margin-left: 0px; margin-top: 0px; left: 5px; top: 5px;"><h4 class="text-center">Kp3</h4><div class="text-center" style="font-size:10px;color:silver">18-21 UTC</div></span>`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }

    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

DEMO


问:
Nodejs Asynchronous reusable function call
I have some problem developping my own Node.JS application. I'm new to this kind of code architecture and not so good with asynchronous as well.

I currently have an event in  my index.js script, calling for another script database.js. This database script will handle every db call inside my application.

index.js

```<code>const db = require('database.js');

//Called when a userjoin the application, this is working well//
db.userJoinedFunction("username");
</code>```

I was planning adding other function call inside my "userjoinedFunction". For example : establishing first the DB connection --> 2nd checking if the user is already inside the DB --> 3d if not, create the user entry --> 4 if yes, do welcome back message.
Since I have to establish the DB connection multiple time, I wanted to reuse some code inside theses function like this :

database.js

```<code>module.exports.userJoinedFuntion = userJoinedFunction

function userjoinedFunction(username){
   Init_database_connection();
   if(UserAlreadySignedup(username)){
      WelcomeMessage(username);
   }
   else {
      AddUserToDatabase(username);
   }
}
</code>```

but obviously i'm doing it wrong because asynchronous Node.js application can't be that simple... How can I have that type of reusable architecture ? Do you have articles I can read about the subject ?

Thank you very much for your help !

EDIT 29/05/2019

with the response of novomanish I tried this :

```<code>async fonction run(){
  await(call("number 1");
  await Init_database_connection();
  await(call("number 2");
}

async function call(text){
  console.log(text);
}

async function Init_database_connection(){
  db = new sqlite3.Database("path", sqlite.OPEN_READWRITE, (err) =>{
    if(err){ console.log(err); }
    else { console.log("DB Connected"); }
  });
}
</code>```

my output are :

```<code>- number one
- number two
- DB Connected
</code>```

I checked many article and documentation, I can't find a good way of reusing function inside a "main function" (like in my example : the function run()). And i'm surprised that waiting for finished DB query isn't apparently thing...

答:
You need async/await in your functions. So the new code would look like:

```<code>async function Init_database_connection(){...}
...

async function userjoinedFunction(username){
   await Init_database_connection();
   if(await UserAlreadySignedup(username)){
      return WelcomeMessage(username);
   }
   return AddUserToDatabase(username);

}
</code>```

Regarding your edit, Init_database_connection should have returned a promise for await to work, like this:

```<code>async function Init_database_connection(){
  return new Promise((resolve, reject)=>{
      db = new sqlite3.Database("path", sqlite.OPEN_READWRITE, (err) =>{
        if(err){
           console.log(err);
           reject();
        }else {
          console.log("DB Connected");
          resolve()
        }
      });
  })
}
</code>```

Body:
I have some problem developping my own Node.JS application. I'm new to this kind of code architecture and not so good with asynchronous as well.

I currently have an event in  my index.js script, calling for another script database.js. This database script will handle every db call inside my application.

index.js

const db = require('database.js');

//Called when a userjoin the application, this is working well//
db.userJoinedFunction("username");

I was planning adding other function call inside my "userjoinedFunction". For example : establishing first the DB connection --> 2nd checking if the user is already inside the DB --> 3d if not, create the user entry --> 4 if yes, do welcome back message.
Since I have to establish the DB connection multiple time, I wanted to reuse some code inside theses function like this :

database.js

module.exports.userJoinedFuntion = userJoinedFunction

function userjoinedFunction(username){
   Init_database_connection();
   if(UserAlreadySignedup(username)){
      WelcomeMessage(username);
   }
   else {
      AddUserToDatabase(username);
   }
}

but obviously i'm doing it wrong because asynchronous Node.js application can't be that simple... How can I have that type of reusable architecture ? Do you have articles I can read about the subject ?

Thank you very much for your help !

EDIT 29/05/2019

with the response of novomanish I tried this :

async fonction run(){
  await(call("number 1");
  await Init_database_connection();
  await(call("number 2");
}

async function call(text){
  console.log(text);
}

async function Init_database_connection(){
  db = new sqlite3.Database("path", sqlite.OPEN_READWRITE, (err) =>{
    if(err){ console.log(err); }
    else { console.log("DB Connected"); }
  });
}

my output are :

- number one
- number two
- DB Connected

I checked many article and documentation, I can't find a good way of reusing function inside a "main function" (like in my example : the function run()). And i'm surprised that waiting for finished DB query isn't apparently thing...

Body:
You need async/await in your functions. So the new code would look like:

async function Init_database_connection(){...}
...

async function userjoinedFunction(username){
   await Init_database_connection();
   if(await UserAlreadySignedup(username)){
      return WelcomeMessage(username);
   }
   return AddUserToDatabase(username);

}

Regarding your edit, Init_database_connection should have returned a promise for await to work, like this:

async function Init_database_connection(){
  return new Promise((resolve, reject)=>{
      db = new sqlite3.Database("path", sqlite.OPEN_READWRITE, (err) =>{
        if(err){
           console.log(err);
           reject();
        }else {
          console.log("DB Connected");
          resolve()
        }
      });
  })
}


问:
Device Provisioning custom allocation - setting initial Device Twin in azure function
Custom allocation supports setting the initial device twin as well as the IoT Hub. The device twin does not get set.

I've configured the device provisioning service in Azure to use a custom Azure Function.  In the Azure function, via custom API, we run logic to determine the best IoT Hub location for the device.  In addition to the IoT Hub assignment, the code supplies the initial device twin data but It's not working.

I'm following the code sample described in this blog:
https://sandervandevelde.wordpress.com/2018/12/29/custom-iot-hub-assignment-in-device-provisioning-service/

I've looked through several related custom allocation issues but haven't found anyone using the custom azure function approach as described above.

Here is a snippet of the related code from the blog article above.

```<code>var response = new Response(savefileresponse.AssignedHub);
//loading an instance of the initiTwin didn't work, try typing device twin values in manually
//response.initialTwin = savefileresponse.initialTwin;
response.initialTwin.properties.desired = new JObject();
response.initialTwin.properties.desired.PropOne = "2345";
response.initialTwin.properties.desired.PropTwo = "6789";
</code>```

Below are the class definitions taken from the Blog article.  Note the use of the dynamic type for desired properties. Can someone confirm this is the correct message response type to DPS?

```<code>public class AssignDeviceResponse
{
    public AssignDeviceResponse()
    {
        this.initialTwin = new ResponseTwin();
    }

    public ProvisioningRegistrationStatusType Status { get; set; }
    public string DeviceId { get; set; }
    public string AssignedHub { get; set; }
    public ResponseTwin initialTwin { get; set; }
}

#endregion

#region Microsoft DPS response contracts
public class Response
{
    public Response(string hostName)
    {
        iotHubHostName = hostName;
        initialTwin = new ResponseTwin();
    }

    public string iotHubHostName { get; set; }
    public ResponseTwin initialTwin { get; set; }
}

public class ResponseTwin
{
    public ResponseTwin()
    {
        properties = new ResponseProperties();
    }

    public dynamic tags { get; set; }
    public ResponseProperties properties { get; set; } // contains desired properties
}

public class ResponseProperties
{
    public dynamic desired { get; set; }
}
#endregion
</code>```

After provisioning, the IoT Hub value is returned to device correctly.  Then I went into the azure portal, IoT Hub and show the device twin value.  None of the custom properties I added show up. The twin below is apparently some IoT Hub default as it doesn't match the twin in the DPS service either.

```<code>{
"deviceId": "cde5d316-9c01-3961-b850-8f5c17cea937",
"etag": "AAAAAAAAAAE=",
"deviceEtag": "NzA1OTc5MzE1",
"status": "enabled",
"statusUpdateTime": "0001-01-01T00:00:00",
"connectionState": "Disconnected",
"lastActivityTime": "2019-04-26T16:41:11.6618195",
"cloudToDeviceMessageCount": 0,
"authenticationType": "selfSigned",
"x509Thumbprint": {
"primaryThumbprint":
  "xxx",
"secondaryThumbprint":
  "xxx"
},
"version": 2,
"properties": {
  "desired": {
    "$metadata": {
      "$lastUpdated": "2019-04-26T16:41:09.4381992Z"
   },
   "$version": 1
},
"reported": {
  "$metadata": {
    "$lastUpdated": "2019-04-26T16:41:09.4381992Z"
  },
  "$version": 1
 }
},
"capabilities": {
"iotEdge": false
}
}
</code>```

How can I set the device twin default value via custom allocation?

EDIT: After trying a different response type on my function, I thought I'd also post the code that works for me to read the parameters as well as forming the response that does serialize correctly through DPS.  The issue still remains how to set the desired initialTwin values.  Here's the azure function code that serializes back to DPS.

```<code>public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
                                                      HttpRequestMessage req, TraceWriter log)
    {
        string requestBody = await req.Content.ReadAsStringAsync();
        dynamic data = JsonConvert.DeserializeObject(requestBody);

        //Read out key information
        string deviceId = data.deviceRuntimeContext.registrationId;
        string certificate = data.deviceRuntimeContext.x509.clientCertificate;
        var response = new Response(data.linkedHubs?[0]);

        //Can't get initialTwin data back to DPS
        //response.initialTwin = new ResponseTwin() { }

        return req.CreateResponse<Response>(HttpStatusCode.OK, response);
    }
</code>```

答:
Ok, after working this through with Microsoft's help, here is the answer to the question.

1.) Implement the Azure Function in a V2 instance of Azure Functions

2.) Add reference to Microsoft.Azure.Devices.Shared

The DPS code is expecting an instance of TwinState as shown below

```<code>public class ResponseObj
{
    public string iotHubHostName { get; set; }
    public TwinState initialTwin { get; set; }
}
</code>```

Then serialization is handled by this return type

```<code>return (ActionResult)new OkObjectResult(response);
</code>```

The TwinState class in Java:
https://github.com/Azure/azure-iot-sdk-java/blob/a9c1487bede6463a6d67aadd68588cdaf92fd905/deps/src/main/java/com/microsoft/azure/sdk/iot/deps/twin/TwinState.java#L123

Body:
Custom allocation supports setting the initial device twin as well as the IoT Hub. The device twin does not get set.

I've configured the device provisioning service in Azure to use a custom Azure Function.  In the Azure function, via custom API, we run logic to determine the best IoT Hub location for the device.  In addition to the IoT Hub assignment, the code supplies the initial device twin data but It's not working.

I'm following the code sample described in this blog:
https://sandervandevelde.wordpress.com/2018/12/29/custom-iot-hub-assignment-in-device-provisioning-service/

I've looked through several related custom allocation issues but haven't found anyone using the custom azure function approach as described above.

Here is a snippet of the related code from the blog article above.

var response = new Response(savefileresponse.AssignedHub);
//loading an instance of the initiTwin didn't work, try typing device twin values in manually
//response.initialTwin = savefileresponse.initialTwin;
response.initialTwin.properties.desired = new JObject();
response.initialTwin.properties.desired.PropOne = "2345";
response.initialTwin.properties.desired.PropTwo = "6789";

Below are the class definitions taken from the Blog article.  Note the use of the dynamic type for desired properties. Can someone confirm this is the correct message response type to DPS?

public class AssignDeviceResponse
{
    public AssignDeviceResponse()
    {
        this.initialTwin = new ResponseTwin();
    }

    public ProvisioningRegistrationStatusType Status { get; set; }
    public string DeviceId { get; set; }
    public string AssignedHub { get; set; }
    public ResponseTwin initialTwin { get; set; }
}

#endregion

#region Microsoft DPS response contracts
public class Response
{
    public Response(string hostName)
    {
        iotHubHostName = hostName;
        initialTwin = new ResponseTwin();
    }

    public string iotHubHostName { get; set; }
    public ResponseTwin initialTwin { get; set; }
}

public class ResponseTwin
{
    public ResponseTwin()
    {
        properties = new ResponseProperties();
    }

    public dynamic tags { get; set; }
    public ResponseProperties properties { get; set; } // contains desired properties
}

public class ResponseProperties
{
    public dynamic desired { get; set; }
}
#endregion

After provisioning, the IoT Hub value is returned to device correctly.  Then I went into the azure portal, IoT Hub and show the device twin value.  None of the custom properties I added show up. The twin below is apparently some IoT Hub default as it doesn't match the twin in the DPS service either.

{
"deviceId": "cde5d316-9c01-3961-b850-8f5c17cea937",
"etag": "AAAAAAAAAAE=",
"deviceEtag": "NzA1OTc5MzE1",
"status": "enabled",
"statusUpdateTime": "0001-01-01T00:00:00",
"connectionState": "Disconnected",
"lastActivityTime": "2019-04-26T16:41:11.6618195",
"cloudToDeviceMessageCount": 0,
"authenticationType": "selfSigned",
"x509Thumbprint": {
"primaryThumbprint":
  "xxx",
"secondaryThumbprint":
  "xxx"
},
"version": 2,
"properties": {
  "desired": {
    "$metadata": {
      "$lastUpdated": "2019-04-26T16:41:09.4381992Z"
   },
   "$version": 1
},
"reported": {
  "$metadata": {
    "$lastUpdated": "2019-04-26T16:41:09.4381992Z"
  },
  "$version": 1
 }
},
"capabilities": {
"iotEdge": false
}
}

How can I set the device twin default value via custom allocation?

EDIT: After trying a different response type on my function, I thought I'd also post the code that works for me to read the parameters as well as forming the response that does serialize correctly through DPS.  The issue still remains how to set the desired initialTwin values.  Here's the azure function code that serializes back to DPS.

public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
                                                      HttpRequestMessage req, TraceWriter log)
    {
        string requestBody = await req.Content.ReadAsStringAsync();
        dynamic data = JsonConvert.DeserializeObject(requestBody);

        //Read out key information
        string deviceId = data.deviceRuntimeContext.registrationId;
        string certificate = data.deviceRuntimeContext.x509.clientCertificate;
        var response = new Response(data.linkedHubs?[0]);

        //Can't get initialTwin data back to DPS
        //response.initialTwin = new ResponseTwin() { }

        return req.CreateResponse<Response>(HttpStatusCode.OK, response);
    }

Body:
Ok, after working this through with Microsoft's help, here is the answer to the question.

1.) Implement the Azure Function in a V2 instance of Azure Functions

2.) Add reference to Microsoft.Azure.Devices.Shared

The DPS code is expecting an instance of TwinState as shown below

public class ResponseObj
{
    public string iotHubHostName { get; set; }
    public TwinState initialTwin { get; set; }
}

Then serialization is handled by this return type

return (ActionResult)new OkObjectResult(response);

The TwinState class in Java:
https://github.com/Azure/azure-iot-sdk-java/blob/a9c1487bede6463a6d67aadd68588cdaf92fd905/deps/src/main/java/com/microsoft/azure/sdk/iot/deps/twin/TwinState.java#L123


问:
Is this class Threadsafe?
Hi

Is the class below threadsafe?

```<code>class ImmutablePossiblyThreadsafeClass<K, V> {

    private final Map<K, V> map;

    public ImmutablePossiblyThreadsafeClass(final Map<K, V> map) {
        this.map = new HashMap<K, V>();

        for (Entry<K, V> entry : map.entrySet()) {
            this.map.put(entry.getKey(), entry.getValue());
        }
    }

    public V get(K key) {
        return this.map.get(key);
    }
}
</code>```

答:
Assuming that nothing changes the map field after construction (since you've named it "immutable" I guess that's the idea) AND the map provided as constructor argument is not altered during construction, that is a thread-safe class.

Mind that there are easier ways of copying entries from one map to another than iteration. You might also want to look at some of the methods in Collections to create immutable versions of collections. You'd first have to copy the map, of course, since the underlying map could still be changed. The "unmodifiable*" methods only return a view of a collection.

ContentLicense: CC BY-SA 3.0

Title: Is this class Threadsafe?

Body:
Hi

Is the class below threadsafe?

class ImmutablePossiblyThreadsafeClass<K, V> {

    private final Map<K, V> map;

    public ImmutablePossiblyThreadsafeClass(final Map<K, V> map) {
        this.map = new HashMap<K, V>();

        for (Entry<K, V> entry : map.entrySet()) {
            this.map.put(entry.getKey(), entry.getValue());
        }
    }

    public V get(K key) {
        return this.map.get(key);
    }
}


问:
Why is AWS NACL stateless?
From what I read, stateless firewalls are used more for packet filtering. Why is AWS NACL stateless?

NACLs force too big a range of ports to be opened for the ephemeral ports.

Is there a way to create stateful firewalls on AWS other than Security Groups? Security Groups feel too granular and may get omitted by mistake.

答:
Network Access Control Lists (ACLs) mimic traditional firewalls implemented on hardware routers. Such routers are used to separate subnets and allow the creation of separate zones, such as a DMZ. They purely filter based upon the content of the packet. That is their job.

Security Groups are an added capability in AWS that provides firewall-like capabilities at the resource level. (To be accurate, they are attached to Elastic Network Interfaces, ENIs). They are stateful, meaning that they allow return traffic to flow.

In general, the recommendation is to leave NACLs at their default settings (allow all traffic IN & OUT). They should only be changed if there is a specific need to block certain types of traffic at the subnet level.

Security Groups are the ideal way to control stateful traffic going in and out of a VPC-attached resource. They are THE way to create stateful firewalls. There is no other such capability provided by a VPC. If you wanted something different, you could route traffic through an Amazon EC2 instance acting as a NAT and then you would have full control over how it behaves.

Title: Why is AWS NACL stateless?


答:
There's a potential problem when the constructor parameter's contents change while you're copying them. But there isn't really anything you can do to prevent that. Another potential problem would be with mutable keys.

Also, you can replace the constructor with this:

```<code>public ImmutablePossiblyThreadsafeClass(final Map<K, V> map) {
    this.map = new HashMap<K, V>(map);
}
</code>```

Title: Is this class Threadsafe?

Body:
There's a potential problem when the constructor parameter's contents change while you're copying them. But there isn't really anything you can do to prevent that. Another potential problem would be with mutable keys.

Also, you can replace the constructor with this:

public ImmutablePossiblyThreadsafeClass(final Map<K, V> map) {
    this.map = new HashMap<K, V>(map);
}


问:
How does tokio::net::TcpStream implement tokio::prelude::Stream?
In the tokio.rs docs we see the following snippet

```<code>// split the socket stream into readable and writable parts
let (reader, writer) = socket.split();
// copy bytes from the reader into the writer
let amount = io::copy(reader, writer);
</code>```

I am assuming that split is indeed Stream::split, but I can't figure out how this trait applies to TcpStream given that the stream page doesn't mention TcpStream and vice versa.

答:
tokio::net::TcpStream implements AsyncRead.

One of the provided methods from AsyncRead is split():

```<code>fn split(self) -> (ReadHalf<Self>, WriteHalf<Self>)
where
    Self: AsyncWrite,
</code>```

So in this case it isn't Stream::split as your question suggested because as per your observation tokio::net::TcpStream isn't an implementor of Stream.

Body:
In the tokio.rs docs we see the following snippet

// split the socket stream into readable and writable parts
let (reader, writer) = socket.split();
// copy bytes from the reader into the writer
let amount = io::copy(reader, writer);

I am assuming that split is indeed Stream::split, but I can't figure out how this trait applies to TcpStream given that the stream page doesn't mention TcpStream and vice versa.

Body:
tokio::net::TcpStream implements AsyncRead.

One of the provided methods from AsyncRead is split():

fn split(self) -> (ReadHalf<Self>, WriteHalf<Self>)
where
    Self: AsyncWrite,

So in this case it isn't Stream::split as your question suggested because as per your observation tokio::net::TcpStream isn't an implementor of Stream.


问:
Create a TypeScript (string) enum from a union type?
If I have a TypeScript union like so:

```<code>type SomeUnion = 'Foo' | 'Bar' | 'Baz';
</code>```

Is there a way I can convert this into a string-based enum? Like the the following:

```<code>enum SomeUnionBasedEnum {
  Foo = 'Foo',
  Bar = 'Bar',
  Baz = 'Baz'
}
</code>```

I am trying to model an enum that represents the permissions in our system, but those permissions are in some cases automatically generated union types. I want a way to combine them into a single enum because enums provide a better developer experience by limiting the intellisense to the permissible values. For example AppPermisionEnum.<available enum values>. I'd also be open to ways to combine enums into a single enum, but I don't think that's possible. My end goal is to have an enum comprised of values from a couple different sources.

答:
Like I pointed out in the comments string literal types already offer good intelisense support, so I personally would just use those and not bother creating anything else, the developer experience is already great.

The code below is a solution in search of a problem but we can do something close to what you want.

You can't create an enum, but you can create an object that has all the properties of the union and each property has the same value as the key, using a mapped type. You will need to maintain these objects manually, but typescript will issue a warning if ever they are out of sync so maintaining them should not be an issue.

```<code>type SomeUnion = 'Foo' | 'Bar' | 'Baz';

function createEnumObject<T extends string>(o: { [P in T]: P }) {
    return o;
}

const SomeUnion = createEnumObject<SomeUnion>({
    Foo: "Foo",
    Bar: "Bar",
    Baz: "Baz"
})

let o: SomeUnion = SomeUnion.Bar;
</code>```

Converting a union (ie a type) to an object (ie a value) without extra code is in principle not possible, types are erased at compile time so can't be relied upon for anything at run-time and typescript has a strict policy against type directed emit.

Body:
If I have a TypeScript union like so:

type SomeUnion = 'Foo' | 'Bar' | 'Baz';

Is there a way I can convert this into a string-based enum? Like the the following:

enum SomeUnionBasedEnum {
  Foo = 'Foo',
  Bar = 'Bar',
  Baz = 'Baz'
}

I am trying to model an enum that represents the permissions in our system, but those permissions are in some cases automatically generated union types. I want a way to combine them into a single enum because enums provide a better developer experience by limiting the intellisense to the permissible values. For example AppPermisionEnum.<available enum values>. I'd also be open to ways to combine enums into a single enum, but I don't think that's possible. My end goal is to have an enum comprised of values from a couple different sources.

Body:
Like I pointed out in the comments string literal types already offer good intelisense support, so I personally would just use those and not bother creating anything else, the developer experience is already great.

The code below is a solution in search of a problem but we can do something close to what you want.

You can't create an enum, but you can create an object that has all the properties of the union and each property has the same value as the key, using a mapped type. You will need to maintain these objects manually, but typescript will issue a warning if ever they are out of sync so maintaining them should not be an issue.

type SomeUnion = 'Foo' | 'Bar' | 'Baz';

function createEnumObject<T extends string>(o: { [P in T]: P }) {
    return o;
}

const SomeUnion = createEnumObject<SomeUnion>({
    Foo: "Foo",
    Bar: "Bar",
    Baz: "Baz"
})

let o: SomeUnion = SomeUnion.Bar;

Converting a union (ie a type) to an object (ie a value) without extra code is in principle not possible, types are erased at compile time so can't be relied upon for anything at run-time and typescript has a strict policy against type directed emit.


问:
What are some best practices for a creating a constructor that takes a boolean isX and depending on that value would need a boolean for isY?
In this hypothetical problem I'm creating a class to represent Sausage which can be:
A. Fresh and Packaged
B. Fresh and Not Packaged
C. Not Fresh and Not Packaged

Note: It can't be Not Fresh and Packaged.

I'm looking for the best practice to create constructor with this in mind.

The way I tried is below, but I think there should be a better solutions.

public class Sausage {
    Meat meat;
    boolean isFresh;
    boolean isPackaged;

    public Sausage(Meat meat, Boolean isFresh, Boolean isPackaged) {
        this.meat = meat;
        if (!isFresh) {
            this.isFresh = false;
            this.isPackaged = false;
        }
        else if (isPackaged) {
            this.isFresh = true;
            this.isPackaged = true;
        }
        else {
            this.isFresh = true;
            this.isPackaged = false;
        }
    }
}
```

I'm looking for a cleaner way to provide this functionality.

答:
There are few problems with your current approach:

There is a way to create write new object which makes no sense e.g. new Sausage(..., false, true) where packaged will be silently converted to false. This is confusing and makes code harder to understand.

You are mixing Boolean object type and boolean primitive type which will result in unnecessary auto-boxing. If you don't need to support null use boolean.

boolean fields probably don't need is prefix.

Since there are two boolean flags and 4 possibilities they can be set (true true, true false, false true, false false) but only 3 valid options perhaps named factory methods would be more suitable:

```<code>public class Sausage {

    public static Sasuage newFreshPackaged(Meat meat) {
      return new Sasuage(meat, true, true);
    }

    public static Sasuage newFreshNotPackaged(Meat meat) {
      return new Sasuage(meat, true, false);
    }

    public static Sasuage newNotFreshNotPackaged(Meat meat) {
      return new Sasuage(meat, false, false);
    }

    private Sausage(Meat meat, boolean fresh, boolean packaged) {
        this.meat = meat;
        this.fresh = fresh;
        this.packaged = packaged;
    }
}
</code>```

Body:
In this hypothetical problem I'm creating a class to represent Sausage which can be:
A. Fresh and Packaged
B. Fresh and Not Packaged
C. Not Fresh and Not Packaged

Note: It can't be Not Fresh and Packaged.

I'm looking for the best practice to create constructor with this in mind.

The way I tried is below, but I think there should be a better solutions.

public class Sausage {
    Meat meat;
    boolean isFresh;
    boolean isPackaged;

    public Sausage(Meat meat, Boolean isFresh, Boolean isPackaged) {
        this.meat = meat;
        if (!isFresh) {
            this.isFresh = false;
            this.isPackaged = false;
        }
        else if (isPackaged) {
            this.isFresh = true;
            this.isPackaged = true;
        }
        else {
            this.isFresh = true;
            this.isPackaged = false;
        }
    }
}

I'm looking for a cleaner way to provide this functionality.

Body:
There are few problems with your current approach:

There is a way to create write new object which makes no sense e.g. new Sausage(..., false, true) where packaged will be silently converted to false. This is confusing and makes code harder to understand.

You are mixing Boolean object type and boolean primitive type which will result in unnecessary auto-boxing. If you don't need to support null use boolean.

boolean fields probably don't need is prefix.

Since there are two boolean flags and 4 possibilities they can be set (true true, true false, false true, false false) but only 3 valid options perhaps named factory methods would be more suitable:

public class Sausage {

    public static Sasuage newFreshPackaged(Meat meat) {
      return new Sasuage(meat, true, true);
    }

    public static Sasuage newFreshNotPackaged(Meat meat) {
      return new Sasuage(meat, true, false);
    }

    public static Sasuage newNotFreshNotPackaged(Meat meat) {
      return new Sasuage(meat, false, false);
    }

    private Sausage(Meat meat, boolean fresh, boolean packaged) {
        this.meat = meat;
        this.fresh = fresh;
        this.packaged = packaged;
    }
}


问:
Can't understand &(sizeof 2[a])[a]
I've got some code that outputs bcdefg and I can't understand why.

I google searched but I couldn't find anything.

```<code>const char a[]="Abcdefg";
printf("%s",&(sizeof 2[a])[a]);
</code>```

Why is the output bcdefg, and not Abcdefg?

答:
This code is meant to confuse you, not do anything useful. Don't write code like this. Here is how it is interpreted by the compiler:

2[a] is the same as a[2], which is a value of char type (which value exactly doesn't matter; the compiler even doesn't try to evaluate it)

sizeof 2[a] is the same as sizeof(char), which is equal to 1

&(sizeof 2[a])[a] is a pointer to the character b in the string Abcdef - the one which has the index 1

printf("%s",&(sizeof 2[a])[a]) prints the string, starting at that pointer

Title: Can't understand &(sizeof 2[a])[a]

Body:
I've got some code that outputs bcdefg and I can't understand why.

I google searched but I couldn't find anything.

const char a[]="Abcdefg";
printf("%s",&(sizeof 2[a])[a]);

Why is the output bcdefg, and not Abcdefg?


问:
401 Unauthorized while using Pinboard API for add post in Android
Hey all,
I am using the Pinboard API for adding a post from my Android App.  Each time I send the GET request with the required credentials and arguments, I get the 401 Unauthorized response code.  I tried the same URL from a PHP code and the post gets added to Pinboard without any errors.
Any idea where I am going wrong?

Here's the code:

```<code>    private void postToPinboard(){

    String url = "https://.muUsername:myPassword@api.pinboard.in/v1/posts/add?";
    HttpClient client = new DefaultHttpClient();
    HttpGet get = new HttpGet(url);

     try {
            // Adding my data
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("description","Description data");
            nameValuePairs.add(new BasicNameValuePair("url", "http://somewebsite.com"));

            String paramString = URLEncodedUtils.format(nameValuePairs, "utf-8");
            url +=paramString;

            // Execute HTTP Post Request
            HttpResponse response = client.execute(get);

            Log.v("", "RESPONSE CODE: "+response.getStatusLine());// giving 401 Unauthorized

        } catch (ClientProtocolException e) {
            // do something
        } catch (IOException e) {
            // do domething
        }
        finish();
}
</code>```

答:
I finally got the problem: using Pinboard API requires Android to support HTTP basic authentication.  So here's how I got it to work:

```<code>    private void postToPinboard(){

        String url ="https://api.pinboard.in/v1/posts/add?";

        DefaultHttpClient client = new DefaultHttpClient();

    String credentials = Base64.encodeBytes((username+":"+password).getBytes());

    if(credentials!=null){

        try {

            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);

            nameValuePairs.add(new BasicNameValuePair("description", "Description data");
            nameValuePairs.add(new BasicNameValuePair("url", "http://somewebsite.com"));

            String paramString = URLEncodedUtils.format(nameValuePairs, "utf-8");

            url +=paramString;

            HttpGet get = new HttpGet(url);
            get.addHeader("Authorization","Basic "+credentials);

           HttpResponse response = client.execute(get);

               if(response.getStatusLine().getStatusCode() == 200){
                   //       Added to pinboard
               }else{
                   //       Error adding to Pinboard
               }

        } catch (ClientProtocolException e) {
            e.printStackTrace();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
finish();
</code>```

}

Body:
Hey all,
I am using the Pinboard API for adding a post from my Android App.  Each time I send the GET request with the required credentials and arguments, I get the 401 Unauthorized response code.  I tried the same URL from a PHP code and the post gets added to Pinboard without any errors.
Any idea where I am going wrong?

Here's the code:

    private void postToPinboard(){

    String url = "https://.muUsername:myPassword@api.pinboard.in/v1/posts/add?";
    HttpClient client = new DefaultHttpClient();
    HttpGet get = new HttpGet(url);

     try {
            // Adding my data
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("description","Description data");
            nameValuePairs.add(new BasicNameValuePair("url", "http://somewebsite.com"));

            String paramString = URLEncodedUtils.format(nameValuePairs, "utf-8");
            url +=paramString;

            // Execute HTTP Post Request
            HttpResponse response = client.execute(get);

            Log.v("", "RESPONSE CODE: "+response.getStatusLine());// giving 401 Unauthorized

        } catch (ClientProtocolException e) {
            // do something
        } catch (IOException e) {
            // do domething
        }
        finish();
}

Body:
I finally got the problem: using Pinboard API requires Android to support HTTP basic authentication.  So here's how I got it to work:

    private void postToPinboard(){

        String url ="https://api.pinboard.in/v1/posts/add?";

        DefaultHttpClient client = new DefaultHttpClient();

    String credentials = Base64.encodeBytes((username+":"+password).getBytes());

    if(credentials!=null){

        try {

            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);

            nameValuePairs.add(new BasicNameValuePair("description", "Description data");
            nameValuePairs.add(new BasicNameValuePair("url", "http://somewebsite.com"));

            String paramString = URLEncodedUtils.format(nameValuePairs, "utf-8");

            url +=paramString;

            HttpGet get = new HttpGet(url);
            get.addHeader("Authorization","Basic "+credentials);

           HttpResponse response = client.execute(get);

               if(response.getStatusLine().getStatusCode() == 200){
                   //       Added to pinboard
               }else{
                   //       Error adding to Pinboard
               }

        } catch (ClientProtocolException e) {
            e.printStackTrace();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
finish();

}


问:
Insert multiple lines of text before specific line using Bash
I am trying to insert a few lines of text before a specific line, but keep getting sed errors when I try to add a new line character.  My command looks like:

```<code>sed -r -i '/Line to insert after/ i Line one to insert \\
    second new line to insert \\
    third new line to insert' /etc/directory/somefile.txt
</code>```

The error that is reported is:

```<code>sed: -e expression #1, char 77: unterminated `s' command
</code>```

I've tried, using \n, \\ (as in the example), no character at all, just moving the second line to the next line.  I've also tried something like:

```<code>sed -r -i -e '/Line to insert after/ i Line one to insert'
    -e 'second new line to insert'
    -e 'third new line to insert' /etc/directory/somefile.txt
</code>```

EDIT!: Apologies, I wanted the text inserted BEFORE the existing, not after!

答:
On MacOs I needed a few more things.

Double backslash after the i

Empty quotes after the -i to specify no backup file

Leading backslashes to add leading whitespace

Trailing double backslashes to add newlines

This code searches for the first instance of </plugins in pom.xml and inserts another XML object immediately preceding it, separated by a newline character.

```<code>sed -i '' "/\<\/plugins/ i \\
\            <plugin>\\
\                <groupId>org.apache.maven.plugins</groupId>\\
\                <artifactId>maven-source-plugin</artifactId>\\
\                <executions>\\
\                    <execution>\\
\                        <id>attach-sources</id>\\
\                        <goals>\\
\                            <goal>jar</goal>\\
\                        </goals>\\
\                    </execution>\\
\                </executions>\\
\            </plugin>\\
" pom.xml
</code>```

Body:
I am trying to insert a few lines of text before a specific line, but keep getting sed errors when I try to add a new line character.  My command looks like:

sed -r -i '/Line to insert after/ i Line one to insert \\
    second new line to insert \\
    third new line to insert' /etc/directory/somefile.txt

The error that is reported is:

sed: -e expression #1, char 77: unterminated `s' command

I've tried, using \n, \\ (as in the example), no character at all, just moving the second line to the next line.  I've also tried something like:

sed -r -i -e '/Line to insert after/ i Line one to insert'
    -e 'second new line to insert'
    -e 'third new line to insert' /etc/directory/somefile.txt

EDIT!: Apologies, I wanted the text inserted BEFORE the existing, not after!

Body:
On MacOs I needed a few more things.

Double backslash after the i

Empty quotes after the -i to specify no backup file

Leading backslashes to add leading whitespace

Trailing double backslashes to add newlines

This code searches for the first instance of </plugins in pom.xml and inserts another XML object immediately preceding it, separated by a newline character.

sed -i '' "/\<\/plugins/ i \\
\            <plugin>\\
\                <groupId>org.apache.maven.plugins</groupId>\\
\                <artifactId>maven-source-plugin</artifactId>\\
\                <executions>\\
\                    <execution>\\
\                        <id>attach-sources</id>\\
\                        <goals>\\
\                            <goal>jar</goal>\\
\                        </goals>\\
\                    </execution>\\
\                </executions>\\
\            </plugin>\\
" pom.xml


答:
Silently changing isPackaged to false may be a surprise to calling code.  Here, you may choose to throw an exception if the combination (not fresh, packaged) is chosen.

```<code>if (!isFresh && isPackaged) {
    throw new IllegalArgumentException("Can't be both not fresh and packaged!");
}
this.isFresh = isFresh;
this.isPackaged = isPackaged;
</code>```

You may also decide to use factory methods (making your constructor private) that enforce your requirements.  This would avoid needing an exception to be thrown.

```<code>public static Sausage createFreshSausage(Meat meat, boolean isPackaged) {
    return new Sausage(meat, true, isPackaged);
}

public static Sausage createNotFreshSausage(Meat meat) {
    return new Sausage(meat, false, false);
}
</code>```

Incidentally, normally the primitive boolean would be used in the constructor's parameters' types, not the object wrapper Boolean, like your instance variables.  A null value here that would be allowed by Boolean doesn't make any sense.

Title: What are some best practices for a creating a constructor that takes a boolean isX and depending on that value would need a boolean for isY?

Body:
Silently changing isPackaged to false may be a surprise to calling code.  Here, you may choose to throw an exception if the combination (not fresh, packaged) is chosen.

if (!isFresh && isPackaged) {
    throw new IllegalArgumentException("Can't be both not fresh and packaged!");
}
this.isFresh = isFresh;
this.isPackaged = isPackaged;

You may also decide to use factory methods (making your constructor private) that enforce your requirements.  This would avoid needing an exception to be thrown.

public static Sausage createFreshSausage(Meat meat, boolean isPackaged) {
    return new Sausage(meat, true, isPackaged);
}

public static Sausage createNotFreshSausage(Meat meat) {
    return new Sausage(meat, false, false);
}

Incidentally, normally the primitive boolean would be used in the constructor's parameters' types, not the object wrapper Boolean, like your instance variables.  A null value here that would be allowed by Boolean doesn't make any sense.


问:
How to call a JS function in the view from the model in MVC?
I'm setting up a NET.ASP application using the MVC model, and I've come across an issue with activating a function already written in the Razor page, which needs to be activated post-page-load, after some computations.
In this case, my model is getting and parsing some data in the background, which the JavaScript needs to wait to be done.
The goal is to use that data to build a list showcasing it.

I'm rather certain that unless I have a way of triggering a script already written in the page from the model, I would have to write and activate on page-load a JavaScript function that would periodically check whether a boolean in the model is set to true and if so then to activate the data loading function in question.
The question is, when - is there a way to trigger the script from the model?

Unfortunately, every solution to this issue I've come across is for Web Forms, or uses controls in some way.

Here is the code:

```<code><html>
<head>
    <script type="text/javascript" language="javascript">
        function showDataMined()
        {
            // Do things
        }

        function checkDataReady()
        {
            // Sleep for 3 seconds then if Model.dataReady call showDataMined()
            // Is this really the best practice?
        }
    </script>
</head>
<body>
    // Stuff
</body>
</html>
</code>```

I simply want to call showDataMined when the model is ready for it to be called.
Is there a way to do this without checking periodically for some boolean? Perhaps somehow with the Observer pattern?

答:
throw it in an IIFE ("iffy"). An IIFE is an Immediately Invoked Function Expression. It basically automatically calls itself.. hence the () at the end</p>

```<code>(function(){
    function showDataMined()
    {
        // Do things
    }

    function checkDataReady()
    {
        // Sleep for 3 seconds then if Model.dataReady call showDataMined()
    }
})();
</code>```

Body:
I'm setting up a NET.ASP application using the MVC model, and I've come across an issue with activating a function already written in the Razor page, which needs to be activated post-page-load, after some computations.
In this case, my model is getting and parsing some data in the background, which the JavaScript needs to wait to be done.
The goal is to use that data to build a list showcasing it.

I'm rather certain that unless I have a way of triggering a script already written in the page from the model, I would have to write and activate on page-load a JavaScript function that would periodically check whether a boolean in the model is set to true and if so then to activate the data loading function in question.
The question is, when - is there a way to trigger the script from the model?

Unfortunately, every solution to this issue I've come across is for Web Forms, or uses controls in some way.

Here is the code:

    // Stuff

I simply want to call showDataMined when the model is ready for it to be called.
Is there a way to do this without checking periodically for some boolean? Perhaps somehow with the Observer pattern?

Body:
throw it in an IIFE ("iffy"). An IIFE is an Immediately Invoked Function Expression. It basically automatically calls itself.. hence the () at the end

(function(){
    function showDataMined()
    {
        // Do things
    }

    function checkDataReady()
    {
        // Sleep for 3 seconds then if Model.dataReady call showDataMined()
    }
})();


问:
VBA - Ranking Highest to Lowest by Counting Negative Values?
How to rank highest to lowest by counting negative values?

I would probably use something like this follow by if elseif logic but I can't seems to figure it out

```<code>Set CountRng = range("B1:E1")
CountApple = Application.WorksheetFunction.CountIf(CountRng, "<0")
CountOrange ..
CountBanana ..

If CountApple > CountOrange then or endif...
</code>```

Maybe there is a better way to do this?

答:
You could use this formula:

```<code>=SUMPRODUCT(--(COUNTIF(OFFSET($B$1,(ROW($1:$3)-1),0,1,4),"<0")>COUNTIF(B1:E1,"<0")))+1
</code>```

Body:
How to rank highest to lowest by counting negative values?

I would probably use something like this follow by if elseif logic but I can't seems to figure it out

Set CountRng = range("B1:E1")
CountApple = Application.WorksheetFunction.CountIf(CountRng, "<0")
CountOrange ..
CountBanana ..

If CountApple > CountOrange then or endif...

Maybe there is a better way to do this?

Body:
You could use this formula:

=SUMPRODUCT(--(COUNTIF(OFFSET($B$1,(ROW($1:$3)-1),0,1,4),"<0")>COUNTIF(B1:E1,"<0")))+1


问:
Server side Blazor blazor.server.js instead of blazor.webassembly.js
I am trying out Server-side Blazor (.net core 3.0 Preview 5).
I have been searching the web but can't seem to find an answer.
I really like the "layout" of the Blazor (ASP.NET Core hosted) template (see image below). The client part of that is WebAssebly. But I read someware that I could change blazor.webassembly.js to blazor.server.js and that it would be it. How ever that doesn't work. I get some errors in the console log:

Error: Failed to complete negotiation with the server: Error: Internal Server Error blazor.server.js:1

Error: Cannot send data if the connection is not in the 'Connected' State. blazor.server.js:1

What do I need to do for the client to use blazor.server.js instead of blazor.webassembly.js?

Or have I just misunderstood everything?

答:
You are not consistent in describing what flavor of Blazor you're using. I'm going to provide you the code below of how to implement Blazor dual mode, but not without warning that though shifting from Blazor client side to Blazor server side, in configuration term is made simple by a developer named Suchiman, coding for the client can be very different than coding for the server, and you should know what you're doing and take into account many factors...

Here's the link that instruct you how to move to and forth:
https://github.com/Suchiman/BlazorDualMode

Please don't hesitate to ask any question about the above.
Next time select the blazor tag. I've got to this section by mere chance. The Blazor section is very active...


问:
sed variable substitution using string
How to pass argument to sed without input files. The sed is in single quote and has pipe in it already.

```<code>git filter-branch -f --index-filter \
      'git ls-files -s | sed -i "s-\t\"*-&dirname/-" |
                GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
                git update-index --index-info &&
       mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
</code>```

The above code works fine if dirname is hard-coded. But i need to pass the dirname from command line arguments to script. I am trying like below but no luck.

```<code> 'set subdir=$folder;git ls-files -s | sed -i "s-\t\"*-&$subdir/-" |
</code>```

The sed says input file is missing. I can not directly pass the input file to sed. I am seeing error like below.

```<code>Rewrite 9c86de42b7f3228e3d45a278c8caf7e24c8e55cf (1/2) (0 seconds passed, remaining 0 predicted)
sed: no input files
</code>```

答: You're using sed -i, which edits its command-line arguments (which are names of files) in place. However, you're reading from standard input and haven't provided any command-line arguments. If you want to just filter the standard input like this, omit the -i from your sed command.

Title: sed variable substitution using string

Body:
How to pass argument to sed without input files. The sed is in single quote and has pipe in it already.

git filter-branch -f --index-filter \
      'git ls-files -s | sed -i "s-\t\"*-&dirname/-" |
                GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
                git update-index --index-info &&
       mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD

The above code works fine if dirname is hard-coded. But i need to pass the dirname from command line arguments to script. I am trying like below but no luck.

 'set subdir=$folder;git ls-files -s | sed -i "s-\t\"*-&$subdir/-" |

The sed says input file is missing. I can not directly pass the input file to sed. I am seeing error like below.

Rewrite 9c86de42b7f3228e3d45a278c8caf7e24c8e55cf (1/2) (0 seconds passed, remaining 0 predicted)
sed: no input files


问:
Gtk Terminal Widget
Simple question: Is there a linux-style terminal widget for GTK? Preferably for Haskell, too, as I want to use gtk2hs</p>

答: vte is what is used in gnome-terminal. It seems there are vte haskell bindings.</p>

Title: Gtk Terminal Widget


问:
Storing and querying a date as JSON sting in Firestore, is it a good practice?
is it a good practice if you are storing and querying a date as a string that has the output of Date.toJSON?

It can be data for example from another service.

Are there any query issues or limitations? From my tests comparison on where worked as expected but I fear I might miss some gotcha.

答:
I wouldn't do that.  It will limit what you can do with that date value.

The best practice is to use Firestore's native timestamp type, which you can target easily in security rules.  If for some reason that's not going to work, you should use an integer, usually milliseconds since epoch.


问:
Sql query to map user log table to user first, last and previous activity
I have a user log table, partitioned on action_date (table name - user_action_log) consisting billions of rows, with columns

user_id, action_name, action_date

Sample data -

```<code>+---------+-------------+-------------+
| user_id | action_name | action_date |
+---------+-------------+-------------+
| 123     | login       | 2018-01-30  |
| 123     | logout      | 2018-01-31  |
| 123     | click       | 2018-02-28  |
| 123     | comment     | 2018-02-15  |
| 123     | post        | 2018-03-15  |
+---------+-------------+-------------+
</code>```

I want to write an ETL/sql to transform this data into something like this (table name - user_action_record).

user_id (Primary key), first_action_date, last_action_date, previous_action_date

Sample output data -

```<code>+---------+-------------------+------------------+---------------------------+
| user_id | first_action_date | last_action_date | previous_last_action_date |
+---------+-------------------+------------------+---------------------------+
| 123     | 2018-01-30        | 2018-03-15       | 2018-02-28                |
+---------+-------------------+------------------+---------------------------+
</code>```

I tried dividing problem into 2 steps -

Insert new users which are not present in user_action_record.

Update existing user by updating "previous_last_action_date" from value in "last_action_date" and update last_action_date based on user_action_log table.

The problem is that, since user_action_log is partitioned on action_date, i can query that table on a daily basis (action_date = CURRENT_DATE)

Can anybody help me with sqls to populate my target table in this case?

-- Edited with additional info below

Source and expected target table on day '2018-01-30'

```<code>+---------+-------------+-------------+
| user_id | action_name | action_date |
+---------+-------------+-------------+
| 123     | login       | 2018-01-30  |
| 123     | logout      | 2018-01-30  |
| 123     | click       | 2018-01-30  |
+---------+-------------+-------------+

</code>```

```<code>+---------+-------------------+------------------+---------------------------+
| user_id | first_action_date | last_action_date | previous_last_action_date |
+---------+-------------------+------------------+---------------------------+
| 123     | 2018-01-30        | 2018-01-30       | 2018-01-30                |
+---------+-------------------+------------------+---------------------------+
</code>```

Source and expected target table on day '2018-01-31'

```<code>+---------+-------------+-------------+
| user_id | action_name | action_date |
+---------+-------------+-------------+
| 123     | login       | 2018-01-30  |
| 123     | logout      | 2018-01-30  |
| 123     | click       | 2018-01-30  |
| 123     | login       | 2018-01-31  |
| 123     | logout      | 2018-01-31  |
+---------+-------------+-------------+

</code>```

```<code>+---------+-------------------+------------------+---------------------------+
| user_id | first_action_date | last_action_date | previous_last_action_date |
+---------+-------------------+------------------+---------------------------+
| 123     | 2018-01-30        | 2018-01-31       | 2018-01-30                |
+---------+-------------------+------------------+---------------------------+
</code>```

Source and expected target table on day '2018-02-15'

```<code>+---------+-------------+-------------+
| user_id | action_name | action_date |
+---------+-------------+-------------+
| 123     | login       | 2018-01-30  |
| 123     | logout      | 2018-01-30  |
| 123     | click       | 2018-01-30  |
| 123     | login       | 2018-01-31  |
| 123     | logout      | 2018-01-31  |
| 123     | logout      | 2018-02-15  |
| 123     | logout      | 2018-02-15  |
+---------+-------------+-------------+

</code>```

```<code>+---------+-------------------+------------------+---------------------------+
| user_id | first_action_date | last_action_date | previous_last_action_date |
+---------+-------------------+------------------+---------------------------+
| 123     | 2018-01-30        | 2018-02-15       | 2018-01-31                |
+---------+-------------------+------------------+---------------------------+
</code>```

答:
You can simulate a ranking function in MySQL < 8 with a self-join on user_id where the row in the second table has a later action_date:

```<code>SELECT u1.*, COUNT(u2.user_id) AS rn
FROM user_action_log u1
LEFT JOIN user_action_log u2 ON u2.user_id = u1.user_id AND u2.action_date > u1.action_date
GROUP BY u1.user_id, u1.action_name, u1.action_date
ORDER BY rn;
</code>```

Output:

```<code>user_id action_name action_date rn
123     post        2018-03-15  0
123     click       2018-02-28  1
123     comment     2018-02-15  2
123     logout      2018-01-31  3
123     login       2018-01-30  4
</code>```

This table can then be used as a derived table, and we can find the previous_last_action_date from the row with rn = 1:

```<code>SELECT user_id,
       MIN(action_date) AS first_action_date,
       MAX(action_date) AS last_action_date,
       MAX(CASE WHEN rn = 1 THEN action_date END) AS previous_last_action_date
FROM (SELECT u1.*, COUNT(u2.user_id) AS rn
      FROM user_action_log u1
      LEFT JOIN user_action_log u2 ON u2.user_id = u1.user_id AND u2.action_date > u1.action_date
      GROUP BY u1.user_id, u1.action_name, u1.action_date) ual
GROUP BY user_id
</code>```

Output:

```<code>user_id first_action_date   last_action_date    previous_last_action_date
123     2018-01-30          2018-03-15          2018-02-28
</code>```

Demo on dbfiddle

Body:
I have a user log table, partitioned on action_date (table name - user_action_log) consisting billions of rows, with columns

user_id, action_name, action_date

Sample data -

+---------+-------------+-------------+
| user_id | action_name | action_date |
+---------+-------------+-------------+
| 123     | login       | 2018-01-30  |
| 123     | logout      | 2018-01-31  |
| 123     | click       | 2018-02-28  |
| 123     | comment     | 2018-02-15  |
| 123     | post        | 2018-03-15  |
+---------+-------------+-------------+

I want to write an ETL/sql to transform this data into something like this (table name - user_action_record).

user_id (Primary key), first_action_date, last_action_date, previous_action_date

Sample output data -

+---------+-------------------+------------------+---------------------------+
| user_id | first_action_date | last_action_date | previous_last_action_date |
+---------+-------------------+------------------+---------------------------+
| 123     | 2018-01-30        | 2018-03-15       | 2018-02-28                |
+---------+-------------------+------------------+---------------------------+

I tried dividing problem into 2 steps -

Insert new users which are not present in user_action_record.

Update existing user by updating "previous_last_action_date" from value in "last_action_date" and update last_action_date based on user_action_log table.

The problem is that, since user_action_log is partitioned on action_date, i can query that table on a daily basis (action_date = CURRENT_DATE)

Can anybody help me with sqls to populate my target table in this case?

-- Edited with additional info below

Source and expected target table on day '2018-01-30'

+---------+-------------+-------------+
| user_id | action_name | action_date |
+---------+-------------+-------------+
| 123     | login       | 2018-01-30  |
| 123     | logout      | 2018-01-30  |
| 123     | click       | 2018-01-30  |
+---------+-------------+-------------+

+---------+-------------------+------------------+---------------------------+
| user_id | first_action_date | last_action_date | previous_last_action_date |
+---------+-------------------+------------------+---------------------------+
| 123     | 2018-01-30        | 2018-01-30       | 2018-01-30                |
+---------+-------------------+------------------+---------------------------+

Source and expected target table on day '2018-01-31'

+---------+-------------+-------------+
| user_id | action_name | action_date |
+---------+-------------+-------------+
| 123     | login       | 2018-01-30  |
| 123     | logout      | 2018-01-30  |
| 123     | click       | 2018-01-30  |
| 123     | login       | 2018-01-31  |
| 123     | logout      | 2018-01-31  |
+---------+-------------+-------------+

+---------+-------------------+------------------+---------------------------+
| user_id | first_action_date | last_action_date | previous_last_action_date |
+---------+-------------------+------------------+---------------------------+
| 123     | 2018-01-30        | 2018-01-31       | 2018-01-30                |
+---------+-------------------+------------------+---------------------------+

Source and expected target table on day '2018-02-15'

+---------+-------------+-------------+
| user_id | action_name | action_date |
+---------+-------------+-------------+
| 123     | login       | 2018-01-30  |
| 123     | logout      | 2018-01-30  |
| 123     | click       | 2018-01-30  |
| 123     | login       | 2018-01-31  |
| 123     | logout      | 2018-01-31  |
| 123     | logout      | 2018-02-15  |
| 123     | logout      | 2018-02-15  |
+---------+-------------+-------------+

+---------+-------------------+------------------+---------------------------+
| user_id | first_action_date | last_action_date | previous_last_action_date |
+---------+-------------------+------------------+---------------------------+
| 123     | 2018-01-30        | 2018-02-15       | 2018-01-31                |
+---------+-------------------+------------------+---------------------------+

Body:
You can simulate a ranking function in MySQL < 8 with a self-join on user_id where the row in the second table has a later action_date:

SELECT u1.*, COUNT(u2.user_id) AS rn
FROM user_action_log u1
LEFT JOIN user_action_log u2 ON u2.user_id = u1.user_id AND u2.action_date > u1.action_date
GROUP BY u1.user_id, u1.action_name, u1.action_date
ORDER BY rn;

Output:

user_id action_name action_date rn
123     post        2018-03-15  0
123     click       2018-02-28  1
123     comment     2018-02-15  2
123     logout      2018-01-31  3
123     login       2018-01-30  4

This table can then be used as a derived table, and we can find the previous_last_action_date from the row with rn = 1:

SELECT user_id,
       MIN(action_date) AS first_action_date,
       MAX(action_date) AS last_action_date,
       MAX(CASE WHEN rn = 1 THEN action_date END) AS previous_last_action_date
FROM (SELECT u1.*, COUNT(u2.user_id) AS rn
      FROM user_action_log u1
      LEFT JOIN user_action_log u2 ON u2.user_id = u1.user_id AND u2.action_date > u1.action_date
      GROUP BY u1.user_id, u1.action_name, u1.action_date) ual
GROUP BY user_id

Output:

user_id first_action_date   last_action_date    previous_last_action_date
123     2018-01-30          2018-03-15          2018-02-28

Demo on dbfiddle