问:
Counting Total Number of Elements in a List using Recursion
The Problem:

Count the number of elements in a List using recursion.

I wrote the following function:

def count_rec(arr, i):
    """
        This function takes List (arr) and Index Number
        then returns the count of number of elements in it
        using Recursion.
    """
    try:
        temp = arr[i]  # if element exists at i, continue
        return 1 + count_rec(arr, i+1)
    except IndexError:
        # if index error, that means, i == length of list
        return 0
```

I noticed some problems with it:

RecursionError (when the number of elements is more than 990)

Using a temp element (wasting memory..?)

Exception Handling (I feel like we shouldn't use it unless necessary)

If anyone can suggest how to improve the above solution or come up with an alternative one, It would be really helpful.

答:
What you have is probably as efficient as you are going to get for this thought experiment (obviously, python already calculates and stores length for LIST objects, which can be retrieved with the len() built-in, so this function is completely unnecessary).

You could get shorter code if you want:

```<code>def count(L):
    return count(L[:-1])+1 if L else 0
</code>```

But you still need to change python's recursion limit.

```<code>import sys; sys.setrecursionlimit(100000)
</code>```

However, we should note that in most cases, "if else" statements take longer to process than "try except". Hence, "try except" is going to be a better (if you are after performance). Of course, that's weird talking about performance because recursion typically doesn't perform very well, due to how python manage's namespaces and such. Recursion is typically frowned upon, unnecessary, and slow. So, trying to optimize recursion performance is a littler strange.

A last point to note. You mention the temp=arr[i] taking up memory. Yes, possibly a few bytes. Of course, any calculation you do to determine if arr has an element at i, is going to take a few bytes in memory even simply running "arr[i]" without assignment. In addition, those bytes are freed the second the temp variable falls out of scope, gets re-used, or the function exits. Hence, unless you are planning on launching 10,000,000,000 sub-processes, rest assure there is no performance degradation in using a temp variable like that.

Body:
The Problem:

Count the number of elements in a List using recursion.

I wrote the following function:

def count_rec(arr, i):
    """
        This function takes List (arr) and Index Number
        then returns the count of number of elements in it
        using Recursion.
    """
    try:
        temp = arr[i]  # if element exists at i, continue
        return 1 + count_rec(arr, i+1)
    except IndexError:
        # if index error, that means, i == length of list
        return 0

I noticed some problems with it:

RecursionError (when the number of elements is more than 990)

Using a temp element (wasting memory..?)

Exception Handling (I feel like we shouldn't use it unless necessary)

If anyone can suggest how to improve the above solution or come up with an alternative one, It would be really helpful.

Body:
What you have is probably as efficient as you are going to get for this thought experiment (obviously, python already calculates and stores length for LIST objects, which can be retrieved with the len() built-in, so this function is completely unnecessary).

You could get shorter code if you want:

def count(L):
    return count(L[:-1])+1 if L else 0

But you still need to change python's recursion limit.

import sys; sys.setrecursionlimit(100000)

However, we should note that in most cases, "if else" statements take longer to process than "try except". Hence, "try except" is going to be a better (if you are after performance). Of course, that's weird talking about performance because recursion typically doesn't perform very well, due to how python manage's namespaces and such. Recursion is typically frowned upon, unnecessary, and slow. So, trying to optimize recursion performance is a littler strange.

A last point to note. You mention the temp=arr[i] taking up memory. Yes, possibly a few bytes. Of course, any calculation you do to determine if arr has an element at i, is going to take a few bytes in memory even simply running "arr[i]" without assignment. In addition, those bytes are freed the second the temp variable falls out of scope, gets re-used, or the function exits. Hence, unless you are planning on launching 10,000,000,000 sub-processes, rest assure there is no performance degradation in using a temp variable like that.


来源: stackexchange

问:
Unable to download excel file from src/assets in development/qa/prod environment for angular application
I am working with angular-7 application. I have sample excel file in src/assets. I have implemented a download attachment method to download sample excel file. I am able to download it but I am getting an error when I open downloaded sample excel file. The error description is: Excel cannot open the file 'sample.xlsx' because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file.

component.component.html

```<code><button mat-raised-button (click)="downloadexcelfile()">
<button mat-raised-button (click)="download()">

</code>```

component.component.ts

```<code>downloadexcelfile() {

if(navigator.msSaveBlob) {
// to support in IE 10+
let data: any;
this.HttpClient.get("./assets/sample.xlsx",{responseType: "blob"}).subscribe((res:any) => {
data = res;

// approach - 1
let csvData = new Blob([data], { type: 'text/csv;charset=utf-8;'});

// approach - 2
let csvData = new Blob([data], { type: 'application/vnd.ms-excel'});

// approach - 3
let csvData = new Blob([data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});

navigator.msSaveBlob(csvData, "sample.xlsx");
})

}

else if(!navigator.msSaveBlob) {
let link = document.createElement("a");
link.href = "assets/sample.xlsx";
link.download = "sample.xlsx";
link.click();
window.URL.revokeObjectURL(link.href);
link.remove();
}

}

// approach - 4
download() {

if(navigator.msSaveBlob) {
// to support in IE 10+
let data: any;
this.HttpClient.get("./assets/sample.xlsx",{responseType: "arraybuffer"}).subscribe((res:any) => {
data = res;

// approach - 5
let csvData = new Blob([data], { type: 'text/csv'});

// approach - 6
let csvData = new Blob([data], { type: 'application/vnd.ms-excel'});

// approach - 7
let csvData = new Blob([data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});

navigator.msSaveBlob(csvData, "sample.xlsx");
})

}

else if(!navigator.msSaveBlob) {
let link = document.createElement("a");
link.href = "assets/sample.xlsx";
link.download = "sample.xlsx";
link.click();
window.URL.revokeObjectURL(link.href);
link.remove();
}

}
</code>```

I have tried with multiple approaches and spent like 5 days to resolve this. still, I am trying to figure out. Could anyone please help me with this. Thanks in advance.

答:
```<code>    this.HttpClient.get("./assets/sample.xlsx",{responseType: "blob"}).subscribe((res:any) => {
          const url= window.URL.createObjectURL(res);
          window.open(url);
    });
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I am working with angular-7 application. I have sample excel file in src/assets. I have implemented a download attachment method to download sample excel file. I am able to download it but I am getting an error when I open downloaded sample excel file. The error description is: Excel cannot open the file 'sample.xlsx' because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file.

component.component.html

<button mat-raised-button (click)="downloadexcelfile()">
<button mat-raised-button (click)="download()">

component.component.ts

downloadexcelfile() {

if(navigator.msSaveBlob) {
// to support in IE 10+
let data: any;
this.HttpClient.get("./assets/sample.xlsx",{responseType: "blob"}).subscribe((res:any) => {
data = res;

// approach - 1
let csvData = new Blob([data], { type: 'text/csv;charset=utf-8;'});

// approach - 2
let csvData = new Blob([data], { type: 'application/vnd.ms-excel'});

// approach - 3
let csvData = new Blob([data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});

navigator.msSaveBlob(csvData, "sample.xlsx");
})

}

else if(!navigator.msSaveBlob) {
let link = document.createElement("a");
link.href = "assets/sample.xlsx";
link.download = "sample.xlsx";
link.click();
window.URL.revokeObjectURL(link.href);
link.remove();
}

}

// approach - 4
download() {

if(navigator.msSaveBlob) {
// to support in IE 10+
let data: any;
this.HttpClient.get("./assets/sample.xlsx",{responseType: "arraybuffer"}).subscribe((res:any) => {
data = res;

// approach - 5
let csvData = new Blob([data], { type: 'text/csv'});

// approach - 6
let csvData = new Blob([data], { type: 'application/vnd.ms-excel'});

// approach - 7
let csvData = new Blob([data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});

navigator.msSaveBlob(csvData, "sample.xlsx");
})

}

else if(!navigator.msSaveBlob) {
let link = document.createElement("a");
link.href = "assets/sample.xlsx";
link.download = "sample.xlsx";
link.click();
window.URL.revokeObjectURL(link.href);
link.remove();
}

}

I have tried with multiple approaches and spent like 5 days to resolve this. still, I am trying to figure out. Could anyone please help me with this. Thanks in advance.


问:
How much static HTML should I serve with React?
How much static HTML should I serve with React as opposed to just leaving it in the HTML file?

(I am just getting started with React.)

I have a single page application, which, greatly simplified, looks like this:

```<code><body>

  <div id="container">

    <div id="header">
      <div id="header_dynamic_content">
      </div>
    </div>

    <div id="dynamic_content">
    </div>

    <div id="footer">
    </div>

  </div>
</body>
</code>```

Is it best/common practice to use React to only handle the dynamic content and to leave everything that is static in the HTML file? Or should I use React Components to serve everything?

So this?

```<code>class DynamicOne extends React.Component {
  render() {
    return (
      /* My Content */
    );
  }
}

class DynamicTwo extends React.Component {
  render() {
    return (
      /* My Content */
    );
  }
}

ReactDOM.render(<DynamicOne />, document.getElementById('header_dynamic_content'));
ReactDOM.render(<DynamicTwo />, document.getElementById('dynamic_content'));
</code>```

or this?

```<code>class DynamicOne extends React.Component {
  render() {
    return (
      /* My Content */
    );
  }
}

class DynamicTwo extends React.Component {
  render() {
    return (
      /* My Content */
    );
  }
}

class App extends React.Component {
  render() {
    return (
      <div>
        <div id="header">
          <div id="header_dynamic_content">
            <DynamicOne />
          </div>
        </div>

        <div id="dynamic_content">
          <DynamicTwo />
        </div>

        <div id="footer">
        </div>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('container'));

</code>```

答:
According to React Documentation:

Applications built with just React usually have a single root DOM node. If you are integrating React into an existing app, you may have as many isolated root DOM nodes as you like.

Ref

Happy coding :)

Body:
How much static HTML should I serve with React as opposed to just leaving it in the HTML file?

(I am just getting started with React.)

I have a single page application, which, greatly simplified, looks like this:

Is it best/common practice to use React to only handle the dynamic content and to leave everything that is static in the HTML file? Or should I use React Components to serve everything?

So this?

class DynamicOne extends React.Component {
  render() {
    return (
      /* My Content */
    );
  }
}

class DynamicTwo extends React.Component {
  render() {
    return (
      /* My Content */
    );
  }
}

ReactDOM.render(<DynamicOne />, document.getElementById('header_dynamic_content'));
ReactDOM.render(<DynamicTwo />, document.getElementById('dynamic_content'));

or this?

class DynamicOne extends React.Component {
  render() {
    return (
      /* My Content */
    );
  }
}

class DynamicTwo extends React.Component {
  render() {
    return (
      /* My Content */
    );
  }
}

