问:
Making a input range that perfectly aligns with numbers above it
I have a slider that goes from 1 to 12. I would like the thumb to perfectly align with all the numbers above it when I move it up and down.

This is what I have so far, but as you can see, it is still slightly off.

Is there a way to achieve this?

body {
  height: 100vh;
  display: flex;
}

.container {
  margin: auto;
  width: 400px;
}

span {
  display: block;
  width: 1ch;
}

.numbers {
  display: flex;
  justify-content: space-between;
  padding-left: .4em;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="container">
  <div class="numbers">
    <span>1</span><span>2</span><span>3</span><span>4</span><span>5</span><span>6</span><span>7</span><span>8</span><span>9</span><span>10</span><span>11</span><span>12</span>
  </div>
  <input style="width: 100%;" type="range" min="1" max="12" name="" id="" />
</div></code>```

答:
I think they can't be easily arranged, according to the idea you have to play with a margin left right or width : 0%; etc ...

If you want it is an alternative

const range = document.getElementById("range"),
    rangeV = document.getElementById("rangeV"),
    setValue = () => {
        const newValue = Number(((range.value - range.min) * 100) / (range.max - range.min)),
            newPosition = 10 - newValue * 0.2;
        rangeV.innerHTML = `<span>${range.value}</span>`;
        rangeV.style.left = `calc(${newValue}% + (${newPosition}px))`;
    };
document.addEventListener("DOMContentLoaded", setValue);
range.addEventListener("input", setValue);```
<pre class="snippet-code-css lang-css prettyprint-override"><code>body {
    min-height: 100vh;
    padding: 0 10vh;
    margin: 0;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
}
input[type="range"] {
    -webkit-appearance: none;
    margin: 20px 0;
    width: 100%;
}
input[type="range"]:focus {
    outline: none;
}
input[type="range"]::-webkit-slider-runnable-track {
    width: 100%;
    height: 4px;
    cursor: pointer;
    animate: 0.2s;
    background: #03a9f4;
    border-radius: 25px;
}
input[type="range"]::-webkit-slider-thumb {
    height: 20px;
    width: 20px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 0 4px 0 rgba(0, 0, 0, 1);
    cursor: pointer;
    -webkit-appearance: none;
    margin-top: -8px;
}
input[type="range"]:focus::-webkit-slider-runnable-track {
    background: #03a9f4;
}
.range-wrap {
    width: 500px;
    position: relative;
}
.range-value {
    position: absolute;
    top: -50%;
}
.range-value span {
    width: 30px;
    height: 24px;
    line-height: 24px;
    text-align: center;
    background: #03a9f4;
    color: #fff;
    font-size: 12px;
    display: block;
    position: absolute;
    left: 50%;
    transform: translate(-50%, 0);
    border-radius: 6px;
}
.range-value span:before {
    content: "";
    position: absolute;
    width: 0;
    height: 0;
    border-top: 10px solid #03a9f4;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    top: 100%;
    left: 50%;
    margin-left: -5px;
    margin-top: -1px;
}</code>```

<!DOCTYPE html>

        <meta charset="UTF-8" />
        <title>Input Range with Dynamic Label</title>

            <input id="range" type="range" min="1" max="12" value="1" step="1" />

```

Body:
I have a slider that goes from 1 to 12. I would like the thumb to perfectly align with all the numbers above it when I move it up and down.

This is what I have so far, but as you can see, it is still slightly off.

Is there a way to achieve this?

body {
  height: 100vh;
  display: flex;
}

.container {
  margin: auto;
  width: 400px;
}

span {
  display: block;
  width: 1ch;
}

.numbers {
  display: flex;
  justify-content: space-between;
  padding-left: .4em;
}

    123456789101112

  <input style="width: 100%;" type="range" min="1" max="12" name="" id="" />

Body:
I think they can't be easily arranged, according to the idea you have to play with a margin left right or width : 0%; etc ...

If you want it is an alternative

const range = document.getElementById("range"),
    rangeV = document.getElementById("rangeV"),
    setValue = () => {
        const newValue = Number(((range.value - range.min) * 100) / (range.max - range.min)),
            newPosition = 10 - newValue * 0.2;
        rangeV.innerHTML = `<span>${range.value}</span>`;
        rangeV.style.left = `calc(${newValue}% + (${newPosition}px))`;
    };
document.addEventListener("DOMContentLoaded", setValue);
range.addEventListener("input", setValue);

body {
    min-height: 100vh;
    padding: 0 10vh;
    margin: 0;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
}
input[type="range"] {
    -webkit-appearance: none;
    margin: 20px 0;
    width: 100%;
}
input[type="range"]:focus {
    outline: none;
}
input[type="range"]::-webkit-slider-runnable-track {
    width: 100%;
    height: 4px;
    cursor: pointer;
    animate: 0.2s;
    background: #03a9f4;
    border-radius: 25px;
}
input[type="range"]::-webkit-slider-thumb {
    height: 20px;
    width: 20px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 0 4px 0 rgba(0, 0, 0, 1);
    cursor: pointer;
    -webkit-appearance: none;
    margin-top: -8px;
}
input[type="range"]:focus::-webkit-slider-runnable-track {
    background: #03a9f4;
}
.range-wrap {
    width: 500px;
    position: relative;
}
.range-value {
    position: absolute;
    top: -50%;
}
.range-value span {
    width: 30px;
    height: 24px;
    line-height: 24px;
    text-align: center;
    background: #03a9f4;
    color: #fff;
    font-size: 12px;
    display: block;
    position: absolute;
    left: 50%;
    transform: translate(-50%, 0);
    border-radius: 6px;
}
.range-value span:before {
    content: "";
    position: absolute;
    width: 0;
    height: 0;
    border-top: 10px solid #03a9f4;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    top: 100%;
    left: 50%;
    margin-left: -5px;
    margin-top: -1px;
}

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Input Range with Dynamic Label</title>
    </head>
    <body>
        <div class="range-wrap">
            <div class="range-value" id="rangeV"></div>
            <input id="range" type="range" min="1" max="12" value="1" step="1" />
        </div>
    </body>
</html>


来源: stackexchange

问:
CSV file read issue in firebase functions
I am trying to read a csv file in a firebase function so that I can process the file and do the rest operations using the data.

```<code>import * as csv from "csvtojson";
const csvFilePath = "<gdrive shared link>"

try{
    console.log("First Method...")
    csv()
    .fromFile(csvFilePath)
    .then((jsonObj: any)=>{
     console.log("jsonObj....",JSON.stringify(jsonObj));
    })

    console.log("Second Method...")
    const jsonArray=await csv().fromFile(csvFilePath);
    console.log("jsonArray...", JSON.stringify(jsonArray))
         }
catch(e){
    console.log("error",JSON.stringify(e))
}
</code>```

The above mentioned are the 2 methods I have tried for reading the csv but both shows the firebase error

'Error: File does not exist. Check to make sure the file path to your csv is correct.'

In case of 'csvFilePath' I have tried 2 methods

Just added the csv file in same folder of the function and added the code like

```<code>const csvFilePath = "./student.csv"
</code>```

Added the same file to google drive and changed the access permissions to anyone with the link can read and edit and given the path to same

```<code>const csvFilePath = "<gdrive shared link>"
</code>```

Both shows the same error. In case of google drive I don't want to use any sort of google credential because I was intented to read a simple csv file in firebase function.

答:
I will start by proposing that you convert your csv to json locally or without the function and see if it works. This is because I see you are using ES6 imports which might be causing an issue since all the documentation uses require. You can also try CSV Parse or some solutions provided in this question as an alternative, trying them without the function to check if it actually works and discard it. Actually, you can upload the JSON once you have converted it from the csv, but that depends on what you are trying to do.

I think the best way to achieve this, is following the approach given in this question, that first uploads the file into cloud storage and using onFinalize() to trigger the conversion.

Also, will address these three questions that went through similar issues with the path. They were able to fix it by adding __dirname. Each one has some extra useful information.

Context for "relative paths" seems to change to the calling module if a module is imported

The csvtojson converter ignores my file name and just puts undefined

How to avoid the error which throws a csvtojson

ContentLicense: CC BY-SA 4.0

Body:
I am trying to read a csv file in a firebase function so that I can process the file and do the rest operations using the data.

import * as csv from "csvtojson";
const csvFilePath = "<gdrive shared link>"

try{
    console.log("First Method...")
    csv()
    .fromFile(csvFilePath)
    .then((jsonObj: any)=>{
     console.log("jsonObj....",JSON.stringify(jsonObj));
    })

    console.log("Second Method...")
    const jsonArray=await csv().fromFile(csvFilePath);
    console.log("jsonArray...", JSON.stringify(jsonArray))
         }
catch(e){
    console.log("error",JSON.stringify(e))
}

The above mentioned are the 2 methods I have tried for reading the csv but both shows the firebase error

'Error: File does not exist. Check to make sure the file path to your csv is correct.'

In case of 'csvFilePath' I have tried 2 methods

Just added the csv file in same folder of the function and added the code like

const csvFilePath = "./student.csv"

Added the same file to google drive and changed the access permissions to anyone with the link can read and edit and given the path to same

const csvFilePath = "<gdrive shared link>"

Both shows the same error. In case of google drive I don't want to use any sort of google credential because I was intented to read a simple csv file in firebase function.


问:
How the define parser rule for empty array in Antlr 4.0
I have the following set of rules in my Antlr grammar file:

```<code>//myidl.g4

grammar myidl;

integerLiteral:
    value = DecimalLiteral # decimalNumberExpr
    | value = HexadecimalLiteral # hexadecimalNumberExpr
    ;

DecimalLiteral: DIGIT+;

HexadecimalLiteral: ('0x' | '0X') HEXADECIMALDIGIT+;

fragment DIGIT: [0-9];

fragment HEXADECIMALDIGIT: [0-9a-fA-F];

array:
    '[' ( integerLiteral ( ',' integerLiteral )* )* ']' // how to allow empty arrays like "[]"?
    ;
</code>```

The resulting parser works fine for arrays with elements, for example "[0x00]".
But when defining an empty array "[]", i get the error:
no viable alternative at input '[]'

The funny thing is that when defining the empty array with a space, like "[ ]", the parser eats it without error. Can somebody tell me whats wrong with my rules, and how to adjust the rules to allow empty arrays definition without spaces, "[]"?

I use ANTLR Parser Generator  Version 4.9.2

EDIT:
It turns out that I was using an old version of the parser due to configuration issue. |=( The above rules work just fine.

答:
The grammar copied above works correctly in my opinion.
must match [] and not [ ] (with space).

As already suggested check the tokens and if you have imported other lexer check that you don't have token like '[]'.

The following grammar:

```<code>    grammar myidl;

    integerLiteral: DecimalLiteral | HexadecimalLiteral;

    DecimalLiteral: DIGIT+;

    HexadecimalLiteral: ('0x' | '0X') HEXADECIMALDIGIT+;

    fragment DIGIT: [0-9];

    fragment HEXADECIMALDIGIT: [0-9a-fA-F];

    array:
        '[' ( integerLiteral ( ',' integerLiteral )* )* ']';

    WS  : [ \t] -> skip ;
</code>```

match:

[0x00]

[]

[ ]

Body:
I have the following set of rules in my Antlr grammar file:

//myidl.g4

grammar myidl;

integerLiteral:
    value = DecimalLiteral # decimalNumberExpr
    | value = HexadecimalLiteral # hexadecimalNumberExpr
    ;

DecimalLiteral: DIGIT+;

HexadecimalLiteral: ('0x' | '0X') HEXADECIMALDIGIT+;

fragment DIGIT: [0-9];

fragment HEXADECIMALDIGIT: [0-9a-fA-F];

array:
    '[' ( integerLiteral ( ',' integerLiteral )* )* ']' // how to allow empty arrays like "[]"?
    ;

The resulting parser works fine for arrays with elements, for example "[0x00]".
But when defining an empty array "[]", i get the error:
no viable alternative at input '[]'

The funny thing is that when defining the empty array with a space, like "[ ]", the parser eats it without error. Can somebody tell me whats wrong with my rules, and how to adjust the rules to allow empty arrays definition without spaces, "[]"?

I use ANTLR Parser Generator  Version 4.9.2

EDIT:
It turns out that I was using an old version of the parser due to configuration issue. |=( The above rules work just fine.

Body:
The grammar copied above works correctly in my opinion.
must match [] and not [ ] (with space).

As already suggested check the tokens and if you have imported other lexer check that you don't have token like '[]'.

The following grammar:

    grammar myidl;

    integerLiteral: DecimalLiteral | HexadecimalLiteral;

    DecimalLiteral: DIGIT+;

    HexadecimalLiteral: ('0x' | '0X') HEXADECIMALDIGIT+;

    fragment DIGIT: [0-9];

    fragment HEXADECIMALDIGIT: [0-9a-fA-F];

    array:
        '[' ( integerLiteral ( ',' integerLiteral )* )* ']';

    WS  : [ \t] -> skip ;

match:

[0x00]

[]

[ ]


问:
how to update service worker when online and reloading the page
Hello all I am having the following code to load the page on offline, I have a requirement where I need to cache few pages and exclude few from cache. The code I wrote is working fine but when ever I push any updates to the site it is loading from cache how to reload it from server instead of cache when online

I referred to this blog and sum up with some modifications

https://www.charistheo.io/blog/2021/03/cache-handling-with-service-workers-and-the-cache-api/

```<code>self.addEventListener("install", function (e) {
     self.skipWaiting();
     e.waitUntil(async function () {
     const cache = await caches.open("app");
     await cache.addAll([
        "/Scripts/jquery-3.6.0.min.js",
        "/ReportableEvent/Index",
        "/NearMissReport/Index",
        "/ReportableEvent/InternalReview?ReportableEventId=0"
     )];
    }());
});

var uncachedPaths = new Set(["/Reportable/Reports", "/Dashboard/Index"]);
self.addEventListener("fetch", async function (e) {
   if (e.request.method !== "GET") {
    return;
  }
  e.respondWith(
    caches.match(e.request, { ignoreSearch: true }).then(async cachedResponse => {
        if (cachedResponse) {
            return cachedResponse;
        }
        else {
            if (e.request.url.includes("service-worker.js") && !navigator.onLine) {
                return;
            }

            // Fetch the requested resource from the network if it does not exist in the cache.
            const networkResponse = await fetch(e.request);

            // Response needs to be cloned if going to be used more than once.
            const clonedResponse = networkResponse.clone();

            if (!uncachedPaths.has(new URL(e.request.url).pathname)) {
                // Save response to runtime cache for later use.
                const runtimeCache = await caches.open("app");
                runtimeCache.put(e.request, networkResponse);
            }
            // Respond with the cloned network response.
            return Promise.resolve(clonedResponse);
        }
    })
);
});
</code>```

Also is this correct to cache the page which has Query strings "/ReportableEvent/InternalReview?ReportableEventId=0"

答:
There are various approaches how to serve files from cache and how to update/invalidate the cache. please, refer here.

Also, if you are updating your service worker js files and want to update the cache as well, try appending version to cache name. For instance,

```<code>var version = 1.0;
var cachename= 'app'+version;
</code>```

And every time you update the file, you can increment the version. This way every updates makes it new cache and files are stored afresh in cache.

Body:
Hello all I am having the following code to load the page on offline, I have a requirement where I need to cache few pages and exclude few from cache. The code I wrote is working fine but when ever I push any updates to the site it is loading from cache how to reload it from server instead of cache when online

I referred to this blog and sum up with some modifications

https://www.charistheo.io/blog/2021/03/cache-handling-with-service-workers-and-the-cache-api/

self.addEventListener("install", function (e) {
     self.skipWaiting();
     e.waitUntil(async function () {
     const cache = await caches.open("app");
     await cache.addAll([
        "/Scripts/jquery-3.6.0.min.js",
        "/ReportableEvent/Index",
        "/NearMissReport/Index",
        "/ReportableEvent/InternalReview?ReportableEventId=0"
     )];
    }());
});

var uncachedPaths = new Set(["/Reportable/Reports", "/Dashboard/Index"]);
self.addEventListener("fetch", async function (e) {
   if (e.request.method !== "GET") {
    return;
  }
  e.respondWith(
    caches.match(e.request, { ignoreSearch: true }).then(async cachedResponse => {
        if (cachedResponse) {
            return cachedResponse;
        }
        else {
            if (e.request.url.includes("service-worker.js") && !navigator.onLine) {
                return;
            }

            // Fetch the requested resource from the network if it does not exist in the cache.
            const networkResponse = await fetch(e.request);

            // Response needs to be cloned if going to be used more than once.
            const clonedResponse = networkResponse.clone();

            if (!uncachedPaths.has(new URL(e.request.url).pathname)) {
                // Save response to runtime cache for later use.
                const runtimeCache = await caches.open("app");
                runtimeCache.put(e.request, networkResponse);
            }
            // Respond with the cloned network response.
            return Promise.resolve(clonedResponse);
        }
    })
);
});

Also is this correct to cache the page which has Query strings "/ReportableEvent/InternalReview?ReportableEventId=0"

Body:
There are various approaches how to serve files from cache and how to update/invalidate the cache. please, refer here.

Also, if you are updating your service worker js files and want to update the cache as well, try appending version to cache name. For instance,

var version = 1.0;
var cachename= 'app'+version;

And every time you update the file, you can increment the version. This way every updates makes it new cache and files are stored afresh in cache.


问:
CORS Laravel VueJS
I'm trying to do a get with axios from VueJS to Laravel which is my API.

I got this error :

Access to XMLHttpRequest at 'http://api.test/api/events/1/' from origin >'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control->Allow-Origin' header is present on the requested resource.

Uncaught (in promise) Error: Network Error
  at createError (createError.js?2d83:16)
  at XMLHttpRequest.handleError (xhr.js?b50d:87)

I've tried to create a middleware named 'cors' like here but it's not working for me or maybe I'm doing it badly ?

Strange thing ? is that's working with Postman.

Thank for the help ! :)

答:
Tried sending Axios request from Vue app to Laravel backend.

I had CORS Error and I couldn't find the solution.

After following request execution in vendor files I found out that I was simply testing it wrong.

I was testing on url: http://localhost/api, but in config/cors.php there is:

```<code>'paths' => ['api/*', 'sanctum/csrf-cookie'],
</code>```

So all I had to do was to change request to http://localhost/api/... and it started working.
Another solution is adding 'api' to paths array in config/cors.php if you want to use http://localhost/api

Title: CORS Laravel VueJS

Body:
Tried sending Axios request from Vue app to Laravel backend.

I had CORS Error and I couldn't find the solution.

After following request execution in vendor files I found out that I was simply testing it wrong.

I was testing on url: http://localhost/api, but in config/cors.php there is:

'paths' => ['api/*', 'sanctum/csrf-cookie'],

So all I had to do was to change request to http://localhost/api/... and it started working.
Another solution is adding 'api' to paths array in config/cors.php if you want to use http://localhost/api


问:
How to convert from any type to std::string in C++
I'm making a LinkedList class using template, since I want to use it for whatever type I need afterwards

```<code>template <typename T> class LinkedList {}
</code>```

I'm trying to make a function that adds all the elements of a list into a string:

```<code>std::string join(const char *seperator)
{
    std::string str;
    auto curr = this->head;
    while (curr)
    {
        str += std::to_string(curr->value);
        if (curr->next)
            str += seperator;
        curr = curr->next;
    }
    return str;
}
</code>```

It works with the types I tested (int, double, float...) but doesn't work with std::string, the to_string() function generates an error

Error C2665   'std::to_string': none of the 9 overloads could convert
all the argument types

I assume it doesn't work with other types. so, can you provide a general method to convert from any type to std::string.

答:
There is no universal way to convert an object of arbitrary type to a string in C++. But the most commonly supported facility for outputting data as strings are output streams. So, you could use std::ostringstream like this:

```<code>std::string join(const char *seperator)
{
    std::ostringstream strm;
    auto curr = this->head;
    while (curr)
    {
        strm << curr->value;
        if (curr->next)
            strm << seperator;
        curr = curr->next;
    }
    return strm.str();
}
</code>```

Note that for this to work the type T should provide an operator<< overload that takes std::ostream& as the first argument. All arithmetic types, C-style strings and std::string are supported by this facility, but not all user-defined types may be.

Body:
I'm making a LinkedList class using template, since I want to use it for whatever type I need afterwards

template <typename T> class LinkedList {}

I'm trying to make a function that adds all the elements of a list into a string:

std::string join(const char *seperator)
{
    std::string str;
    auto curr = this->head;
    while (curr)
    {
        str += std::to_string(curr->value);
        if (curr->next)
            str += seperator;
        curr = curr->next;
    }
    return str;
}

It works with the types I tested (int, double, float...) but doesn't work with std::string, the to_string() function generates an error

Error C2665   'std::to_string': none of the 9 overloads could convert
all the argument types

I assume it doesn't work with other types. so, can you provide a general method to convert from any type to std::string.

Body:
There is no universal way to convert an object of arbitrary type to a string in C++. But the most commonly supported facility for outputting data as strings are output streams. So, you could use std::ostringstream like this:

std::string join(const char *seperator)
{
    std::ostringstream strm;
    auto curr = this->head;
    while (curr)
    {
        strm << curr->value;
        if (curr->next)
            strm << seperator;
        curr = curr->next;
    }
    return strm.str();
}

Note that for this to work the type T should provide an operator<< overload that takes std::ostream& as the first argument. All arithmetic types, C-style strings and std::string are supported by this facility, but not all user-defined types may be.


问:
How to convert RTF to Markdown on the UNIX/OSX command line similar to pandoc
How do I convert RTF (say from stdin) to Markdown with a command line tool under UNIX/OSX.

I am looking for something like pandoc. However pandoc itself does not allow RTF as an input format. :-( So, I'd be happy either with a similar tool to pandoc or a pointer to an external RTF reader for pandoc.

答:
Pandoc now supports RTF as an input format, so you can use:

cat file.rtf | pandoc --from=rtf --to=markdown
```

ContentLicense: CC BY-SA 3.0


问:
R: instrument function to capture all assignments
Given a regular R function f, I'd like to be able to create a new function f_debug that acts just like f, but lets me keep track of all the assignments to function-local variables that happened inside it.

For example:

f <- function(x, y) {
  z <- x + y
  df <- data.frame(z=z)
  df
}

# This function doesn't work as intended - would like it to (in the case of `f` above)
# write out a list containing `z` and `df` to an RDS file
capturing <- function(func) {
  e <- new.env()
  altered <- function(...) {
    parent <- parent.frame()
    e <- something...(func, environment(), parent, etc., etc.)
    result <- func(...)
    saveRDS(as.list(e), 'foo.rds')
    result
  }
  environment(func) <- e
  altered
}

f_debug <- capturing(f)
```

I'm not sure whether my knowledge gap to do this is large or small, anyone have a solution?

答:
Solution 1: Steal the function's code

Here's a solution which doesn't return a new function which captures intermediate calculations, but rather calls the given function's code internally. There's some limitations, such as it probably only works with named arguments. Instead of storing the intermediate calculations as an RDS, it attaches them as an attribute.

```<code>capturing <- function(fun, ...) {
  fun <- match.fun(fun)
  code <- body(fun)
  parent <- environment(fun)
  env <- new.env(parent = parent)
  for (val in names(list(...))) {
    env[[val]] <- list(...)[[val]]
  }
  result <- eval(code, envir = env, enclos = parent.frame())
  attr(result, "intermediate") <- env
  result
}

my_add <- function(x, y) {
  z <- x+y
  u <- x-y
  w <- x*y
  x + y
}

intermediates <- function(x) {
  attr(x, "intermediate", exact = TRUE)
}

value <- capturing(my_add, x = 1, y = 7)
ls(envir = intermediates(value))
#> [1] "u" "w" "x" "y" "z"
intermediates(value)$x
#> [1] 1
# Created on 2022-02-08 by the reprex package (v2.0.1)
</code>```

Solution 2: Modify the function's code

One weakness of this solution is that if the chosen function features a call to on.exit(add=FALSE), some additional work needs to be done to modify the function so the internal environment is captured. However, it does work when the function accepts ... arguments.

my_add <- function(x, y) {
  z <- x+y
  u <- x-y
  w <- x*y
  x + y
}

insert_capture <- function(code) {
  # `<<-` assigns into the global environment if no variable of the given name is found
  # while traveling up to the global environment. If you need this assignment to go elsewhere,
  # I'd recommend passing in `assign()`. Of course, you could also modify the `on.exit()`
  # to use saveRDS.
  parse(text=append(deparse(code),
                            "on.exit(._last_capture <<- environment(), add = TRUE)",
                            after = 1L))
}
capturing2 <- function(fun) {
  fun <- match.fun(fun)
  code <- insert_capture(body(fun))
  body(fun) <- code
  fun
}

my_add2 <- capturing2(my_add)

my_add2(1, 7)
#> [1] 8
ls(envir = ._last_capture)
#> [1] "u" "w" "x" "y" "z"
._last_capture$u
#> [1] -6
```

Created on 2022-02-08 by the reprex package (v2.0.1)

Body:
Given a regular R function f, I'd like to be able to create a new function f_debug that acts just like f, but lets me keep track of all the assignments to function-local variables that happened inside it.

For example:

f <- function(x, y) {
  z <- x + y
  df <- data.frame(z=z)
  df
}

# This function doesn't work as intended - would like it to (in the case of `f` above)
# write out a list containing `z` and `df` to an RDS file
capturing <- function(func) {
  e <- new.env()
  altered <- function(...) {
    parent <- parent.frame()
    e <- something...(func, environment(), parent, etc., etc.)
    result <- func(...)
    saveRDS(as.list(e), 'foo.rds')
    result
  }
  environment(func) <- e
  altered
}

f_debug <- capturing(f)

I'm not sure whether my knowledge gap to do this is large or small, anyone have a solution?

Body:
Solution 1: Steal the function's code

Here's a solution which doesn't return a new function which captures intermediate calculations, but rather calls the given function's code internally. There's some limitations, such as it probably only works with named arguments. Instead of storing the intermediate calculations as an RDS, it attaches them as an attribute.

capturing <- function(fun, ...) {
  fun <- match.fun(fun)
  code <- body(fun)
  parent <- environment(fun)
  env <- new.env(parent = parent)
  for (val in names(list(...))) {
    env[[val]] <- list(...)[[val]]
  }
  result <- eval(code, envir = env, enclos = parent.frame())
  attr(result, "intermediate") <- env
  result
}

my_add <- function(x, y) {
  z <- x+y
  u <- x-y
  w <- x*y
  x + y
}

intermediates <- function(x) {
  attr(x, "intermediate", exact = TRUE)
}

value <- capturing(my_add, x = 1, y = 7)
ls(envir = intermediates(value))
#> [1] "u" "w" "x" "y" "z"
intermediates(value)$x
#> [1] 1
# Created on 2022-02-08 by the reprex package (v2.0.1)

Solution 2: Modify the function's code

One weakness of this solution is that if the chosen function features a call to on.exit(add=FALSE), some additional work needs to be done to modify the function so the internal environment is captured. However, it does work when the function accepts ... arguments.

my_add <- function(x, y) {
  z <- x+y
  u <- x-y
  w <- x*y
  x + y
}

insert_capture <- function(code) {
  # `<<-` assigns into the global environment if no variable of the given name is found
  # while traveling up to the global environment. If you need this assignment to go elsewhere,
  # I'd recommend passing in `assign()`. Of course, you could also modify the `on.exit()`
  # to use saveRDS.
  parse(text=append(deparse(code),
                            "on.exit(._last_capture <<- environment(), add = TRUE)",
                            after = 1L))
}
capturing2 <- function(fun) {
  fun <- match.fun(fun)
  code <- insert_capture(body(fun))
  body(fun) <- code
  fun
}

my_add2 <- capturing2(my_add)

my_add2(1, 7)
#> [1] 8
ls(envir = ._last_capture)
#> [1] "u" "w" "x" "y" "z"
._last_capture$u
#> [1] -6

Created on 2022-02-08 by the reprex package (v2.0.1)


问:
Uncaught SyntaxError: Cannot use import statement outside a module" When Importing React
I'm starting to learn react from this tutorial https://www.youtube.com/watch?v=DLX62G4lc44
so I did first 2 chapters and all good, then a week later I run the same code exactly and started to get this error:
Uncaught SyntaxError: Cannot use import statement outside a module
I tried every thing on the web, best thing I got is put type="module" or type="text"
the error gone but nothing shows up at the page!
and got this new error:
Uncaught SyntaxError: Unexpected token '<'
can somebody please help, I'm starting to give up please help here is the code:

HTML:

```<code><!DOCTYPE html>
<html lang="en">
<head>
    <title>React</title>
</head>
<body>
    <h1>Hello React</h1>
    <div id="root"></div>
    <script src="index.js"></script>
</body>
</html>
</code>```

JS:

```<code>import React from "react"
import ReactDOM from "react-dom"
function MyApp(){
    return(
        <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
        </ul>
    )
}
ReactDOM.render(<MyApp/>,document.getElementById("root"))
</code>```

答:
```<code>Uncaught SyntaxError: Unexpected token '<'
</code>```

To solve this you need to add to the HTML script tag type="text/babel"
like so:

And to solve the "Uncaught SyntaxError: Cannot use import statement outside a module" I did a quick Google search and found this:

https://nkaushik.com/javascript/solved-cannot-use-import-statement-outside-module/

In short: In your package.json file, simply add “type”:“module”

If you don't have a package.json here are the docs on how to make one:

https://docs.npmjs.com/creating-a-package-json-file

Write in console npm install react-scripts
than make sure you're package.json file have this:

```<code>  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }
</code>```

Don't forget to add a comma, after that in console write npm start

Body:
I'm starting to learn react from this tutorial https://www.youtube.com/watch?v=DLX62G4lc44
so I did first 2 chapters and all good, then a week later I run the same code exactly and started to get this error:
Uncaught SyntaxError: Cannot use import statement outside a module
I tried every thing on the web, best thing I got is put type="module" or type="text"
the error gone but nothing shows up at the page!
and got this new error:
Uncaught SyntaxError: Unexpected token '<'
can somebody please help, I'm starting to give up please help here is the code:

HTML:

<!DOCTYPE html>

    <title>React</title>

Hello React

JS:

import React from "react"
import ReactDOM from "react-dom"
function MyApp(){
    return(

1

2

3

    )
}
ReactDOM.render(<MyApp/>,document.getElementById("root"))

Body:
Uncaught SyntaxError: Unexpected token '<'

To solve this you need to add to the HTML script tag type="text/babel"
like so: <script src="path/to/script" type="text/babel"></script>

And to solve the "Uncaught SyntaxError: Cannot use import statement outside a module" I did a quick Google search and found this:

https://nkaushik.com/javascript/solved-cannot-use-import-statement-outside-module/

In short: In your package.json file, simply add “type”:“module”

If you don't have a package.json here are the docs on how to make one:

https://docs.npmjs.com/creating-a-package-json-file

Write in console npm install react-scripts
than make sure you're package.json file have this:

  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }

Don't forget to add a comma, after that in console write npm start


问:
sum() to remove bracket in a double list
I just saw someone wrote this below and got confused why sum() could be used to remove the bracket from another list:

```<code>pwd = [['x'], ['y'], ['z']]

a = sum(pwd, [])
print(a)          // ['x', 'y', 'z']
</code>```

By looking up sum() definition…

sum(iterable, /, start=0)`

iterable can be anything, list, tuples or dictionaries, but most importantly it should be numeric.

start is added to the sum of numbers in the iterable.
If start is not given in the syntax, it is assumed to be 0.

How does an empty list as start argument of sum() remove the list from another list? This puzzles me…could anyone demystify this?

答:
Think about what sum does. This:

```<code>x = sum([1,2,3,4],0)
</code>```

Is the same as

```<code>x = 0 + 1 + 2 + 3 + 4
</code>```

Similarly,

```<code>x = sum([['x'],['y'],['z']], [])
</code>```

Is the same as

```<code>x = [] + ['x'] + ['y'] + ['z']
</code>```

And that results in x = ['x','y','z'].  It's a side effect of the fact that the list type overrides the + operator.

Body:
I just saw someone wrote this below and got confused why sum() could be used to remove the bracket from another list:

pwd = [['x'], ['y'], ['z']]

a = sum(pwd, [])
print(a)          // ['x', 'y', 'z']

By looking up sum() definition…

sum(iterable, /, start=0)`

iterable can be anything, list, tuples or dictionaries, but most importantly it should be numeric.

start is added to the sum of numbers in the iterable.
If start is not given in the syntax, it is assumed to be 0.

How does an empty list as start argument of sum() remove the list from another list? This puzzles me…could anyone demystify this?

Body:
Think about what sum does. This:

x = sum([1,2,3,4],0)

Is the same as

x = 0 + 1 + 2 + 3 + 4

Similarly,

x = sum([['x'],['y'],['z']], [])

Is the same as

x = [] + ['x'] + ['y'] + ['z']

And that results in x = ['x','y','z'].  It's a side effect of the fact that the list type overrides the + operator.


问:
Attempting to parse numbers from strings and store in array but array seems to have no contents after more than one iteration
My program has the goal of parsing the string "Ge34eks-f10or-Gee59ks". It does this by using strtok to split on delimiter '-' into three tokens Ge34eks, f10or, and Gee59ks. Each token is passed into num_extraction func with the goal of getting the numbers from each token: 34, 10, 59. I want to keep spaces between each token's numbers, so they will be stored in an array with a zero in between each number : [34, 0, 10, 0, 59]. When attempting to print array nothing appears. Note: The while loop handles the second and third token, so if it is commented out, the first token number,34,is correctly printed.

Specific issue: Nothing is printed? And no error is given
Guesses: Either something wrong with my count variable or my array is not properly storing the numbers.

```<code>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int* num_extraction(char* a, int* arr, int* index)
{
    char* p = a;
    //int i = 0;
    while (*p)
    {  // While there are more characters to process...
        if (isdigit(*p) || ((*p == '-' || *p == '+') && isdigit(*(p + 1))))
        {
            // Found a number
            arr[*index] = strtol(p, &p, 10);  // Read number
            //printf("%d\n", val);          // and print it.
            *(index)++;
        }
        else
        {
            // Otherwise, move on to the next character.
            p++;
        }

    }
    return arr;

}

int main()
{
    char str[] = "Ge34eks-f10or-Gee59ks";
    int array[100] = { 0 };
    //int* p = array;
    int count = 0;
    int* q = &count;

    // Returns first token
    char *token = strtok(str, "-");
    num_extraction(token, array, q);
    count += 2;

    // Keep printing tokens while one of the
    // delimiters present in str[].

    while (token != NULL) // problem starts here if loop is commented out first token number is printed
    {
        //printf("%s\n", token);
        token = strtok(NULL, "-");
        num_extraction(token, array, q);
        count += 2;
    }

    for(int i = 0; i < count; i++)
    {
        printf("%d\n", array[i]);
    }
    //printf("%d\n", count);
    return 0;
}
</code>```

Verion 2

```<code>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

char* char_extraction(char* a, char* arr, int* index)
{
    char* p = a;

    for( int i = 0; i < strlen(p); i++)
    {
        printf("%s\n", "test"); // ISSUE: ONLY PRINTS TWICE?
        if(isalpha(p[i]))
        {

            arr[*index] = p[i];
            //printf("%c\n", arr[*index]);
            *(index)++;
        }
    }
    return arr;

}

int main()
{
    char str[] = "Ge34eks-f10or-Gee59ks";
    int array[100] = { 0 };
    char array1[100] = "";
    int count1 = 0;
    int* r = &count1;

    // Returns first token
    char *token = strtok(str, "-");

    char_extraction(token, array1, r); // called once

    count1 += 2;

    // Keep printing tokens while one of the
    // delimiters present in str[].

    while ((token = strtok(NULL, "-")) != NULL)
    {

        char_extraction(token, array1, r); // should be called twice
        count1 += 2;
    }

    for(int i = 0; i < count1; i++)
    {
        printf("%c\n", array1[i]);
    }

    //printf("%d\n", count);
    return 0;
}

</code>```

答:
look here - see inline comments

```<code>while (token != NULL)
{
    // token not null here from last loop
    token = strtok(NULL, "-");
    // now token is null if last
    num_extraction(token, array, q);
    count += 2;
}
</code>```

you need to do

```<code>// get next token then test if NULL
while ((token = strtok(NULL, "-")) != NULL)
{
    num_extraction(token, array, q);
    count += 2;
}
</code>```

or

```<code>// get next token then test if NULL
for(;;)
{
   token = strtok(NULL, "-");
    if(token == NULL) break;
    num_extraction(token, array, q);
    count += 2;
}
</code>```

or even

```<code> while (token = strtok(NULL, "-"))
    {
        //printf("%s\n", token);
        num_extraction(token, array, q);
        count += 2;
    }
</code>```

Body:
My program has the goal of parsing the string "Ge34eks-f10or-Gee59ks". It does this by using strtok to split on delimiter '-' into three tokens Ge34eks, f10or, and Gee59ks. Each token is passed into num_extraction func with the goal of getting the numbers from each token: 34, 10, 59. I want to keep spaces between each token's numbers, so they will be stored in an array with a zero in between each number : [34, 0, 10, 0, 59]. When attempting to print array nothing appears. Note: The while loop handles the second and third token, so if it is commented out, the first token number,34,is correctly printed.

Specific issue: Nothing is printed? And no error is given
Guesses: Either something wrong with my count variable or my array is not properly storing the numbers.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int* num_extraction(char* a, int* arr, int* index)
{
    char* p = a;
    //int i = 0;
    while (*p)
    {  // While there are more characters to process...
        if (isdigit(*p) || ((*p == '-' || *p == '+') && isdigit(*(p + 1))))
        {
            // Found a number
            arr[*index] = strtol(p, &p, 10);  // Read number
            //printf("%d\n", val);          // and print it.
            *(index)++;
        }
        else
        {
            // Otherwise, move on to the next character.
            p++;
        }

    }
    return arr;

}

int main()
{
    char str[] = "Ge34eks-f10or-Gee59ks";
    int array[100] = { 0 };
    //int* p = array;
    int count = 0;
    int* q = &count;

    // Returns first token
    char *token = strtok(str, "-");
    num_extraction(token, array, q);
    count += 2;

    // Keep printing tokens while one of the
    // delimiters present in str[].

    while (token != NULL) // problem starts here if loop is commented out first token number is printed
    {
        //printf("%s\n", token);
        token = strtok(NULL, "-");
        num_extraction(token, array, q);
        count += 2;
    }

    for(int i = 0; i < count; i++)
    {
        printf("%d\n", array[i]);
    }
    //printf("%d\n", count);
    return 0;
}

Verion 2

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

char* char_extraction(char* a, char* arr, int* index)
{
    char* p = a;

    for( int i = 0; i < strlen(p); i++)
    {
        printf("%s\n", "test"); // ISSUE: ONLY PRINTS TWICE?
        if(isalpha(p[i]))
        {

            arr[*index] = p[i];
            //printf("%c\n", arr[*index]);
            *(index)++;
        }
    }
    return arr;

}

int main()
{
    char str[] = "Ge34eks-f10or-Gee59ks";
    int array[100] = { 0 };
    char array1[100] = "";
    int count1 = 0;
    int* r = &count1;

    // Returns first token
    char *token = strtok(str, "-");

    char_extraction(token, array1, r); // called once

    count1 += 2;

    // Keep printing tokens while one of the
    // delimiters present in str[].

    while ((token = strtok(NULL, "-")) != NULL)
    {

        char_extraction(token, array1, r); // should be called twice
        count1 += 2;
    }

    for(int i = 0; i < count1; i++)
    {
        printf("%c\n", array1[i]);
    }

    //printf("%d\n", count);
    return 0;
}

Body:
look here - see inline comments

while (token != NULL)
{
    // token not null here from last loop
    token = strtok(NULL, "-");
    // now token is null if last
    num_extraction(token, array, q);
    count += 2;
}

you need to do

// get next token then test if NULL
while ((token = strtok(NULL, "-")) != NULL)
{
    num_extraction(token, array, q);
    count += 2;
}

or

// get next token then test if NULL
for(;;)
{
   token = strtok(NULL, "-");
    if(token == NULL) break;
    num_extraction(token, array, q);
    count += 2;
}

or even

 while (token = strtok(NULL, "-"))
    {
        //printf("%s\n", token);
        num_extraction(token, array, q);
        count += 2;
    }


问:
Trying to match on multiple characters
Have tried a variety of things but nothing is quite working...

I have the following code:

```<code>        correctList(id, e) {
          if (this.regex.test(e.key)) {
            this.correctLetters.push([e.key, id]);
          }

          this.correctLetters.forEach(
            (array) => {
              if (this.filteredWords.length > 1) {
                this.filteredList = this.filteredWords.filter((word) => word.indexOf(array[0]) === array[1]);
            } else {
                this.filteredList = this.FiveLetterWords.filter((word) => word.indexOf(array[0]) === array[1]);
            }
            this.setFilteredWords(this.filteredList);
            }
          );
        },
</code>```

Where 'this.correctLetters[]' is:

```<code>[[e,0], [l,1], [d,2]...]
</code>```

This is built up using inputs and the order they are typed is the index number ( the 0, 1, 2 in the arrays)

and

'this.filteredWords' is:

```<code>["cigar", "rebut", "sissy", "humph", "awake", "blush",  "focal", "evade", "naval", "serve", "heath", "dwarf", "model", "karma", "stink", "grade", "quiet", "bench", "abate", "feign", "major", "death", "fresh", "crust", "stool", "colon", "abase", "marry", "react", "batty", "pride", "floss", "helix", "croak", "staff", "paper", "unfed", "whelp", "trawl", "outdo", "adobe", "crazy", "sower", "repay", "digit", "crate", "cluck", "spike", "mimic", "elder".....]
</code>```

There are many more, but not really relevant to list all for question

My problem is the filter... Take the Word "elder"... If I type "e", "l" , "d", then I will get the list filters by words starting with "e", then filtered by words starting "el" and then filtered but words staring "eld".But as soon as I type "elde", it filters the array to empty (which I understand is technically correct due to my filtering method currently) and then if I type "elder", I will get all words ending in "r".

So essentially I understand my problem is the indexOf(() part of things as it`s only matching the first instance of the letter in the word, but I want to filter on words where the letter === the index of that letter but I am not sure how to change things. So if I type    E R then right ow, I get only ending in R words, I want any words ending ER, including any that START with E also, or have another E in there...

Hopefully this makes some sense, am going round in circles with this.... Somebody suggested regex, but my first few attempts didn`t help, but possibly doing it wrong...

EDIT:
Sort of fixed it with:

```<code>correctList(id, e) {
    if (this.regex.test(e.key)) {
    this.correctLetters.push([e.key, id]);
    }

    this.correctLetters.forEach(
    (array) => {
        if (this.filteredWords.length > 1) {
        this.filteredList = this.filteredWords.filter(
            (word) => {
                const wordSplit = word.split('');
                return wordSplit[array[1]] === array[0];
            }
        );
    } else {
        this.filteredList = this.FiveLetterWords.filter(
            (word) => {
                const wordSplit = word.split('');
                return wordSplit[array[1]] === array[0];
            }
        );
    }
    console.log(this.filteredList);
    this.setFilteredWords(this.filteredList);
    }
    );
</code>```

But not sure if there is a more elegant method...

答:
To get the set of words that have the given letters in the given positions, just do this...</p>
```<code>filteredList = FiveLetterWords.filter(
    word => correctLetters.reduce(
        (prev, [letter, index]) => prev && (word[index] === letter),
        true
    )
);
</code>```

Title: Trying to match on multiple characters

Body:
Have tried a variety of things but nothing is quite working...

I have the following code:

        correctList(id, e) {
          if (this.regex.test(e.key)) {
            this.correctLetters.push([e.key, id]);
          }

          this.correctLetters.forEach(
            (array) => {
              if (this.filteredWords.length > 1) {
                this.filteredList = this.filteredWords.filter((word) => word.indexOf(array[0]) === array[1]);
            } else {
                this.filteredList = this.FiveLetterWords.filter((word) => word.indexOf(array[0]) === array[1]);
            }
            this.setFilteredWords(this.filteredList);
            }
          );
        },

Where 'this.correctLetters[]' is:

[[e,0], [l,1], [d,2]...]

This is built up using inputs and the order they are typed is the index number ( the 0, 1, 2 in the arrays)

and

'this.filteredWords' is:

["cigar", "rebut", "sissy", "humph", "awake", "blush",  "focal", "evade", "naval", "serve", "heath", "dwarf", "model", "karma", "stink", "grade", "quiet", "bench", "abate", "feign", "major", "death", "fresh", "crust", "stool", "colon", "abase", "marry", "react", "batty", "pride", "floss", "helix", "croak", "staff", "paper", "unfed", "whelp", "trawl", "outdo", "adobe", "crazy", "sower", "repay", "digit", "crate", "cluck", "spike", "mimic", "elder".....]

There are many more, but not really relevant to list all for question

My problem is the filter... Take the Word "elder"... If I type "e", "l" , "d", then I will get the list filters by words starting with "e", then filtered by words starting "el" and then filtered but words staring "eld".But as soon as I type "elde", it filters the array to empty (which I understand is technically correct due to my filtering method currently) and then if I type "elder", I will get all words ending in "r".

So essentially I understand my problem is the indexOf(() part of things as it`s only matching the first instance of the letter in the word, but I want to filter on words where the letter === the index of that letter but I am not sure how to change things. So if I type    E R then right ow, I get only ending in R words, I want any words ending ER, including any that START with E also, or have another E in there...

Hopefully this makes some sense, am going round in circles with this.... Somebody suggested regex, but my first few attempts didn`t help, but possibly doing it wrong...

EDIT:
Sort of fixed it with:

correctList(id, e) {
    if (this.regex.test(e.key)) {
    this.correctLetters.push([e.key, id]);
    }

    this.correctLetters.forEach(
    (array) => {
        if (this.filteredWords.length > 1) {
        this.filteredList = this.filteredWords.filter(
            (word) => {
                const wordSplit = word.split('');
                return wordSplit[array[1]] === array[0];
            }
        );
    } else {
        this.filteredList = this.FiveLetterWords.filter(
            (word) => {
                const wordSplit = word.split('');
                return wordSplit[array[1]] === array[0];
            }
        );
    }
    console.log(this.filteredList);
    this.setFilteredWords(this.filteredList);
    }
    );

But not sure if there is a more elegant method...

Body:
To get the set of words that have the given letters in the given positions, just do this...

filteredList = FiveLetterWords.filter(
    word => correctLetters.reduce(
        (prev, [letter, index]) => prev && (word[index] === letter),
        true
    )
);


问:
Azure Resource Group Deployment is failing
My release pipeline fails on task AzureResourceGroupDeployment@2 with error:

Error: Could not find any file matching the template file pattern

Here is the yaml code:

```<code>       steps:

      - download: build
        #artifact: function, arm

      - task: AzureResourceGroupDeployment@2
        displayName: 'Perform Resource Deployment'
        inputs:
          azureSubscription: $(qaSubscription)
          action: 'Create Or Update Resource Group'
          resourceGroupName: $(resourceGroup)
          location: $(location)
          templateLocation: 'Linked artifact'
          csmFile: '$(Pipeline.Workspace)/arm/azuredeploy.json'
          csmParametersFile: '$(Pipeline.Workspace)/arm/azuredeploy.parameters.json'
          deploymentMode: 'Incremental'
</code>```

I don't understand what may be wrong here...

答:
Figured it out. I needed to add "build/" to the path:</p>
```<code>csmFile: '$(Pipeline.Workspace)/build/arm/azuredeploy.json'
</code>```

Body:
My release pipeline fails on task AzureResourceGroupDeployment@2 with error:

Error: Could not find any file matching the template file pattern

Here is the yaml code:

       steps:

      - download: build
        #artifact: function, arm

      - task: AzureResourceGroupDeployment@2
        displayName: 'Perform Resource Deployment'
        inputs:
          azureSubscription: $(qaSubscription)
          action: 'Create Or Update Resource Group'
          resourceGroupName: $(resourceGroup)
          location: $(location)
          templateLocation: 'Linked artifact'
          csmFile: '$(Pipeline.Workspace)/arm/azuredeploy.json'
          csmParametersFile: '$(Pipeline.Workspace)/arm/azuredeploy.parameters.json'
          deploymentMode: 'Incremental'

I don't understand what may be wrong here...

Body:
Figured it out. I needed to add "build/" to the path:

csmFile: '$(Pipeline.Workspace)/build/arm/azuredeploy.json'


问:
Python: Permutations
I am working on a problem, where I want to get all permutations, but am not permitted to  modify the print statement. I am also not permitted to  use itertools or other packages.

Instuctions:

In order for the program to list out all possible routes it needs some work. Fix the program by adding an if statement that checks that the route includes all of the ports. In other words, check that each of the numbers 0, 1, 2, 3, 4 are included in the list route. Note that it isn't necessary to check that no port appears twice because if that were the case, then the route couldn't include all the five ports.

You do not need to change the print statement.

This is my code, but it doesn't work. How can this be fixed?

```<code>def main():
    portnames = ["PAN", "AMS", "CAS", "NYC", "HEL"]

    # don't change this bit - provided in exercise
    port1 = 0
    for port2 in range(1, 5):
        for port3 in range(1, 5):
            for port4 in range(1, 5):
                for port5 in range(1, 5):
                    route = [port1, port2, port3, port4, port5]

                    # instructions to add if statement that checks that the route includes all of the ports
                    # if "PAN" in route and "AMS" in route and "CAS" in route and "NYC" in route and "HEL" in route:
                    if all([val in route for val in portnames]):

                        # do not modify the print statement
                        print(' '.join([portnames[i] for i in route]))

                    else:
                        continue

main()
</code>```

答:
```<code>def main():
    portnames = ["PAN", "AMS", "CAS", "NYC", "HEL"]
    # https://sea-distances.org/
    # nautical miles converted to km
    D = [
            [0,8943,8019,3652,10545],
            [8943,0,2619,6317,2078],
            [8019,2619,0,5836,4939],
            [3652,6317,5836,0,7825],
            [10545,2078,4939,7825,0]
        ]
    # https://timeforchange.org/co2-emissions-shipping-goods
    # assume 20g per km per metric ton (of pineapples)
    co2 = 0.020
    route = []
    port1 = 0
    for port2 in range(1,5):
                for port3 in range(1,5):
                    for port4 in range(1,5):
                        for port5 in range(1,5):
                            result = [port1, port2, port3, port4, port5]
                            if 0 in result:
                                if 1 in result:
                                    if 2 in result:
                                        if 3 in result:
                                            if 4 in result:
                                                route.append(result)
    for singleRoute in route:
        distance = D[singleRoute[0]][singleRoute[1]] + D[singleRoute[1]][singleRoute[2]] + D[singleRoute[2]][singleRoute[3]] + D[singleRoute[3]][singleRoute[4]]
        emissions = distance * co2
        print(' '.join([portnames[i] for i in singleRoute]) + " %.1f kg" % emissions)
main()
</code>```

Title: Python: Permutations

Body:
I am working on a problem, where I want to get all permutations, but am not permitted to  modify the print statement. I am also not permitted to  use itertools or other packages.

Instuctions:

In order for the program to list out all possible routes it needs some work. Fix the program by adding an if statement that checks that the route includes all of the ports. In other words, check that each of the numbers 0, 1, 2, 3, 4 are included in the list route. Note that it isn't necessary to check that no port appears twice because if that were the case, then the route couldn't include all the five ports.

You do not need to change the print statement.

This is my code, but it doesn't work. How can this be fixed?

def main():
    portnames = ["PAN", "AMS", "CAS", "NYC", "HEL"]

    # don't change this bit - provided in exercise
    port1 = 0
    for port2 in range(1, 5):
        for port3 in range(1, 5):
            for port4 in range(1, 5):
                for port5 in range(1, 5):
                    route = [port1, port2, port3, port4, port5]

                    # instructions to add if statement that checks that the route includes all of the ports
                    # if "PAN" in route and "AMS" in route and "CAS" in route and "NYC" in route and "HEL" in route:
                    if all([val in route for val in portnames]):

                        # do not modify the print statement
                        print(' '.join([portnames[i] for i in route]))

                    else:
                        continue

main()


问:
read a file from runner in github actions using java
I have couple of files: asdf.json and qwer.json that are sitting in /runner of self-hosted vm after github actions is run

Now I want to read those files into my java code with something like File file = new File("asdf.json");

I always end up getting file not found exception while doing this. I tried with new File("runner/asdf.json") and is still the same

答:
If you file is located in your repository you have to use GITHUB_WORKSPACE variable to access it, like this:

${{ env.GITHUB_WORKSPACE }}/asdf.json

and pass it to your Java code.

Of course you have checkout your repository first:

- uses: actions/checkout@v2


问:
Swift mkmapview get zoom level, width or radius of visible map area from latitude longitude delta
I am in a confusion, on how to get a zoom level and radius of a visible area of the map (using mapkit mapview).

Here is what I am looking for (either of them or both, as needed) -

Zoom level, is to see at what level of the map is being shown to the users and with that information, I want to display the custom pins in the visible area. If zoom level is high, I need to show the actual logos of some commerce stores as pins. If zoom level is low, I need to show colored dots instead of logos.

As of now, I am using let updatedRadius = (mapView.camera.altitude)/1000 to get altitude of the camera, and if the updatedRadius value is > 25.0, I am showing colored dots. Below 25.0, I show the logos. I am doing this in regionDidChanged
Is this approach correct?

Radius, is to send it as a parameter to my REST API to fetch the list of places within that radius. When user zooms out on the map, visible area increases and so the REST API needs bigger radius to return the places covered in that area.

Ultimately, what should happen is, whenever user zooms out, then the radius changes. I need to send this changed radius to my REST to get an updated list.

What are latitude longtitude deltas, can we get radius/width of visible area using these values?

let latitudeDeltaVal = mapView.region.span.latitudeDelta
let longitudeDeltaVal = mapView.region.span.longitudeDelta

Can someone throw some light on what needs to be done please?

答:
To account for both landscape and portrait orientations, and/or situations where the map orientation is close to Northeast, Northwest, Southwest, Southeast, and to enclose the full screen up to the corners, one should consider both latitudeDelta and longitudeDelta:

```<code>func getRadius() -> Double{
    let centralLocation = CLLocation(latitude: mapView.region.center.latitude, longitude: mapView.region.center.longitude)
    let cornerOfMap = CLLocation(latitude: centralLocation.coordinate.latitude + mapView.region.span.latitudeDelta , longitude: centralLocation.coordinate.longitude + mapView.region.span.longitudeDelta)
    let radius = centralLocation.distance(from: cornerOfMap)
    return radius / 1000.0 // to convert radius to meters
}
</code>```

Body:
To account for both landscape and portrait orientations, and/or situations where the map orientation is close to Northeast, Northwest, Southwest, Southeast, and to enclose the full screen up to the corners, one should consider both latitudeDelta and longitudeDelta:

func getRadius() -> Double{
    let centralLocation = CLLocation(latitude: mapView.region.center.latitude, longitude: mapView.region.center.longitude)
    let cornerOfMap = CLLocation(latitude: centralLocation.coordinate.latitude + mapView.region.span.latitudeDelta , longitude: centralLocation.coordinate.longitude + mapView.region.span.longitudeDelta)
    let radius = centralLocation.distance(from: cornerOfMap)
    return radius / 1000.0 // to convert radius to meters
}


问:
Display one JSON object in XAML
I'm failing to display one json object in XAML in xamarin.forms, everywhere i search there are only list or collection methods to display json in xaml. What I recieve is only one json object, and these (listview and collection) methods fail to display this object.

I managed to recieve the object json content in C#, so the only problem is to pass it to XAML so it could be displayed.

I'm starting to think that Xamarin.forms cannot display one json object, only lists.

There is also list of these Json objects which I successfully pass as table, so i tried to point to specific object (using its ID) <CollectionView ItemsSource="{Binding List[4]}" but that causes that neither list or that one object is displayed then.

答:
Convert to string helped, thak you guys.
To be specific i used this Show JSON response through binding (Xamarin forms)</p>

Title: Display one JSON object in XAML


问:
jQuery review DOM and react
I have a bunch of DIVs which are the feed in a portfolio which has a filtering system which shows and hides the DIVs - this works well - I am adapting this system to look at the DIVs that match the filter clicked on and then style them with a new class with jQuery. CSS nth-of-type does not work, as it recognizes the hidden divs and thus messes up my custom layout, so I need a reliable way of checking the list of DIVs and applying the new class ONLY to those which do not have the inline style "transform: scale(0.001)" applied to them - this inline style is applied by the filtering system which I don't want to mess around with - so am looking for a way of adding a new class to the DIVS which don't have "transform: scale(0.001)" applied each time the filter buttons are clicked.

The classes I want to add are "itemPOS1" to the first div without the transform applied, then "itemPOS2" to the 2nd, etc etc... so the list of DIVS below would look like this on initial load:

```<code><div>Project 1</div>
<div>Project 2</div>
<div>Project 3</div>
<div>Project 4</div>
<div>Project 5</div>
</code>```

Then after clicking on a filter the list could look like this:

```<code><div>Project 1</div>
<div style="transform: scale(0.001)">Project 2</div>
<div style="transform: scale(0.001)">Project 3</div>
<div>Project 4</div>
<div style="transform: scale(0.001)">Project 5</div>
</code>```

In which case - the list would then look like this once I have added the new classes to those DIVS which are suitable:

```<code><div class="itemPOS1">Project 1</div>
<div style="transform: scale(0.001)">Project 2</div>
<div style="transform: scale(0.001)">Project 3</div>
<div class="itemPOS2">Project 4</div>
<div style="transform: scale(0.001)">Project 5</div>
</code>```

So, in the front end - the user would just see "Project 1" and "Project 4"....

I cant seem to get this to work well - I was using:

```<code>$('div:visible:eq(0)').addClass('itemPOS1');
$('div:visible:eq(1)').addClass('itemPOS2');
$('div:visible:eq(2)').addClass('itemPOS3');
$('div:visible:eq(3)').addClass('itemPOS4');
</code>```

but its not reliable as sometimes it applies classes to DIVs which have the transform: scale(0.001) applied and thus makes the rendering of the projects wrong as the class names get added incorrectly. I was hoping to find a way to only apply the adding class logic to those divs which did not have "transform: scale(0.001)" applied to them...

I also want to add itemPOS1, 2, 3, 4 and 5 to each 5 DIVs that dont have the inline transform applied - so for example - the 6th DIV that should have the class applied should get itemPOS1 not itemPOS6

Any thoughts?

In essence looking for:

if div does not have transform: scale(0.001) then add class itemPOSX

X starting at 1 for 1st div, then 2 for 2nd... up to 5th, then 6th div has itemPOS1, div 7 has itemPO2 etc...

$('div:visible:eq(0)').addClass('itemPOS1');
$('div:visible:eq(1)').addClass('itemPOS2');
$('div:visible:eq(2)').addClass('itemPOS3');
$('div:visible:eq(3)').addClass('itemPOS4');```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h2>basic set</h2>
<div>Project 1</div>
<div>Project 2</div>
<div>Project 3</div>
<div>Project 4</div>
<div>Project 5</div>
<h2>test set filtered:</h2>
<div>Project 1</div>
<div style="transform: scale(0.001)">Project 2</div>
<div style="transform: scale(0.001)">Project 3</div>
<div>Project 4</div>
<div style="transform: scale(0.001)">Project 5</div></code>```

答:
You can do something like this (check the console):

Explanation :

we set a counter variable starting at 1

we iterate every div

we check for div's NOT having the specified style,when found we apply the required class using the counter value and increment the counter by 1.

when counter reaches our upper limit (5),we set it back to 1.

const allDivs = document.querySelectorAll("div")
let counter=1;
allDivs.forEach(div=>{
  if (div.style.transform !== "scale(0.001)" ) {
  if(counter<6){
  $(div).addClass('itemPOS' + counter);
  counter++
  }else{
  counter=1;
  $(div).addClass('itemPOS' + counter);
  counter++
  }

  }
  console.log( "class is : " + div.classList[0] + " and style(transform) is : " + div.style.transform )

})```
<pre class="snippet-code-html lang-html prettyprint-override"><code><!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"
    integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
</head>

<body>
<div>Project 1</div>
<div style="transform: scale(0.001)">Project 2</div>
<div style="transform: scale(0.001)">Project 3</div>
<div>Project 4</div>
<div style="transform: scale(0.001)">Project 5</div>
<div>Project 6</div>
<div>Project 7</div>
<div>Project 8</div>
<div>Project 9</div>
<div>Project 10</div>
</body>

</html></code>```

Title: jQuery review DOM and react

Body:
I have a bunch of DIVs which are the feed in a portfolio which has a filtering system which shows and hides the DIVs - this works well - I am adapting this system to look at the DIVs that match the filter clicked on and then style them with a new class with jQuery. CSS nth-of-type does not work, as it recognizes the hidden divs and thus messes up my custom layout, so I need a reliable way of checking the list of DIVs and applying the new class ONLY to those which do not have the inline style "transform: scale(0.001)" applied to them - this inline style is applied by the filtering system which I don't want to mess around with - so am looking for a way of adding a new class to the DIVS which don't have "transform: scale(0.001)" applied each time the filter buttons are clicked.

The classes I want to add are "itemPOS1" to the first div without the transform applied, then "itemPOS2" to the 2nd, etc etc... so the list of DIVS below would look like this on initial load:

Project 1

Project 2

Project 3

Project 4

Project 5

Then after clicking on a filter the list could look like this:

Project 1

Project 2

Project 3

Project 4

Project 5

In which case - the list would then look like this once I have added the new classes to those DIVS which are suitable:

Project 1

Project 2

Project 3

Project 4

Project 5

So, in the front end - the user would just see "Project 1" and "Project 4"....

I cant seem to get this to work well - I was using:

$('div:visible:eq(0)').addClass('itemPOS1');
$('div:visible:eq(1)').addClass('itemPOS2');
$('div:visible:eq(2)').addClass('itemPOS3');
$('div:visible:eq(3)').addClass('itemPOS4');

but its not reliable as sometimes it applies classes to DIVs which have the transform: scale(0.001) applied and thus makes the rendering of the projects wrong as the class names get added incorrectly. I was hoping to find a way to only apply the adding class logic to those divs which did not have "transform: scale(0.001)" applied to them...

I also want to add itemPOS1, 2, 3, 4 and 5 to each 5 DIVs that dont have the inline transform applied - so for example - the 6th DIV that should have the class applied should get itemPOS1 not itemPOS6

Any thoughts?

In essence looking for:

if div does not have transform: scale(0.001) then add class itemPOSX

X starting at 1 for 1st div, then 2 for 2nd... up to 5th, then 6th div has itemPOS1, div 7 has itemPO2 etc...

$('div:visible:eq(0)').addClass('itemPOS1');
$('div:visible:eq(1)').addClass('itemPOS2');
$('div:visible:eq(2)').addClass('itemPOS3');
$('div:visible:eq(3)').addClass('itemPOS4');

basic set

Project 1

Project 2

Project 3

Project 4

Project 5

test set filtered:

Project 1

Project 2

Project 3

Project 4

Project 5

Body:
You can do something like this (check the console):

Explanation :

we set a counter variable starting at 1

we iterate every div

we check for div's NOT having the specified style,when found we apply the required class using the counter value and increment the counter by 1.

when counter reaches our upper limit (5),we set it back to 1.

const allDivs = document.querySelectorAll("div")
let counter=1;
allDivs.forEach(div=>{
  if (div.style.transform !== "scale(0.001)" ) {
  if(counter<6){
  $(div).addClass('itemPOS' + counter);
  counter++
  }else{
  counter=1;
  $(div).addClass('itemPOS' + counter);
  counter++
  }

  }
  console.log( "class is : " + div.classList[0] + " and style(transform) is : " + div.style.transform )

})

<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"
    integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
</head>

<body>
<div>Project 1</div>
<div style="transform: scale(0.001)">Project 2</div>
<div style="transform: scale(0.001)">Project 3</div>
<div>Project 4</div>
<div style="transform: scale(0.001)">Project 5</div>
<div>Project 6</div>
<div>Project 7</div>
<div>Project 8</div>
<div>Project 9</div>
<div>Project 10</div>
</body>

</html>


答:
We start with the empty list.

After processing the first element, we have [] + ['x'] == ['x'].

After processing the second element, we have ['x'] + ['y'] == ['x', 'y'].

After processing the third element, we have ['x', 'y'] + ['z'] == ['x', 'y', 'z'], as observed.

Title: sum() to remove bracket in a double list


问:
Persist custom url parameters with algolia search url rewriting
We are using vue instantsearch from Algolia.

When the user lands on page with some initial url parameters, algolia instantsearch loads an initial search, and changes the url to include the search parameters. However the initial url parameters do not persist when algolia rewrites the url, and we'd like them to stay. ie.e

land on /stuff?myparam=value

algolia sets up intial search results and changes url to /stuff?refinementList=... and the url param myparam is removed. Is there a way to keep it in the url?

答:
Incredible that there is no simple example to this problem on the whole internet
Here is my shot at it (vanilla JS)

const algoliaAppId = 'APP_ID';
const algoliaApiKey = 'API_KEY';
const algoliaIndex = 'instant_search';

const search = instantsearch({
  indexName: algoliaIndex,
  algoliasearch(algoliaAppId, algoliaApiKey),
  routing: {
    router: instantsearch.routers.history({

      createURL({ qsModule, location, routeState }) {
        // current search params
        const indexState = routeState[algoliaIndex] || {};
        const { origin, pathname, hash, search } = location;
        // grab current query string and convert to object
        const queryParameters = qsModule.parse(search.slice(1)) || {};

        // if there is an active search
        if (Object.keys(indexState).length ){
          // merge the search params with the current query params
          Object.assign(queryParameters, routeState);
        }else{
          // remove the search params
          delete queryParameters[algoliaIndex];
        }

        let queryString = qsModule.stringify(queryParameters);

        if(queryString.length){
          queryString = `?${queryString}`;
        }

        return `${origin}${pathname}${queryString}${hash}`;
      },

    })
  }

});

search.start();
```


问:
how to list col1 with the multiple values in col2
I need to to know

are there multiple Product-ID for the same barcode number

are there multiple barcodes number for the same Product-ID

example of the dataset:

```<code>data = {'Proudct':['SLL', 'MNO', 'Drin', 'JAJ'],
        'Product-ID':[20, 20, 19, 18]
         'barcode':['3633', '7676', '2313','3311'}
 df = pd.DataFrame(data) ```

I need the output to be like:

Name   ID   Code
SLL    20    3633
MNO    20    7676
```

答:
Simply use the duplicated method that is specifically made for this:

```<code>df[df[['Name','ID']].duplicated(keep=False)]
</code>```

Output:

```<code>  Name  ID  Code
0  Tom  20  3633
1  Tom  20  7676
</code>```

Body:
I need to to know

are there multiple Product-ID for the same barcode number

are there multiple barcodes number for the same Product-ID

example of the dataset:

data = {'Proudct':['SLL', 'MNO', 'Drin', 'JAJ'],
        'Product-ID':[20, 20, 19, 18]
         'barcode':['3633', '7676', '2313','3311'}
 df = pd.DataFrame(data) ```

I need the output to be like:

Name   ID   Code
SLL    20    3633
MNO    20    7676

Body:
Simply use the duplicated method that is specifically made for this:

df[df[['Name','ID']].duplicated(keep=False)]

Output:

  Name  ID  Code
0  Tom  20  3633
1  Tom  20  7676


答:
In your instance :visible won't work as technically it is still not hidden, just really small. use not() instead.

Update from your comment I'm assuming you want to reset the count after 5. For that we can use the modulo (or remainder) operator to get the remainder of a division.

let maxPos = 5;

//Select all divs that don't contain your transform style and itterate
//The selector would also work with querySelectorAll natively
$("div:not([style*='transform: scale(0.001)'])").each(function(idx){
  //If maxPos > 0 use the modulo operator to get our position index
  //otherwise don't reset
  let classIdx =  maxPos > 0 ? idx % maxPos + 1 : idx;
  //Add the class dynamically based off the index
  $(this).addClass("POS"+classIdx)
  //Or if you want to one line it:
  //$(this).addClass("POS"+(maxPos > 0 ? idx % maxPos + 1 : idx));
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>/*Just to display the added class name*/
[class^=POS]::after {
  content: 'Class: ' attr(class);
  font-size:0.75em;
  display:inline-block;
  padding-left: 3em;
}</code>```

Project 1

Project 2

Project 3

Project 4

Project 5

Project 6

Project 7

Project 8

Project 9

Project 10
```

For more info see Attribute Selectors and the not() pseudo class

Title: jQuery review DOM and react

Body:
In your instance :visible won't work as technically it is still not hidden, just really small. use not() instead.

Update from your comment I'm assuming you want to reset the count after 5. For that we can use the modulo (or remainder) operator to get the remainder of a division.

let maxPos = 5;

//Select all divs that don't contain your transform style and itterate
//The selector would also work with querySelectorAll natively
$("div:not([style*='transform: scale(0.001)'])").each(function(idx){
  //If maxPos > 0 use the modulo operator to get our position index
  //otherwise don't reset
  let classIdx =  maxPos > 0 ? idx % maxPos + 1 : idx;
  //Add the class dynamically based off the index
  $(this).addClass("POS"+classIdx)
  //Or if you want to one line it:
  //$(this).addClass("POS"+(maxPos > 0 ? idx % maxPos + 1 : idx));
});

/*Just to display the added class name*/
[class^=POS]::after {
  content: 'Class: ' attr(class);
  font-size:0.75em;
  display:inline-block;
  padding-left: 3em;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>Project 1</div>
<div style="transform: scale(0.001)">Project 2</div>
<div style="transform: scale(0.001)">Project 3</div>
<div>Project 4</div>
<div style="transform: scale(0.001)">Project 5</div>
<div>Project 6</div>
<div>Project 7</div>
<div>Project 8</div>
<div>Project 9</div>
<div>Project 10</div>

For more info see Attribute Selectors and the not() pseudo class


问:
Golang bufio from websocket breaking after first read
I am trying to stream JSON text from a websocket. However after an initial read I noticed that the stream seems to break/disconnect. This is from a Pleroma server (think: Mastodon). I am using the default Golang websocket library.

```<code>package main

import (
    "bufio"
    "fmt"
    "log"

    "golang.org/x/net/websocket"
)

func main() {
    origin := "https://poa.st/"
    url := "wss://poa.st/api/v1/streaming/?stream=public"

    ws, err := websocket.Dial(url, "", origin)
    if err != nil {
        log.Fatal(err)
    }

    s := bufio.NewScanner(ws)
    for s.Scan() {
        line := s.Text()
        fmt.Println(line)
    }
}
</code>```

After the initial JSON text response, the for-loop breaks. I would expect it to send a new message every few seconds.

What might be causing this? I am willing to switch to the Gorilla websocket library if I can use it with bufio.

Thanks!

答:
Although x/net/websocket connection has a Read method with the same signature as the Read method in io.Reader, the connection does not work like an io.Reader.  The connection will not work as you expect when wrapped with a bufio.Scanner.

The poa.st endpoint sends a stream of messages where each message is a JSON document.  Use the following code to read the messages using the Gorilla package:

```<code>url := "wss://poa.st/api/v1/streaming/?stream=public"
ws, _, err := websocket.DefaultDialer.Dial(url, nil)
if err != nil {
    log.Fatal(err)
}
defer ws.Close()

for {
    _, p, err := ws.ReadMessage()
    if err != nil {
        log.Fatal(err)
    }
    // p is a []byte containing the JSON document.
    fmt.Printf("%s\n", p)
}
</code>```

The Gorilla package has a helper method for decoding JSON messages.  Here's an example of how to use that method.

```<code>url := "wss://poa.st/api/v1/streaming/?stream=public"
ws, _, err := websocket.DefaultDialer.Dial(url, nil)
if err != nil {
    log.Fatal(err)
}
defer ws.Close()

for {
    // The JSON documents are objects containing two fields,
    // the event type and the payload. The payload is a JSON
    // document itself.
    var e struct {
        Event   string
        Payload string
    }

    err := ws.ReadJSON(&e)
    if err != nil {
        log.Fatal(err)
    }
    // TODO: decode e.Payload based on e.Event
}
</code>```

Body:
I am trying to stream JSON text from a websocket. However after an initial read I noticed that the stream seems to break/disconnect. This is from a Pleroma server (think: Mastodon). I am using the default Golang websocket library.

package main

import (
    "bufio"
    "fmt"
    "log"

    "golang.org/x/net/websocket"
)

func main() {
    origin := "https://poa.st/"
    url := "wss://poa.st/api/v1/streaming/?stream=public"

    ws, err := websocket.Dial(url, "", origin)
    if err != nil {
        log.Fatal(err)
    }

    s := bufio.NewScanner(ws)
    for s.Scan() {
        line := s.Text()
        fmt.Println(line)
    }
}

After the initial JSON text response, the for-loop breaks. I would expect it to send a new message every few seconds.

What might be causing this? I am willing to switch to the Gorilla websocket library if I can use it with bufio.

Thanks!

Body:
Although x/net/websocket connection has a Read method with the same signature as the Read method in io.Reader, the connection does not work like an io.Reader.  The connection will not work as you expect when wrapped with a bufio.Scanner.

The poa.st endpoint sends a stream of messages where each message is a JSON document.  Use the following code to read the messages using the Gorilla package:

url := "wss://poa.st/api/v1/streaming/?stream=public"
ws, _, err := websocket.DefaultDialer.Dial(url, nil)
if err != nil {
    log.Fatal(err)
}
defer ws.Close()

for {
    _, p, err := ws.ReadMessage()
    if err != nil {
        log.Fatal(err)
    }
    // p is a []byte containing the JSON document.
    fmt.Printf("%s\n", p)
}

The Gorilla package has a helper method for decoding JSON messages.  Here's an example of how to use that method.

url := "wss://poa.st/api/v1/streaming/?stream=public"
ws, _, err := websocket.DefaultDialer.Dial(url, nil)
if err != nil {
    log.Fatal(err)
}
defer ws.Close()

for {
    // The JSON documents are objects containing two fields,
    // the event type and the payload. The payload is a JSON
    // document itself.
    var e struct {
        Event   string
        Payload string
    }

    err := ws.ReadJSON(&e)
    if err != nil {
        log.Fatal(err)
    }
    // TODO: decode e.Payload based on e.Event
}