class App extends React.Component {
  render() {
    return (

            <DynamicOne />

          <DynamicTwo />

    );
  }
}

ReactDOM.render(<App />, document.getElementById('container'));


问:
Is there a way to get a difference report on two Jet (.mdb) databases?
I have code that depends a relatively small MS Jet (created in Access) database. Our source control process is far from all that it could/should be (which is a problem that needs to be solved immediately) and we have ended up with two versions of the same database. The person who edited the "other" version is no longer around to give me hints about what he changed. What is the best way to find the differences of the actual data contained in two versions of a database?</p>

答:
Output all the forms and modules to text files and use a text compare utility.

For example:

```<code>Sub ToText()
Dim frm, mdl

For Each frm In CurrentProject.AllForms
    Application.SaveAsText acForm, frm.Name, "c:\docs\" _
        & frm.Name & ".txt"
</code>```

'SO formatting

```<code>Next

For Each mdl In CurrentProject.AllModules
    Application.SaveAsText acModule, mdl.Name, "c:\docs\" _
        & mdl.Name & ".txt"
</code>```

'SO formatting

```<code>Next
End Sub
</code>```

ContentLicense: CC BY-SA 2.5

Body:
Output all the forms and modules to text files and use a text compare utility.

For example:

Sub ToText()
Dim frm, mdl

For Each frm In CurrentProject.AllForms
    Application.SaveAsText acForm, frm.Name, "c:\docs\" _
        & frm.Name & ".txt"

'SO formatting

Next

For Each mdl In CurrentProject.AllModules
    Application.SaveAsText acModule, mdl.Name, "c:\docs\" _
        & mdl.Name & ".txt"

'SO formatting

Next
End Sub

OwnerDisplayName: Remou


问:
Plotting multiple values to one key in python
I am trying to make a scatter plot with this dictionary

```<code>d = {1: [1, 2, 3, 4, 5], 3: [3, 6, 9, 12, 15], 5: [5, 10, 15, 20, 25]}
</code>```

I want the keys to be in X-axis and the values to be on Y-axis, and also to show a legend with different key values. I have tried this code-

```<code>import matplotlib.pyplot as plt

d = {1: [1, 2, 3, 4, 5], 3: [3, 6, 9, 12, 15], 5: [5, 10, 15, 20, 25]}
colors = list("rgbk")
x, y =[], []
for i in d.keys():
   for j in d[i]:
       x.append(i)
       y.append(j)
   plt.scatter(x, y, color = colors.pop())
   plt.legend(d.keys())
plt.show()
</code>```

But this is giving me a plot with points with only one colour but the legends are alright.

答:
It's better to use plt.subplots() in this case, so you can reuse the same axis. The colour iteration comes for free but I left it in, not sure if you prefer rgbk.

When possible, avoid for-loops in Python for better readability and performance.

import matplotlib.pyplot as plt

d = {1: [1, 2, 3, 4, 5], 3: [3, 6, 9, 12, 15], 5: [5, 10, 15, 20, 25]}
colors = list("rgbk")

fig, ax = plt.subplots()

for x, ys in d.items():
    ax.scatter([x] * len(ys), ys, color = colors.pop(), label=x)

plt.legend()
plt.show()
```

<p><img src="https://i.stack.imgur.com/UCJG6.png" alt="plot"></p>

<p>If you are dealing with large arrays, consider using <code>numpy</code>. In this case you can rescale the <code>key</code> for example like this:</p>

<pre class="lang-py prettyprint-override"><code>import matplotlib.pyplot as plt
import numpy as np

d = {1: [1, 2, 3, 4, 5], 3: [3, 6, 9, 12, 15], 5: [5, 10, 15, 20, 25]}
colors = list("rgbk")

fig, ax = plt.subplots()

for x, ys in d.items():
    ax.scatter(np.full_like(ys, x), ys, color = colors.pop(), label=x)

plt.legend()
plt.show()
</code>```

Body:
I am trying to make a scatter plot with this dictionary

d = {1: [1, 2, 3, 4, 5], 3: [3, 6, 9, 12, 15], 5: [5, 10, 15, 20, 25]}

I want the keys to be in X-axis and the values to be on Y-axis, and also to show a legend with different key values. I have tried this code-

import matplotlib.pyplot as plt

d = {1: [1, 2, 3, 4, 5], 3: [3, 6, 9, 12, 15], 5: [5, 10, 15, 20, 25]}
colors = list("rgbk")
x, y =[], []
for i in d.keys():
   for j in d[i]:
       x.append(i)
       y.append(j)
   plt.scatter(x, y, color = colors.pop())
   plt.legend(d.keys())
plt.show()

But this is giving me a plot with points with only one colour but the legends are alright.

Body:
It's better to use plt.subplots() in this case, so you can reuse the same axis. The colour iteration comes for free but I left it in, not sure if you prefer rgbk.

When possible, avoid for-loops in Python for better readability and performance.

import matplotlib.pyplot as plt

d = {1: [1, 2, 3, 4, 5], 3: [3, 6, 9, 12, 15], 5: [5, 10, 15, 20, 25]}
colors = list("rgbk")

fig, ax = plt.subplots()

for x, ys in d.items():
    ax.scatter([x] * len(ys), ys, color = colors.pop(), label=x)

plt.legend()
plt.show()

If you are dealing with large arrays, consider using numpy. In this case you can rescale the key for example like this:

import matplotlib.pyplot as plt
import numpy as np

d = {1: [1, 2, 3, 4, 5], 3: [3, 6, 9, 12, 15], 5: [5, 10, 15, 20, 25]}
colors = list("rgbk")

fig, ax = plt.subplots()

for x, ys in d.items():
    ax.scatter(np.full_like(ys, x), ys, color = colors.pop(), label=x)

plt.legend()
plt.show()


问:
Azure Application Insights Query customDimensions
I have a Java application that sends log4j2 logs to App Insights. When logging an exception I basically pass a JSON in string format and the exception something like this

```<code>JSONObject json=new JSONObject();
json.put(...)
....
log.error(json.toString(), exception)
</code>```

On the App Insights side; the message is stored under customDimensions with the key Logger Message in a JSON format.

From this stored information, I would like to make a query that would fetch all the exception messages where the statusCode > 200 and statusCode < 300. I've tried couple of queries but I was not able to extract those specific exception messages.

One of the queries I was trying was

```<code>exceptions
| limit 50
| where toint(customDimensions["Logger Message"].statusCode) > 200
  and toint(customDimensions["Logger Message"].statusCode) < 300
</code>```

Any help would be appreciated

Update: I've running the query

```<code>exceptions
| limit 50
| project s1 = customDimensions["Logger Message"]
| extend  s2 = s1.statusCode
| extend  s3 = toint(s2)
| extend  s4 = s3 >= 200 and s3 < 300
</code>```

答:
from a query language perspective, you're doing the right thing (assuming you actually want > 200 and not >= 200, so that the query in your example will actually return the record you've pasted a snapshot of)

```<code>print customDimensions = dynamic({
    "Logger Message":{
        "message":"Test 1 and Test 2",
        "statusCode": 200
    }
})
| project toint(customDimensions['Logger Message'].statusCode)
</code>```

This returns a single table, with a single row, with a single column, with the value 200.

It's hard to fully understand how the actual data in your case looks like based on the snapshot - you could try 'debugging' it step by step (s1,...,s4 below) and seeing where it 'breaks'.

(just a guess) you may need to invoke parse_json() on a string payload so that you can actually access dynamic properties in it.

```<code>exceptions
| limit 50
| project s1 = customDimensions["Logger Message"]
| extend  s2 = s1.statusCode
| extend  s3 = toint(s2)
| extend  s4 = s3 > 200 and s3 < 300
</code>```

Update:

try using parse_json() as the previous 'guess' suggested:

(plus, see Notes section here: https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/parsejsonfunction)

```<code>exceptions
| limit 50
| project s1 = parse_json(tostring(customDimensions["Logger Message"]))
| extend  s2 = s1.statusCode
| extend  s3 = toint(s2)
| extend  s4 = s3 > 200 and s3 < 300
</code>```

Body:
I have a Java application that sends log4j2 logs to App Insights. When logging an exception I basically pass a JSON in string format and the exception something like this

JSONObject json=new JSONObject();
json.put(...)
....
log.error(json.toString(), exception)

On the App Insights side; the message is stored under customDimensions with the key Logger Message in a JSON format.

From this stored information, I would like to make a query that would fetch all the exception messages where the statusCode > 200 and statusCode < 300. I've tried couple of queries but I was not able to extract those specific exception messages.

One of the queries I was trying was

exceptions
| limit 50
| where toint(customDimensions["Logger Message"].statusCode) > 200
  and toint(customDimensions["Logger Message"].statusCode) < 300

Any help would be appreciated

Update: I've running the query

exceptions
| limit 50
| project s1 = customDimensions["Logger Message"]
| extend  s2 = s1.statusCode
| extend  s3 = toint(s2)
| extend  s4 = s3 >= 200 and s3 < 300

Body:
from a query language perspective, you're doing the right thing (assuming you actually want > 200 and not >= 200, so that the query in your example will actually return the record you've pasted a snapshot of)

print customDimensions = dynamic({
    "Logger Message":{
        "message":"Test 1 and Test 2",
        "statusCode": 200
    }
})
| project toint(customDimensions['Logger Message'].statusCode)

This returns a single table, with a single row, with a single column, with the value 200.

It's hard to fully understand how the actual data in your case looks like based on the snapshot - you could try 'debugging' it step by step (s1,...,s4 below) and seeing where it 'breaks'.

(just a guess) you may need to invoke parse_json() on a string payload so that you can actually access dynamic properties in it.

exceptions
| limit 50
| project s1 = customDimensions["Logger Message"]
| extend  s2 = s1.statusCode
| extend  s3 = toint(s2)
| extend  s4 = s3 > 200 and s3 < 300

Update:

try using parse_json() as the previous 'guess' suggested:

(plus, see Notes section here: https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/parsejsonfunction)

exceptions
| limit 50
| project s1 = parse_json(tostring(customDimensions["Logger Message"]))
| extend  s2 = s1.statusCode
| extend  s3 = toint(s2)
| extend  s4 = s3 > 200 and s3 < 300


问:
Blazor multi-user questionaire
I need to create an app thats basically functions like a multi-user realtime questionnaire or trivia.

I've gotten to the point where i've created a questionnaire and associated users to it, but i'm hitting a road block on how to go forward.

Basically what i need to do next is
For each question in the questionnaire:

1) have the server send the users a question

2) wait for all of the users to respond or a set timeout period

3) display to the users a question result page

I was wondering how i should attempt to do something like this. Any help or resources would be wonderful

答:
I am building a chat application that has something very similar using Server Side Blazor.

The way I did was I inject a class I created called SubscriberService:

```<code>@inject Services.SubscriberService SubscriberService
</code>```

Then in my ConfigureServices method in Startup.cs I add this:

```<code>services.AddSingleton<SubscriberService>();
</code>```

The Add Singleton means only 1 instance will be created for all your browser instances (users).

This makes my Subscriber Services available to all my subcribers, which is just a name, Guid Id and a callback delegate

```<code>#region using statements

using DataJuggler.UltimateHelper.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Transactions;

#endregion

namespace BlazorChat.Services
{

    #region class SubscriberService
    /// <summary>
    /// This class is used to subscribe to services, so other windows get a notification a new message
    /// came in.
    /// </summary>
    public class SubscriberService
    {

        #region Private Variables
        private int count;
        private Guid serverId;
        private List<SubscriberCallback> subscribers;
        #endregion

        #region Constructor
        /// <summary>
        /// Create a new instance of a 'SubscriberService' object.
        /// </summary>
        public SubscriberService()
        {
            // Create a new Guid
            this.ServerId = Guid.NewGuid();
            Subscribers = new List<SubscriberCallback>();
        }
        #endregion

        #region Methods

            #region BroadcastMessage(SubscriberMessage message)
            /// <summary>
            /// This method Broadcasts a Message to everyone that ins't blocked.
            /// Note To Self: Add Blocked Feature
            /// </summary>
            public void BroadcastMessage(SubscriberMessage message)
            {
                // if the value for HasSubscribers is true
                if ((HasSubscribers) && (NullHelper.Exists(message)))
                {
                    // Iterate the collection of SubscriberCallback objects
                    foreach (SubscriberCallback subscriber in Subscribers)
                    {
                        // if the Callback exists
                        if ((subscriber.HasCallback) && (subscriber.Id != message.FromId))
                        {
                            // to do: Add if not blocked

                            // send the message
                            subscriber.Callback(message);
                        }
                    }
                }
            }
            #endregion

            #region GetSubscriberNames()
            /// <summary>
            /// This method returns a list of Subscriber Names ()
            /// </summary>
            public List<string> GetSubscriberNames()
            {
                // initial value
                List<string> subscriberNames = null;

                // if the value for HasSubscribers is true
                if (HasSubscribers)
                {
                    // create the return value
                    subscriberNames = new List<string>();

                    // Get the SubscriberNamesl in alphabetical order
                    List<SubscriberCallback> sortedNames = Subscribers.OrderBy(x => x.Name).ToList();

                    // Iterate the collection of SubscriberService objects
                    foreach (SubscriberCallback subscriber in sortedNames)
                    {
                        // Add this name
                        subscriberNames.Add(subscriber.Name);
                    }
                }

                // return value
                return subscriberNames;
            }
            #endregion

            #region Subscribe(string subscriberName)
            /// <summary>
            /// method returns a message with their id
            /// </summary>
            public SubscriberMessage Subscribe(SubscriberCallback subscriber)
            {
                // initial value
                SubscriberMessage message = null;

                // If the subscriber object exists
                if ((NullHelper.Exists(subscriber)) && (HasSubscribers))
                {
                    // Add this item
                    Subscribers.Add(subscriber);

                    // return a test message for now
                    message = new SubscriberMessage();

                    // set the message return properties
                    message.FromName = "Subscriber Service";
                    message.FromId = ServerId;
                    message.ToName = subscriber.Name;
                    message.ToId = subscriber.Id;
                    message.Data = Subscribers.Count.ToString();
                    message.Text = "Subscribed";
                }

                // return value
                return message;
            }
            #endregion

            #region Unsubscribe(Guid id)
            /// <summary>
            /// This method Unsubscribe
            /// </summary>
            public void Unsubscribe(Guid id)
            {
                // if the value for HasSubscribers is true
                if ((HasSubscribers) && (Subscribers.Count > 0))
                {
                    // attempt to find this callback
                    SubscriberCallback callback = Subscribers.FirstOrDefault(x => x.Id == id);

                    // If the callback object exists
                    if (NullHelper.Exists(callback))
                    {
                        // Remove this item
                        Subscribers.Remove(callback);

                         // create a new message
                        SubscriberMessage message = new SubscriberMessage();

                        // set the message return properties
                        message.FromId = ServerId;
                        message.FromName = "Subscriber Service";
                        message.Text = callback.Name + " has left the conversation.";
                        message.ToId = Guid.Empty;
                        message.ToName = "Room";

                        // Broadcast the message to everyone
                        BroadcastMessage(message);
                    }
                }
            }
            #endregion

        #endregion

        #region Properties

            #region Count
            /// <summary>
            /// This property gets or sets the value for 'Count'.
            /// </summary>
            public int Count
            {
                get { return count; }
                set { count = value; }
            }
            #endregion

            #region HasSubscribers
            /// <summary>
            /// This property returns true if this object has a 'Subscribers'.
            /// </summary>
            public bool HasSubscribers
            {
                get
                {
                    // initial value
                    bool hasSubscribers = (this.Subscribers != null);

                    // return value
                    return hasSubscribers;
                }
            }
            #endregion

            #region ServerId
            /// <summary>
            /// This property gets or sets the value for 'ServerId'.
            /// </summary>
            public Guid ServerId
            {
                get { return serverId; }
                set { serverId = value; }
            }
            #endregion

            #region Subscribers
            /// <summary>
            /// This property gets or sets the value for 'Subscribers'.
            /// </summary>
            public List<SubscriberCallback> Subscribers
            {
                get { return subscribers; }
                set { subscribers = value; }
            }
            #endregion

        #endregion

    }
    #endregion

}
</code>```

Here is my SubscriberCallback.cs:

```<code>#region using statements

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

#endregion

namespace BlazorChat
{

    #region class SubscriberCallback
    /// <summary>
    /// This class is used to register a subscriber with the ChatService
    /// </summary>
    public class SubscriberCallback
    {

        #region Private Variables
        private string name;
        private Guid id;
        private Callback callback;
        private List<Guid> blockedList;
        #endregion

        #region Constructor
        /// <summary>
        /// Create a new instance of a SubscriberCallback instance
        /// </summary>
        public SubscriberCallback(string name)
        {
            // store the Name
            Name = name;

            // Create the Id
            Id = Guid.NewGuid();

            // create a BlockedList
            BlockedList = new List<Guid>();
        }
        #endregion

        #region Methods

            #region ToString()
            /// <summary>
            /// This method is used to return the Name of the Subscriber when ToString is called.
            /// </summary>
            /// <returns></returns>
            public override string ToString()
            {
                // return the Name when ToString is called
                return this.Name;
            }
            #endregion

        #endregion

        #region Properties

        #region BlockedList
        /// <summary>
        /// This property gets or sets the value for 'BlockedList'.
        /// </summary>
        public List<Guid> BlockedList
            {
                get { return blockedList; }
                set { blockedList = value; }
            }
            #endregion

            #region Callback
            /// <summary>
            /// This property gets or sets the value for 'Callback'.
            /// </summary>
            public Callback Callback
            {
                get { return callback; }
                set { callback = value; }
            }
            #endregion

            #region HasBlockedList
            /// <summary>
            /// This property returns true if this object has a 'BlockedList'.
            /// </summary>
            public bool HasBlockedList
            {
                get
                {
                    // initial value
                    bool hasBlockedList = (this.BlockedList != null);

                    // return value
                    return hasBlockedList;
                }
            }
            #endregion

            #region HasCallback
            /// <summary>
            /// This property returns true if this object has a 'Callback'.
            /// </summary>
            public bool HasCallback
            {
                get
                {
                    // initial value
                    bool hasCallback = (this.Callback != null);

                    // return value
                    return hasCallback;
                }
            }
            #endregion

            #region HasName
            /// <summary>
            /// This property returns true if the 'Name' exists.
            /// </summary>
            public bool HasName
            {
                get
                {
                    // initial value
                    bool hasName = (!String.IsNullOrEmpty(this.Name));

                    // return value
                    return hasName;
                }
            }
            #endregion

            #region Id
            /// <summary>
            /// This property gets or sets the value for 'Id'.
            /// </summary>
            public Guid Id
            {
                get { return id; }
                set { id = value; }
            }
            #endregion

            #region Name
            /// <summary>
            /// This property gets or sets the value for 'Name'.
            /// </summary>
            public string Name
            {
                get { return name; }
                set { name = value; }
            }
            #endregion

        #endregion

    }
    #endregion

}
</code>```

And here is my delegate class:

```<code>/// <summary>
/// This delegate is used by the SubscriberService to send messages to any subscribers
/// </summary>
/// <returns></returns>
public delegate void Callback(SubscriberMessage message);
</code>```

Then in my component I call methods like this:

```<code>//  Send this message to all clients
SubscriberService.BroadcastMessage(message);
</code>```

And each client has a listen method:

```<code>SubscriberCallback callback = new SubscriberCallback(SubscriberName);
callback.Callback = Listen;
callback.Name = SubscriberName;

// Get a message back
SubscriberMessage message = SubscriberService.Subscribe(callback);
</code>```

Here is my Listen method, it just waits for messages;

```<code>using DataJuggler.UltimateHelper.Core; // Nuget package

public void Listen(SubscriberMessage message)
{
    // if the message exists (part of DataJuggler.UltimateHelper.Core Nuget Package)
    // Same as (message != null)
    if (NullHelper.Exists(message))
    {
        // if the message contains Joined the conversation
        if ((message.Text.Contains("joined the conversation")) ||
        (message.Text.Contains("left the conversation")))
        {
            // this updates my list of 'Whose On' whenever a user joins or leaves

            // Get the Names again
            this.Names = SubscriberService.GetSubscriberNames();

            // Update the UI
            Refresh();
        }
        else
        {
            // my display message code is here
        }
    }
</code>```

And finally here is my Subscriber message:

```<code>#region using statements

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

#endregion

namespace BlazorChat
{

    #region class SubscriberMessage
    /// <summary>
    /// This class is used to send information between components / pages.
    /// </summary>
    public class SubscriberMessage
    {

        #region Private Variables
        private string text;
        private Guid fromId;
        private Guid toId;
        private string fromName;
        private string toName;
        private object data;
        private string valid;
        private DateTime sent;
        private string invalidReason;
        #endregion

        #region Properties

            #region Data
            /// <summary>
            /// This property gets or sets the value for 'Data'.
            /// </summary>
            public object Data
            {
                get { return data; }
                set { data = value; }
            }
            #endregion

            #region FromId
            /// <summary>
            /// This property gets or sets the value for 'FromId'.
            /// </summary>
            public Guid FromId
            {
                get { return fromId; }
                set { fromId = value; }
            }
            #endregion

            #region FromName
            /// <summary>
            /// This property gets or sets the value for 'FromName'.
            /// </summary>
            public string FromName
            {
                get { return fromName; }
                set { fromName = value; }
            }
            #endregion

            #region HasText
            /// <summary>
            /// This property returns true if the 'Text' exists.
            /// </summary>
            public bool HasText
            {
                get
                {
                    // initial value
                    bool hasText = (!String.IsNullOrEmpty(this.Text));

                    // return value
                    return hasText;
                }
            }
            #endregion

            #region InvalidReason
            /// <summary>
            /// This property gets or sets the value for 'InvalidReason'.
            /// </summary>
            public string InvalidReason
            {
                get { return invalidReason; }
                set { invalidReason = value; }
            }
            #endregion

            #region Sent
            /// <summary>
            /// This property gets or sets the value for 'Sent'.
            /// </summary>
            public DateTime Sent
            {
                get { return sent; }
                set { sent = value; }
            }
            #endregion

            #region Text
            /// <summary>
            /// This property gets or sets the value for 'Text'.
            /// </summary>
            public string Text
            {
                get { return text; }
                set { text = value; }
            }
            #endregion

            #region ToId
            /// <summary>
            /// This property gets or sets the value for 'ToId'.
            /// </summary>
            public Guid ToId
            {
                get { return toId; }
                set { toId = value; }
            }
            #endregion

            #region ToName
            /// <summary>
            /// This property gets or sets the value for 'ToName'.
            /// </summary>
            public string ToName
            {
                get { return toName; }
                set { toName = value; }
            }
            #endregion

            #region Valid
            /// <summary>
            /// This property gets or sets the value for 'Valid'.
            /// </summary>
            public string Valid
            {
                get { return valid; }
                set { valid = value; }
            }
            #endregion

        #endregion

    }
    #endregion

}
</code>```

BlazorChat is a sample project I am still working on as part of my Nuget package:
DataJuggler.Blazor.Components, which contains a Sprite component, ProgressBar and Validation component.

The full code is here in the Samples folder of this project if I left anything out.
https://github.com/DataJuggler/DataJuggler.Blazor.Components

Documentation and SQL scripts are missing, so sorry, its a work in progress.

Title: Blazor multi-user questionaire

Body:
I am building a chat application that has something very similar using Server Side Blazor.

The way I did was I inject a class I created called SubscriberService:

@inject Services.SubscriberService SubscriberService

Then in my ConfigureServices method in Startup.cs I add this:

services.AddSingleton<SubscriberService>();

The Add Singleton means only 1 instance will be created for all your browser instances (users).

This makes my Subscriber Services available to all my subcribers, which is just a name, Guid Id and a callback delegate

#region using statements

using DataJuggler.UltimateHelper.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Transactions;

#endregion

namespace BlazorChat.Services
{

    #region class SubscriberService
    /// <summary>
    /// This class is used to subscribe to services, so other windows get a notification a new message
    /// came in.
    /// </summary>
    public class SubscriberService
    {

        #region Private Variables
        private int count;
        private Guid serverId;
        private List<SubscriberCallback> subscribers;
        #endregion

        #region Constructor
        /// <summary>
        /// Create a new instance of a 'SubscriberService' object.
        /// </summary>
        public SubscriberService()
        {
            // Create a new Guid
            this.ServerId = Guid.NewGuid();
            Subscribers = new List<SubscriberCallback>();
        }
        #endregion

        #region Methods

            #region BroadcastMessage(SubscriberMessage message)
            /// <summary>
            /// This method Broadcasts a Message to everyone that ins't blocked.
            /// Note To Self: Add Blocked Feature
            /// </summary>
            public void BroadcastMessage(SubscriberMessage message)
            {
                // if the value for HasSubscribers is true
                if ((HasSubscribers) && (NullHelper.Exists(message)))
                {
                    // Iterate the collection of SubscriberCallback objects
                    foreach (SubscriberCallback subscriber in Subscribers)
                    {
                        // if the Callback exists
                        if ((subscriber.HasCallback) && (subscriber.Id != message.FromId))
                        {
                            // to do: Add if not blocked

                            // send the message
                            subscriber.Callback(message);
                        }
                    }
                }
            }
            #endregion

            #region GetSubscriberNames()
            /// <summary>
            /// This method returns a list of Subscriber Names ()
            /// </summary>
            public List<string> GetSubscriberNames()
            {
                // initial value
                List<string> subscriberNames = null;

                // if the value for HasSubscribers is true
                if (HasSubscribers)
                {
                    // create the return value
                    subscriberNames = new List<string>();

                    // Get the SubscriberNamesl in alphabetical order
                    List<SubscriberCallback> sortedNames = Subscribers.OrderBy(x => x.Name).ToList();

                    // Iterate the collection of SubscriberService objects
                    foreach (SubscriberCallback subscriber in sortedNames)
                    {
                        // Add this name
                        subscriberNames.Add(subscriber.Name);
                    }
                }

                // return value
                return subscriberNames;
            }
            #endregion

            #region Subscribe(string subscriberName)
            /// <summary>
            /// method returns a message with their id
            /// </summary>
            public SubscriberMessage Subscribe(SubscriberCallback subscriber)
            {
                // initial value
                SubscriberMessage message = null;

                // If the subscriber object exists
                if ((NullHelper.Exists(subscriber)) && (HasSubscribers))
                {
                    // Add this item
                    Subscribers.Add(subscriber);

                    // return a test message for now
                    message = new SubscriberMessage();

                    // set the message return properties
                    message.FromName = "Subscriber Service";
                    message.FromId = ServerId;
                    message.ToName = subscriber.Name;
                    message.ToId = subscriber.Id;
                    message.Data = Subscribers.Count.ToString();
                    message.Text = "Subscribed";
                }

                // return value
                return message;
            }
            #endregion

            #region Unsubscribe(Guid id)
            /// <summary>
            /// This method Unsubscribe
            /// </summary>
            public void Unsubscribe(Guid id)
            {
                // if the value for HasSubscribers is true
                if ((HasSubscribers) && (Subscribers.Count > 0))
                {
                    // attempt to find this callback
                    SubscriberCallback callback = Subscribers.FirstOrDefault(x => x.Id == id);

                    // If the callback object exists
                    if (NullHelper.Exists(callback))
                    {
                        // Remove this item
                        Subscribers.Remove(callback);

                         // create a new message
                        SubscriberMessage message = new SubscriberMessage();

                        // set the message return properties
                        message.FromId = ServerId;
                        message.FromName = "Subscriber Service";
                        message.Text = callback.Name + " has left the conversation.";
                        message.ToId = Guid.Empty;
                        message.ToName = "Room";

                        // Broadcast the message to everyone
                        BroadcastMessage(message);
                    }
                }
            }
            #endregion

        #endregion

        #region Properties

            #region Count
            /// <summary>
            /// This property gets or sets the value for 'Count'.
            /// </summary>
            public int Count
            {
                get { return count; }
                set { count = value; }
            }
            #endregion

            #region HasSubscribers
            /// <summary>
            /// This property returns true if this object has a 'Subscribers'.
            /// </summary>
            public bool HasSubscribers
            {
                get
                {
                    // initial value
                    bool hasSubscribers = (this.Subscribers != null);

                    // return value
                    return hasSubscribers;
                }
            }
            #endregion

            #region ServerId
            /// <summary>
            /// This property gets or sets the value for 'ServerId'.
            /// </summary>
            public Guid ServerId
            {
                get { return serverId; }
                set { serverId = value; }
            }
            #endregion

            #region Subscribers
            /// <summary>
            /// This property gets or sets the value for 'Subscribers'.
            /// </summary>
            public List<SubscriberCallback> Subscribers
            {
                get { return subscribers; }
                set { subscribers = value; }
            }
            #endregion

        #endregion

    }
    #endregion

}

Here is my SubscriberCallback.cs:

#region using statements

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

#endregion

namespace BlazorChat
{

    #region class SubscriberCallback
    /// <summary>
    /// This class is used to register a subscriber with the ChatService
    /// </summary>
    public class SubscriberCallback
    {

        #region Private Variables
        private string name;
        private Guid id;
        private Callback callback;
        private List<Guid> blockedList;
        #endregion

        #region Constructor
        /// <summary>
        /// Create a new instance of a SubscriberCallback instance
        /// </summary>
        public SubscriberCallback(string name)
        {
            // store the Name
            Name = name;

            // Create the Id
            Id = Guid.NewGuid();

            // create a BlockedList
            BlockedList = new List<Guid>();
        }
        #endregion

        #region Methods

            #region ToString()
            /// <summary>
            /// This method is used to return the Name of the Subscriber when ToString is called.
            /// </summary>
            /// <returns></returns>
            public override string ToString()
            {
                // return the Name when ToString is called
                return this.Name;
            }
            #endregion

        #endregion

        #region Properties

        #region BlockedList
        /// <summary>
        /// This property gets or sets the value for 'BlockedList'.
        /// </summary>
        public List<Guid> BlockedList
            {
                get { return blockedList; }
                set { blockedList = value; }
            }
            #endregion

            #region Callback
            /// <summary>
            /// This property gets or sets the value for 'Callback'.
            /// </summary>
            public Callback Callback
            {
                get { return callback; }
                set { callback = value; }
            }
            #endregion

            #region HasBlockedList
            /// <summary>
            /// This property returns true if this object has a 'BlockedList'.
            /// </summary>
            public bool HasBlockedList
            {
                get
                {
                    // initial value
                    bool hasBlockedList = (this.BlockedList != null);

                    // return value
                    return hasBlockedList;
                }
            }
            #endregion

            #region HasCallback
            /// <summary>
            /// This property returns true if this object has a 'Callback'.
            /// </summary>
            public bool HasCallback
            {
                get
                {
                    // initial value
                    bool hasCallback = (this.Callback != null);

                    // return value
                    return hasCallback;
                }
            }
            #endregion

            #region HasName
            /// <summary>
            /// This property returns true if the 'Name' exists.
            /// </summary>
            public bool HasName
            {
                get
                {
                    // initial value
                    bool hasName = (!String.IsNullOrEmpty(this.Name));

                    // return value
                    return hasName;
                }
            }
            #endregion

            #region Id
            /// <summary>
            /// This property gets or sets the value for 'Id'.
            /// </summary>
            public Guid Id
            {
                get { return id; }
                set { id = value; }
            }
            #endregion

            #region Name
            /// <summary>
            /// This property gets or sets the value for 'Name'.
            /// </summary>
            public string Name
            {
                get { return name; }
                set { name = value; }
            }
            #endregion

        #endregion

    }
    #endregion

}

And here is my delegate class:

/// <summary>
/// This delegate is used by the SubscriberService to send messages to any subscribers
/// </summary>
/// <returns></returns>
public delegate void Callback(SubscriberMessage message);

Then in my component I call methods like this:

//  Send this message to all clients
SubscriberService.BroadcastMessage(message);

And each client has a listen method:

SubscriberCallback callback = new SubscriberCallback(SubscriberName);
callback.Callback = Listen;
callback.Name = SubscriberName;

// Get a message back
SubscriberMessage message = SubscriberService.Subscribe(callback);

Here is my Listen method, it just waits for messages;

using DataJuggler.UltimateHelper.Core; // Nuget package

public void Listen(SubscriberMessage message)
{
    // if the message exists (part of DataJuggler.UltimateHelper.Core Nuget Package)
    // Same as (message != null)
    if (NullHelper.Exists(message))
    {
        // if the message contains Joined the conversation
        if ((message.Text.Contains("joined the conversation")) ||
        (message.Text.Contains("left the conversation")))
        {
            // this updates my list of 'Whose On' whenever a user joins or leaves

            // Get the Names again
            this.Names = SubscriberService.GetSubscriberNames();

            // Update the UI
            Refresh();
        }
        else
        {
            // my display message code is here
        }
    }

And finally here is my Subscriber message:

#region using statements

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

#endregion

namespace BlazorChat
{

    #region class SubscriberMessage
    /// <summary>
    /// This class is used to send information between components / pages.
    /// </summary>
    public class SubscriberMessage
    {

        #region Private Variables
        private string text;
        private Guid fromId;
        private Guid toId;
        private string fromName;
        private string toName;
        private object data;
        private string valid;
        private DateTime sent;
        private string invalidReason;
        #endregion

        #region Properties

            #region Data
            /// <summary>
            /// This property gets or sets the value for 'Data'.
            /// </summary>
            public object Data
            {
                get { return data; }
                set { data = value; }
            }
            #endregion

            #region FromId
            /// <summary>
            /// This property gets or sets the value for 'FromId'.
            /// </summary>
            public Guid FromId
            {
                get { return fromId; }
                set { fromId = value; }
            }
            #endregion

            #region FromName
            /// <summary>
            /// This property gets or sets the value for 'FromName'.
            /// </summary>
            public string FromName
            {
                get { return fromName; }
                set { fromName = value; }
            }
            #endregion

            #region HasText
            /// <summary>
            /// This property returns true if the 'Text' exists.
            /// </summary>
            public bool HasText
            {
                get
                {
                    // initial value
                    bool hasText = (!String.IsNullOrEmpty(this.Text));

                    // return value
                    return hasText;
                }
            }
            #endregion

            #region InvalidReason
            /// <summary>
            /// This property gets or sets the value for 'InvalidReason'.
            /// </summary>
            public string InvalidReason
            {
                get { return invalidReason; }
                set { invalidReason = value; }
            }
            #endregion

            #region Sent
            /// <summary>
            /// This property gets or sets the value for 'Sent'.
            /// </summary>
            public DateTime Sent
            {
                get { return sent; }
                set { sent = value; }
            }
            #endregion

            #region Text
            /// <summary>
            /// This property gets or sets the value for 'Text'.
            /// </summary>
            public string Text
            {
                get { return text; }
                set { text = value; }
            }
            #endregion

            #region ToId
            /// <summary>
            /// This property gets or sets the value for 'ToId'.
            /// </summary>
            public Guid ToId
            {
                get { return toId; }
                set { toId = value; }
            }
            #endregion

            #region ToName
            /// <summary>
            /// This property gets or sets the value for 'ToName'.
            /// </summary>
            public string ToName
            {
                get { return toName; }
                set { toName = value; }
            }
            #endregion

            #region Valid
            /// <summary>
            /// This property gets or sets the value for 'Valid'.
            /// </summary>
            public string Valid
            {
                get { return valid; }
                set { valid = value; }
            }
            #endregion

        #endregion

    }
    #endregion

}

BlazorChat is a sample project I am still working on as part of my Nuget package:
DataJuggler.Blazor.Components, which contains a Sprite component, ProgressBar and Validation component.

The full code is here in the Samples folder of this project if I left anything out.
https://github.com/DataJuggler/DataJuggler.Blazor.Components

Documentation and SQL scripts are missing, so sorry, its a work in progress.


问:
How can I avoid DTOs duplication without inheritance?
I am connecting with many social networks for login in my application.
I have one DTO for each social network response.

```<code>public class GoogleUserInfo {
    private String id;
    private String firstName;
    private String lastName;
    private String email;
    private AgeRange ageRange;
    // more specific fields
}

public class FacebookUserInfo {
    private String id;
    private String firstName;
    private String lastName;
    private String email;
    private String picture;
    // more specific fields
}

public class AppleUserInfo {
    private String id;
    private String firstName;
    private String lastName;
    private String email;
    private Boolean emailVerified;
    // more specific fields
}
</code>```

In each social network connector, I make similar steps to fetch the information, so I thought I could go with some DTO as follows:

```<code>public class SocialNetworkInfo {
    protected String id;
    protected String firstName;
    protected String lastName;
    protected String email;
}
</code>```

Social networks DTOs could extend this to obtain the common fields. Then I could use this generic DTO to implement an abstract connector that deals with all the duplicate logic between connectors (make request, parse response, etc...):

```<code>abstract class AbstractConnector {
    abstract SocialNetworkInfo fetchUserInfo(String networkId);
    ...
}
</code>```

But I realized that above, in my service layer, I would need those specific fields to make some changes and operations.

```<code>SocialNetworkInfo networkUserInfo = facebookConnector.fetchUserInfo(facebookId);
facebookService.updatePicture(networkUserInfo.getPicture()); // can't access this specific field
</code>```

What do you think that's the best way to go through this situation without casting and avoiding logic or DTO duplication?

Would love to hear your thoughts.

Thanks!

答:
According to your situation, all social network models have the same nature, so it's ok if you move common attributes to shared class like CommonSocialInfo. Then I would recommend to provide interface for the connectors like:

```<code>interface SocialNetworkConnector<T extends SocialNetworkInfo> {
    T fetchUserInfo(String userId);
}
</code>```

Of course for common functionality(for connectors) is great idea to define common abstract class that implements interface above (implement Template pattern). I see that you are using FacebookService and related connector separately. I think that good idea to use composition in this case and make SocialNetworkService dependent on it connector. In short, FacebookService depends on FacebookConnecter and so on. Just a quick example:

```<code>public class FacebookService implements SocialNetworkService {
    private final SocialNetworkConnector<FacebookSocialInfo> connector;
    ...
}
</code>```

And if you need to implement multiple social service, you can use Factory pattern to produce required service, quick example:

```<code>interface SocialNetworkServiceFactory {
    SocialNetworkService getFacebookService();
    ...
}
</code>```

If you need more detailed help or you have troubles with understanding of the idea - feel free to ask!

Body:
I am connecting with many social networks for login in my application.
I have one DTO for each social network response.

public class GoogleUserInfo {
    private String id;
    private String firstName;
    private String lastName;
    private String email;
    private AgeRange ageRange;
    // more specific fields
}

public class FacebookUserInfo {
    private String id;
    private String firstName;
    private String lastName;
    private String email;
    private String picture;
    // more specific fields
}

public class AppleUserInfo {
    private String id;
    private String firstName;
    private String lastName;
    private String email;
    private Boolean emailVerified;
    // more specific fields
}

In each social network connector, I make similar steps to fetch the information, so I thought I could go with some DTO as follows:

public class SocialNetworkInfo {
    protected String id;
    protected String firstName;
    protected String lastName;
    protected String email;
}

Social networks DTOs could extend this to obtain the common fields. Then I could use this generic DTO to implement an abstract connector that deals with all the duplicate logic between connectors (make request, parse response, etc...):

abstract class AbstractConnector {
    abstract SocialNetworkInfo fetchUserInfo(String networkId);
    ...
}

But I realized that above, in my service layer, I would need those specific fields to make some changes and operations.

SocialNetworkInfo networkUserInfo = facebookConnector.fetchUserInfo(facebookId);
facebookService.updatePicture(networkUserInfo.getPicture()); // can't access this specific field

What do you think that's the best way to go through this situation without casting and avoiding logic or DTO duplication?

Would love to hear your thoughts.

Thanks!

Body:
According to your situation, all social network models have the same nature, so it's ok if you move common attributes to shared class like CommonSocialInfo. Then I would recommend to provide interface for the connectors like:

interface SocialNetworkConnector<T extends SocialNetworkInfo> {
    T fetchUserInfo(String userId);
}

Of course for common functionality(for connectors) is great idea to define common abstract class that implements interface above (implement Template pattern). I see that you are using FacebookService and related connector separately. I think that good idea to use composition in this case and make SocialNetworkService dependent on it connector. In short, FacebookService depends on FacebookConnecter and so on. Just a quick example:

public class FacebookService implements SocialNetworkService {
    private final SocialNetworkConnector<FacebookSocialInfo> connector;
    ...
}

And if you need to implement multiple social service, you can use Factory pattern to produce required service, quick example:

interface SocialNetworkServiceFactory {
    SocialNetworkService getFacebookService();
    ...
}

If you need more detailed help or you have troubles with understanding of the idea - feel free to ask!


问:
Git fatal: ambiguous argument '|': unknown revision or path not in the working tree
When I open git bash and execute the follow command, I have no problem!

```<code>  git log --no-renames --after=’2020-01-01’ --diff-filter=D --summary | grep 'delete mode' > log.txt
</code>```

But When I try to execute this:

```<code>GitTasks.Git(@"log --no-renames --after=’2020-01-01’ --diff-filter=D --summary | grep 'delete mode' > files.20.exclude", @"D:\folder\myproject");
</code>```

I Get those errors:

```<code>fatal: ambiguous argument '|': unknown revision or path not in the working tree.

fatal: ambiguous argument '>': unknown revision or path not in the working tree.
</code>```

What I have to do to get the same result?

答:
I got the problem, I was executing bash commands expecting to work with git like @axiac commented!

For resolving my problem, I wrote the log to a file without
| grep 'delete mode' and > log.txt and removed everything that I didn't want.

Body:
When I open git bash and execute the follow command, I have no problem!

  git log --no-renames --after=’2020-01-01’ --diff-filter=D --summary | grep 'delete mode' > log.txt

But When I try to execute this:

GitTasks.Git(@"log --no-renames --after=’2020-01-01’ --diff-filter=D --summary | grep 'delete mode' > files.20.exclude", @"D:\folder\myproject");

I Get those errors:

fatal: ambiguous argument '|': unknown revision or path not in the working tree.

fatal: ambiguous argument '>': unknown revision or path not in the working tree.

What I have to do to get the same result?


问:
Clean way of extracting VID, PID and Serial from Device Path
I managed to extract the device path of all connected USB devices on my computer using SetupDiGetDeviceInterfaceDetail. They usually look like the following:

```<code>\\?\hid#vid_0461&pid_4d15#6&219e7220&1&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
</code>```

Given this, what's the cleanest way of extracting vid (0461), pid (4d15) and serial number (6&219e7220&1&0000)?

I thought about using IndexOf(vid_) and reading 4 characters from there (similarly for others as well), but this solution looks pretty dirty.

Or is there a known Win32 API that extracts that information nicely without having to parse that info?

答:
You can use RegularExpressions. For example to extract vid, pid and serial number:</p>

```<code>string input ="\\?\hid#vid_0461&pid_4d15#6&219e7220&1&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}";
Regex rx = new Regex(@"_[0-9a-fA-F]+|\{[0-9a-fA-F\-]+\}");
MatchCollection matches = rx.Matches(input);

for (int i = 0; i< matches.Count; i++){
        console.writeln(matches[i].Value);
}
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I managed to extract the device path of all connected USB devices on my computer using SetupDiGetDeviceInterfaceDetail. They usually look like the following:

\\?\hid#vid_0461&pid_4d15#6&219e7220&1&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}

Given this, what's the cleanest way of extracting vid (0461), pid (4d15) and serial number (6&219e7220&1&0000)?

I thought about using IndexOf(vid_) and reading 4 characters from there (similarly for others as well), but this solution looks pretty dirty.

Or is there a known Win32 API that extracts that information nicely without having to parse that info?

Body:
You can use RegularExpressions. For example to extract vid, pid and serial number:

string input ="\\?\hid#vid_0461&pid_4d15#6&219e7220&1&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}";
Regex rx = new Regex(@"_[0-9a-fA-F]+|\{[0-9a-fA-F\-]+\}");
MatchCollection matches = rx.Matches(input);

for (int i = 0; i< matches.Count; i++){
        console.writeln(matches[i].Value);
}


问:
Sending a message on a user join event - discord.py
I've been programming a bot that welcomes a user when they join but it doesn't seem to be working.</p>

```<code>async def on_member_join(member):
    channel = member.channel
    await channel.send(f'{member} has arrived')
</code>```

答:
You haven't specified where the channel is that you want to send the message to, and discord.Member doesn't have an attribute called channel.

You'll have to get the channel via its ID, like so:

async def on_member_join(member):
    channel = bot.get_channel(112233445566778899) # replace id with the welcome channel's id
    await channel.send(f"{member} has arrived!")
```

<p>If you want to, you can also get it via its name:</p>

<pre class="lang-py prettyprint-override"><code>async def on_member_join(member):
    channel = discord.utils.get(member.guild.text_channels, name="welcome")
    await channel.send(f"{member} has arrived!")
</code>```

References:

on_member_join()

Client.get_channel()

Guild.text_channels

Member.guild

utils.get()

Body:
I've been programming a bot that welcomes a user when they join but it doesn't seem to be working.

async def on_member_join(member):
    channel = member.channel
    await channel.send(f'{member} has arrived')

Body:
You haven't specified where the channel is that you want to send the message to, and discord.Member doesn't have an attribute called channel.

You'll have to get the channel via its ID, like so:

async def on_member_join(member):
    channel = bot.get_channel(112233445566778899) # replace id with the welcome channel's id
    await channel.send(f"{member} has arrived!")

If you want to, you can also get it via its name:

async def on_member_join(member):
    channel = discord.utils.get(member.guild.text_channels, name="welcome")
    await channel.send(f"{member} has arrived!")

References:

on_member_join()

Client.get_channel()

Guild.text_channels

Member.guild

utils.get()


问:
Why we write Bearer in front of the token in the authorization header?
When I have for example a post method - login, I get back the signed JSON web token. I watched some tutorials on youtube and there, when they check if the user is authorized, they send the JWT in the authorization header like:

Bearer -token-

My question is: why they do that, when the same thing is working if we send only the token in the authorization header, without the "Bearer" in front of the token?

答: Because it's in the relevant standards documents. The general scheme is that you first state the type of token ("Bearer" in this case) and then the token itself. There are other authentication schemes too and they use different type keywords (like "Basic" or "Digest"). If you control the web server and parse the headers yourself then, sure, you can use whatever syntax you like. You can even invent your own header, nobody's stopping you. But having it comply to a unified standard makes it a little easier down the road when  you need to integrate with other systems. :)</p>


问:
Pandas groupby mean() not ignoring NaNs
If I calculate the mean of a groupby object and within one of the groups there is a NaN(s) the NaNs are ignored. Even when applying np.mean it is still returning just the mean of all valid numbers. I would expect a behaviour of returning NaN as soon as one NaN is within the group. Here a simplified example of the behaviour

```<code>import pandas as pd
import numpy as np
c = pd.DataFrame({'a':[1,np.nan,2,3],'b':[1,2,1,2]})
c.groupby('b').mean()
     a
b
1  1.5
2  3.0
c.groupby('b').agg(np.mean)
     a
b
1  1.5
2  3.0
</code>```

I want to receive following result:

```<code>     a
b
1  1.5
2  NaN
</code>```

I am aware that I can replace NaNs beforehand and that i probably can write my own aggregation function to return NaN as soon as NaN is within the group. This function wouldn't be optimized though.

Do you know of an argument to achieve the desired behaviour with the optimized functions?

Btw, I think the desired behaviour was implemented in a previous version of pandas.

答:
There is mean(skipna=False), but it's not working

GroupBy aggregation methods (min, max, mean, median, etc.) have the skipna parameter, which is meant for this exact task, but it seems that currently (may-2020) there is a bug (issue opened on mar-2020), which prevents it from working correctly.

Quick workaround

Complete working example based on this comments: @Serge Ballesta, @RoelAdriaans

>>> import pandas as pd
>>> import numpy as np
>>> c = pd.DataFrame({'a':[1,np.nan,2,3],'b':[1,2,1,2]})
>>> c.fillna(np.inf).groupby('b').mean().replace(np.inf, np.nan)

     a
b
1  1.5
2  NaN
```

For additional information and updates follow the link above.

Title: Pandas groupby mean() not ignoring NaNs

Body:
If I calculate the mean of a groupby object and within one of the groups there is a NaN(s) the NaNs are ignored. Even when applying np.mean it is still returning just the mean of all valid numbers. I would expect a behaviour of returning NaN as soon as one NaN is within the group. Here a simplified example of the behaviour

import pandas as pd
import numpy as np
c = pd.DataFrame({'a':[1,np.nan,2,3],'b':[1,2,1,2]})
c.groupby('b').mean()
     a
b
1  1.5
2  3.0
c.groupby('b').agg(np.mean)
     a
b
1  1.5
2  3.0

I want to receive following result:

     a
b
1  1.5
2  NaN

I am aware that I can replace NaNs beforehand and that i probably can write my own aggregation function to return NaN as soon as NaN is within the group. This function wouldn't be optimized though.

Do you know of an argument to achieve the desired behaviour with the optimized functions?

Btw, I think the desired behaviour was implemented in a previous version of pandas.

Body:
There is mean(skipna=False), but it's not working

GroupBy aggregation methods (min, max, mean, median, etc.) have the skipna parameter, which is meant for this exact task, but it seems that currently (may-2020) there is a bug (issue opened on mar-2020), which prevents it from working correctly.

Quick workaround

Complete working example based on this comments: @Serge Ballesta, @RoelAdriaans

>>> import pandas as pd
>>> import numpy as np
>>> c = pd.DataFrame({'a':[1,np.nan,2,3],'b':[1,2,1,2]})
>>> c.fillna(np.inf).groupby('b').mean().replace(np.inf, np.nan)

     a
b
1  1.5
2  NaN

For additional information and updates follow the link above.


问:
How to pause process run using Java's ProcessBuilder.start()?
Alright, so I'm writing this program that essentially batch runs other java programs for me (multiple times, varying parameters, parallel executions, etc).

So far the running part works great. Using ProcessBuilder's .start() method (equivalent to the Runtime.exec() I believe), it creates a separate java process and off it goes.

Problem is I would like to be able to pause/stop these processes once they've been started. With simple threads this is generally easy to do, however the external process doesn't seem to have any inbuilt functionality for waiting/sleeping, at least not from an external point of view.

My question(s) is this: Is there a way to pause a java.lang.Process object? If not, does anyone know of any related exec libraries that do contain this ability? Barring all of that, is extending Process a more viable alternative?

答:
You will need to create a system for sending messages between processes. You might do this by:

Sending signals, depending on OS. (As aioobe notes.)

Having one process occasionally check for presence/absence of a file that another process can create/delete. (If the file is being read/written, you will need to use file locking.)

Have your "main" process listen on a port, and when it launches the children it tells them (via a comamnd-line argument) how to "phone home" as they start up. Both programs alternate between doing work and checking for handling messages.

From what you have described (all Java programs in a complex batch environment) I would suggest #3, TCP/IP communication.

While it certainly involves extra work, it also gives you the flexibility to send commands or information of whatever kind you want between different processes.


问:
Continue column with average of previous values
I have a number of columns all indexed by datetime and I need to project a forecast for some of the columns based on the past n (lets say in this case 4) days.

```<code>          A  B  C
31-12-201917 19 49
1-1-2020  4  9  2
2-1-2020  2  23 3
3-1-2020  8  23 7
4-1-2020  6  21 4
5-1-2020  5
6-1-2020  5
7-1-2020  5
8-1-2020  5
9-1-2020  5
10-1-2020 5
11-1-2020 5
</code>```

So the desired output would have the average of the last 4 days as the respective value for that column for each of the future dates (as shown in column A). Note it should only take the last 4 days as opposed to all dates in the dataframe.

I've tried various rolling ave functions but all seem to require a new column!

Could anyone assist?

答:
It's not the best solution, but it is highly extensible. df.update is your saver in these situations.

```<code>import pandas as pd

df = pd.DataFrame([[17, 19, 49],
                   [4, 9, 2],
                   [2, 23, 3],
                   [8, 23, 7],
                   [6, 21, 24],
                   [5, "", ""],
                   [5, "", ""],
                   [5, "", ""],
                   [5, "", ""],
                   [5, "", ""],
                   [5, "", ""],
                   [5, "", ""]], columns=list("ABC"))

df.index = pd.date_range(start="12-31-2019", end="01-11-2020", freq="D")

def forecast(df):
    last_day = df.iloc[-1]
    new_day = last_day.name + pd.Timedelta(days=1)
    new_data = df.loc[last_day.name - pd.Timedelta(days=3):last_day.name, :].mean()
    new_data.name = new_day
    return new_data

num_predict_days = 7
columns_to_predict = ['B', 'C']

available_data = df.shape[0] - num_predict_days
df_to_predict = df.iloc[:available_data, :].loc[:, columns_to_predict]

for i in range(num_predict_days):
    df_to_predict = df_to_predict.append(forecast(df_to_predict))

df.update(df_to_predict)
</code>```

Body:
I have a number of columns all indexed by datetime and I need to project a forecast for some of the columns based on the past n (lets say in this case 4) days.

          A  B  C
31-12-201917 19 49
1-1-2020  4  9  2
2-1-2020  2  23 3
3-1-2020  8  23 7
4-1-2020  6  21 4
5-1-2020  5
6-1-2020  5
7-1-2020  5
8-1-2020  5
9-1-2020  5
10-1-2020 5
11-1-2020 5

So the desired output would have the average of the last 4 days as the respective value for that column for each of the future dates (as shown in column A). Note it should only take the last 4 days as opposed to all dates in the dataframe.

I've tried various rolling ave functions but all seem to require a new column!

Could anyone assist?

Body:
It's not the best solution, but it is highly extensible. df.update is your saver in these situations.

import pandas as pd

df = pd.DataFrame([[17, 19, 49],
                   [4, 9, 2],
                   [2, 23, 3],
                   [8, 23, 7],
                   [6, 21, 24],
                   [5, "", ""],
                   [5, "", ""],
                   [5, "", ""],
                   [5, "", ""],
                   [5, "", ""],
                   [5, "", ""],
                   [5, "", ""]], columns=list("ABC"))

df.index = pd.date_range(start="12-31-2019", end="01-11-2020", freq="D")

def forecast(df):
    last_day = df.iloc[-1]
    new_day = last_day.name + pd.Timedelta(days=1)
    new_data = df.loc[last_day.name - pd.Timedelta(days=3):last_day.name, :].mean()
    new_data.name = new_day
    return new_data

num_predict_days = 7
columns_to_predict = ['B', 'C']

available_data = df.shape[0] - num_predict_days
df_to_predict = df.iloc[:available_data, :].loc[:, columns_to_predict]

for i in range(num_predict_days):
    df_to_predict = df_to_predict.append(forecast(df_to_predict))

df.update(df_to_predict)


问:
how to provide inbound access from public internet to an app hosted in an Azure private kubernetes cluster
I deployed an application in an Azure K8S cluster, using NGINX as gateway, with a public static IP, based on AKS & PUBLIC-IP and on AKS & NGINX.

Now I need to deploy the application in an Azure private cluster, ie, running in a private vnet (see CREATE PRIVATE AKS); attempting to assign a public static IP to NGINX does not work, which can be expected as the load-balancer expects a private IP, not a public IP.

How can I provide inbound access to my app hosted in a private cluster, using NGINX and a public static IP?

答:
As stated in the comment above you can do the same via Application Gateway in Azure. But if you are going to only use AKS you might want to just use Application Gateway as your ingress controller which is already created with the private cluster.

Please follow this to achieve the same https://microsoft.github.io/AzureTipsAndTricks/blog/tip256.html


问:
fill Na values in df according to other columns values
I would need help in R and deal with columns marging infomations depending on patterns.
In order to undestand here is an exemple :

```<code>       Groups                    Names   COL1 COL2 COL3
1      G1 KB640596.1_2-BICs_-__SP1   <NA>   10   30
2      G1  KB640596.1_32-33_-__SP1  YP_98   NA   NA
3      G1  KB640596.1_32-33_-__SP1  YP_99   NA   NA
4      G1  KB640596.1_32-33_-__SP1 YP_100   NA   NA
5      G1  KB640596.1_32-33_-__SP1 YP_101   NA   NA
6      G1 KB640588.1_2-BICs_-__SP1   <NA>   89   28
7      G1  KB640596.1_38-39_-__SP1 YP_102   NA   NA
8      G1  KB640588.1_38-39_-__SP1 YP_103   NA   NA
9      G1  KB640596.1_21-90_-__SP1 YP_102   NA   NA
10     G1  KB640588.1_78-32_-__SP1 YP_102   NA   NA
11     G1  KB640596.1_89-90_-__SP2 YP_104   90   76
12     G2    LO640571_89-90_-__SP3 YP_100   30   90
13     G2    LO640571_89-90_-__SP3 YP_101   40   10
14     G3    LO640571_89-90_-__SP3   YP_2   29   29
15     G3    LO640571_10-20_-__SP3   YP_2   29   29
16     G3    LO640571_09-99_-__SP3   YP_2   29   29
</code>```

From this df I would like for each Groups and each Names that have a -BICs pattern to fill its COL2 COL3 values and remplace them to the other Names that
have the same content part before the first'_'`

so for instance :

Within the G1, only KB640596.1_2-BICs_-__SP1 has a -BICs pattern,
  then I extract the content before the first '_' pattern and get : KB640596.1
    KB640596.1 is also present in other Names then I add COL2 and COL3 values (10   and 30 respectively) to them and get :

```<code>Groups Names COL1 COL2 COL3
G1 KB640596.1_2-BICs_-__SP1 NA 10 30
G1 KB640596.1_2-BICs_-__SP1 YP_98 10 30
G1 KB640596.1_2-BICs_-__SP1 YP_99 10 30
G1 KB640596.1_2-BICs_-__SP1 YP_100 10 30
G1 KB640596.1_2-BICs_-__SP1 YP_101 10 30
G1 KB640588.1_2-BICs_-__SP1 NA 89 28
G1 KB640596.1_2-BICs_-__SP1 YP_102 10 30
G1 KB640588.1_2-BICs_-__SP1 YP_103 89 28
G1 KB640596.1_2-BICs_-__SP1 YP_102 10 30
G1 KB640588.1_2-BICs_-__SP1 YP_102 89 28
G1 KB640596.1_2-BICs_-__SP1 YP_104 90 76
G2 LO640571_89-90_-__SP3 YP_100 30 90
G2 LO640571_89-90_-__SP3 YP_101 40 10
G3 LO640571_89-90_-__SP3   YP_2   29   29
G3 LO640571_10-20_-__SP3   YP_2   29   29
G3 LO640571_09-99_-__SP3   YP_2   29   29
</code>```

If someone had and idea it would be greate

data

```<code>   structure(list(Groups = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 2L, 2L, 3L, 3L, 3L), .Label = c("G1", "G2", "G3"
), class = "factor"), Names = structure(c(4L, 6L, 6L, 6L, 6L,
1L, 7L, 2L, 5L, 3L, 8L, 11L, 11L, 11L, 10L, 9L), .Label = c("KB640588.1_2-BICs_-__SP1",
"KB640588.1_38-39_-__SP1", "KB640588.1_78-32_-__SP1", "KB640596.1_2-BICs_-__SP1",
"KB640596.1_21-90_-__SP1", "KB640596.1_32-33_-__SP1", "KB640596.1_38-39_-__SP1",
"KB640596.1_89-90_-__SP2", "LO640571_09-99_-__SP3", "LO640571_10-20_-__SP3",
"LO640571_89-90_-__SP3"), class = "factor"), COL1 = structure(c(NA,
7L, 8L, 1L, 2L, NA, 3L, 4L, 3L, 3L, 5L, 1L, 2L, 6L, 6L, 6L), .Label = c("YP_100",
"YP_101", "YP_102", "YP_103", "YP_104", "YP_2", "YP_98", "YP_99"
), class = "factor"), COL2 = c(10L, NA, NA, NA, NA, 89L, NA,
NA, NA, NA, 90L, 30L, 40L, 29L, 29L, 29L), COL3 = c(30L, NA,
NA, NA, NA, 28L, NA, NA, NA, NA, 76L, 90L, 10L, 29L, 29L, 29L
)), class = "data.frame", row.names = c(NA, -16L))
</code>```

答:
We can group by 'Groups' and the substring of 'Names' based on removing the suffix part, then mutate the numeric columns by replacing the NA elements with the corresponding values where the 'Names' have -BICs

```<code>library(dplyr)
library(stringr)
df %>%
  group_by(Groups, grp = str_remove(Names, "_\\d+.*")) %>%
   mutate_if(is.numeric, ~
      replace(., is.na(.), .[str_detect(Names, '-BICs')])) %>%
  ungroup %>%
  select(-grp)
# A tibble: 13 x 5
#   Groups Names                    COL1    COL2  COL3
#   <fct>  <fct>                    <fct>  <int> <int>
# 1 G1     KB640596.1_2-BICs_-__SP1 <NA>      10    30
# 2 G1     KB640596.1_32-33_-__SP1  YP_98     10    30
# 3 G1     KB640596.1_32-33_-__SP1  YP_99     10    30
# 4 G1     KB640596.1_32-33_-__SP1  YP_100    10    30
# 5 G1     KB640596.1_32-33_-__SP1  YP_101    10    30
# 6 G1     KB640588.1_2-BICs_-__SP1 <NA>      89    28
# 7 G1     KB640596.1_38-39_-__SP1  YP_102    10    30
# 8 G1     KB640588.1_38-39_-__SP1  YP_103    89    28
# 9 G1     KB640596.1_21-90_-__SP1  YP_102    10    30
#10 G1     KB640588.1_78-32_-__SP1  YP_102    89    28
#11 G1     KB640596.1_89-90_-__SP2  YP_104    90    76
#12 G2     LO640571_89-90_-__SP3    YP_100    30    90
#13 G2     LO640571_89-90_-__SP3    YP_101    40    10
</code>```

Or using mutate/across

```<code>df %>%
     group_by(Groups, grp = str_remove(Names, "_\\d+.*")) %>%
     mutate(across(where(is.numeric), ~replace(., is.na(.),
             .[str_detect(Names, '-BICs')]))) %>%
     ungroup %>%
     select(-grp)
</code>```

Body:
I would need help in R and deal with columns marging infomations depending on patterns.
In order to undestand here is an exemple :

       Groups                    Names   COL1 COL2 COL3
1      G1 KB640596.1_2-BICs_-__SP1   <NA>   10   30
2      G1  KB640596.1_32-33_-__SP1  YP_98   NA   NA
3      G1  KB640596.1_32-33_-__SP1  YP_99   NA   NA
4      G1  KB640596.1_32-33_-__SP1 YP_100   NA   NA
5      G1  KB640596.1_32-33_-__SP1 YP_101   NA   NA
6      G1 KB640588.1_2-BICs_-__SP1   <NA>   89   28
7      G1  KB640596.1_38-39_-__SP1 YP_102   NA   NA
8      G1  KB640588.1_38-39_-__SP1 YP_103   NA   NA
9      G1  KB640596.1_21-90_-__SP1 YP_102   NA   NA
10     G1  KB640588.1_78-32_-__SP1 YP_102   NA   NA
11     G1  KB640596.1_89-90_-__SP2 YP_104   90   76
12     G2    LO640571_89-90_-__SP3 YP_100   30   90
13     G2    LO640571_89-90_-__SP3 YP_101   40   10
14     G3    LO640571_89-90_-__SP3   YP_2   29   29
15     G3    LO640571_10-20_-__SP3   YP_2   29   29
16     G3    LO640571_09-99_-__SP3   YP_2   29   29

From this df I would like for each Groups and each Names that have a -BICs pattern to fill its COL2 COL3 values and remplace them to the other Names that
have the same content part before the first'_'`

so for instance :

Within the G1, only KB640596.1_2-BICs_-__SP1 has a -BICs pattern,
  then I extract the content before the first '_' pattern and get : KB640596.1
    KB640596.1 is also present in other Names then I add COL2 and COL3 values (10   and 30 respectively) to them and get :

Groups Names COL1 COL2 COL3
G1 KB640596.1_2-BICs_-__SP1 NA 10 30
G1 KB640596.1_2-BICs_-__SP1 YP_98 10 30
G1 KB640596.1_2-BICs_-__SP1 YP_99 10 30
G1 KB640596.1_2-BICs_-__SP1 YP_100 10 30
G1 KB640596.1_2-BICs_-__SP1 YP_101 10 30
G1 KB640588.1_2-BICs_-__SP1 NA 89 28
G1 KB640596.1_2-BICs_-__SP1 YP_102 10 30
G1 KB640588.1_2-BICs_-__SP1 YP_103 89 28
G1 KB640596.1_2-BICs_-__SP1 YP_102 10 30
G1 KB640588.1_2-BICs_-__SP1 YP_102 89 28
G1 KB640596.1_2-BICs_-__SP1 YP_104 90 76
G2 LO640571_89-90_-__SP3 YP_100 30 90
G2 LO640571_89-90_-__SP3 YP_101 40 10
G3 LO640571_89-90_-__SP3   YP_2   29   29
G3 LO640571_10-20_-__SP3   YP_2   29   29
G3 LO640571_09-99_-__SP3   YP_2   29   29

If someone had and idea it would be greate

data

   structure(list(Groups = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 2L, 2L, 3L, 3L, 3L), .Label = c("G1", "G2", "G3"
), class = "factor"), Names = structure(c(4L, 6L, 6L, 6L, 6L,
1L, 7L, 2L, 5L, 3L, 8L, 11L, 11L, 11L, 10L, 9L), .Label = c("KB640588.1_2-BICs_-__SP1",
"KB640588.1_38-39_-__SP1", "KB640588.1_78-32_-__SP1", "KB640596.1_2-BICs_-__SP1",
"KB640596.1_21-90_-__SP1", "KB640596.1_32-33_-__SP1", "KB640596.1_38-39_-__SP1",
"KB640596.1_89-90_-__SP2", "LO640571_09-99_-__SP3", "LO640571_10-20_-__SP3",
"LO640571_89-90_-__SP3"), class = "factor"), COL1 = structure(c(NA,
7L, 8L, 1L, 2L, NA, 3L, 4L, 3L, 3L, 5L, 1L, 2L, 6L, 6L, 6L), .Label = c("YP_100",
"YP_101", "YP_102", "YP_103", "YP_104", "YP_2", "YP_98", "YP_99"
), class = "factor"), COL2 = c(10L, NA, NA, NA, NA, 89L, NA,
NA, NA, NA, 90L, 30L, 40L, 29L, 29L, 29L), COL3 = c(30L, NA,
NA, NA, NA, 28L, NA, NA, NA, NA, 76L, 90L, 10L, 29L, 29L, 29L
)), class = "data.frame", row.names = c(NA, -16L))

Body:
We can group by 'Groups' and the substring of 'Names' based on removing the suffix part, then mutate the numeric columns by replacing the NA elements with the corresponding values where the 'Names' have -BICs

library(dplyr)
library(stringr)
df %>%
  group_by(Groups, grp = str_remove(Names, "_\\d+.*")) %>%
   mutate_if(is.numeric, ~
      replace(., is.na(.), .[str_detect(Names, '-BICs')])) %>%
  ungroup %>%
  select(-grp)
# A tibble: 13 x 5
#   Groups Names                    COL1    COL2  COL3
#   <fct>  <fct>                    <fct>  <int> <int>
# 1 G1     KB640596.1_2-BICs_-__SP1 <NA>      10    30
# 2 G1     KB640596.1_32-33_-__SP1  YP_98     10    30
# 3 G1     KB640596.1_32-33_-__SP1  YP_99     10    30
# 4 G1     KB640596.1_32-33_-__SP1  YP_100    10    30
# 5 G1     KB640596.1_32-33_-__SP1  YP_101    10    30
# 6 G1     KB640588.1_2-BICs_-__SP1 <NA>      89    28
# 7 G1     KB640596.1_38-39_-__SP1  YP_102    10    30
# 8 G1     KB640588.1_38-39_-__SP1  YP_103    89    28
# 9 G1     KB640596.1_21-90_-__SP1  YP_102    10    30
#10 G1     KB640588.1_78-32_-__SP1  YP_102    89    28
#11 G1     KB640596.1_89-90_-__SP2  YP_104    90    76
#12 G2     LO640571_89-90_-__SP3    YP_100    30    90
#13 G2     LO640571_89-90_-__SP3    YP_101    40    10

Or using mutate/across

df %>%
     group_by(Groups, grp = str_remove(Names, "_\\d+.*")) %>%
     mutate(across(where(is.numeric), ~replace(., is.na(.),
             .[str_detect(Names, '-BICs')]))) %>%
     ungroup %>%
     select(-grp)


问:
How to use "--replace" in wkhtmltopdf
I saw all that content, didn't see about the content of the way to use '--replace'.
How to use "--replace" in wkhtmltopdf.
Please give me an example,Thanks.:)</p>

答:
I did some adjustments to @viniciux answer which is actually working so here is the improvements in footer.html

```<code><!DOCTYPE html>
<html>
  <head>
  <meta charset="utf-8">
  <script charset="utf-8">
    function replaceParams() {
      var url = window.location.href
        .replace(/#$/, ""); // Remove last # if exist
      // default params
      //['page', 'section','sitepage','title','subsection','frompage','subsubsection','isodate','topage','doctitle','sitepages','webpage','time','date'];
      var params = (url.split("?")[1] || "").split("&");
      for (var i = 0; i < params.length; i++) {
          var param = params[i].split("=");
          var key = param[0];
          var value = param[1] || '';
          var regex = new RegExp('{' + key + '}', 'g');
          document.body.innerText = document.body.innerText.replace(regex, value);
      }
    }
  </script>
  </head>
  <body onload="replaceParams()">
    name: {username}
    age: {age}
    url: {url}
    page {page}
  </body>
</html>
</code>```

and then you can add multiple parameters to replace dynamically

```<code>wkhtmltopdf page.html --footer-html footer.html --replace "username" "Veaer" --replace "age" "20" --replace "url" "google.com"
</code>```

notice that page will be current pdf page and will be included by default in the parameters list

Title: How to use "--replace" in wkhtmltopdf

Body:
I did some adjustments to @viniciux answer which is actually working so here is the improvements in footer.html

<!DOCTYPE html>
<html>
  <head>
  <meta charset="utf-8">
  <script charset="utf-8">
    function replaceParams() {
      var url = window.location.href
        .replace(/#$/, ""); // Remove last # if exist
      // default params
      //['page', 'section','sitepage','title','subsection','frompage','subsubsection','isodate','topage','doctitle','sitepages','webpage','time','date'];
      var params = (url.split("?")[1] || "").split("&");
      for (var i = 0; i < params.length; i++) {
          var param = params[i].split("=");
          var key = param[0];
          var value = param[1] || '';
          var regex = new RegExp('{' + key + '}', 'g');
          document.body.innerText = document.body.innerText.replace(regex, value);
      }
    }
  </script>
  </head>
  <body onload="replaceParams()">
    name: {username}
    age: {age}
    url: {url}
    page {page}
  </body>
</html>

and then you can add multiple parameters to replace dynamically

wkhtmltopdf page.html --footer-html footer.html --replace "username" "Veaer" --replace "age" "20" --replace "url" "google.com"

notice that page will be current pdf page and will be included by default in the parameters list


问:
jQuery Toggle Display none and animate.css classes
I have a div that is initially hidden by display: none in the css.

```<code><div id="myDiv" class="animate__animated">Div content Here</div>
</code>```

I this have a function:

```<code>function togglefunc() {

    $('#myDiv').toggle().toggleClass('animate__slideInRight animate__slideInLeft');

}
</code>```

What I want to do is to toggle display: none and block but also toggle classes:

```<code>animate__slideInRight and animate__slideInLeft
</code>```

So...

If it's hidden and the function is called, it shows up with the effect animate__slideInRight (animate.css class)

otherwise

If it's visible and the function is called, it will hide with the effect animate__slideInLeft (animate.css class)

My function shows fine with the effect animate__slideInRight but when I click again if quickly hides with no effect.

How can I fix this?

答:
It does not work because the jquery toggle is done inmediatelly and not after the hide animation triggered by the attribute change is done.

I would instead use just jQuery for this slide effect:

function togglefunc() {
   $("#myDiv").animate({width: "toggle"}, 350);
}```
<pre class="snippet-code-css lang-css prettyprint-override"><code>#myDiv {
   overflow: hidden;
   white-space: nowrap;
}</code>```

<button onclick="togglefunc()">Toggle</button>

Div content Here
```

Body:
I have a div that is initially hidden by display: none in the css.

Div content Here

I this have a function:

function togglefunc() {

    $('#myDiv').toggle().toggleClass('animate__slideInRight animate__slideInLeft');

}

What I want to do is to toggle display: none and block but also toggle classes:

animate__slideInRight and animate__slideInLeft

So...

If it's hidden and the function is called, it shows up with the effect animate__slideInRight (animate.css class)

otherwise

If it's visible and the function is called, it will hide with the effect animate__slideInLeft (animate.css class)

My function shows fine with the effect animate__slideInRight but when I click again if quickly hides with no effect.

How can I fix this?

Body:
It does not work because the jquery toggle is done inmediatelly and not after the hide animation triggered by the attribute change is done.

I would instead use just jQuery for this slide effect:

function togglefunc() {
   $("#myDiv").animate({width: "toggle"}, 350);
}

#myDiv {
   overflow: hidden;
   white-space: nowrap;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button onclick="togglefunc()">Toggle</button><br><br>
<div id="myDiv" class="animate__animated">Div content Here</div>