答:
You can send SignalR messages from other places in your app using the IHubContext service. You simply inject it where you need to use it.

To address your issue I would add a new method to INotificationHub:

```<code>public interface INotificationHub
{
    Task ExcecutingDailyPost(string action);
}
</code>```

Inject your strongly typed hub context wherever you need to use hub functionality.

Your endpoint could then look like this:

```<code>public class DailyPostingController : ControllerBase
{
    private readonly IMapper _mapper;
    private readonly IDailyPostingService _DailyPostingService;
    private readonly ILogger<DailyPostingController> _logger;
    private readonly IHubContext<NotificationHub, INotificationHub> _hubContext;

    public DailyPostingController(IMapper mapper,
        IDailyPostingService DailyPostingService,
        ILogger<DailyPostingController> logger,
        IHubContext<NotificationHub, INotificationHub> hubContext)
    {
        _mapper = mapper;
        _DailyPostingService = DailyPostingService;
        _logger = logger;
        _hubContext = hubContext;
    }

    [Authorize(Policy = Permissions.DailyPosting.Execute)]
    [HttpPost("Execute")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<int> Execute(OperatingCentreQueryModel ocQueryModel)
    {
        _logger.LogDebug("Executing Daily posting for date#"
            + ocQueryModel.ProcessDate.ToString("dd/mmm/yyy"));

        // Notify your clients that the process has started
        await _hubContext.Clients.All.ExcecutingDailyPost("START");

        var res = await _DailyPostingService.Execute(ocQueryModel);

        // Notify your clients that the process has ended
        await _hubContext.Clients.All.ExcecutingDailyPost("END");
        return res;
    }
}
</code>```

Then on the client side you need to listen on the "ExcecutingDailyPost" channel and depending on the action, do what you would like.

Title: Publish message to connected clients from Web API through SignalR

Body:
You can send SignalR messages from other places in your app using the IHubContext service. You simply inject it where you need to use it.

To address your issue I would add a new method to INotificationHub:

public interface INotificationHub
{
    Task ExcecutingDailyPost(string action);
}

Inject your strongly typed hub context wherever you need to use hub functionality.

Your endpoint could then look like this:

public class DailyPostingController : ControllerBase
{
    private readonly IMapper _mapper;
    private readonly IDailyPostingService _DailyPostingService;
    private readonly ILogger<DailyPostingController> _logger;
    private readonly IHubContext<NotificationHub, INotificationHub> _hubContext;

    public DailyPostingController(IMapper mapper,
        IDailyPostingService DailyPostingService,
        ILogger<DailyPostingController> logger,
        IHubContext<NotificationHub, INotificationHub> hubContext)
    {
        _mapper = mapper;
        _DailyPostingService = DailyPostingService;
        _logger = logger;
        _hubContext = hubContext;
    }

    [Authorize(Policy = Permissions.DailyPosting.Execute)]
    [HttpPost("Execute")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<int> Execute(OperatingCentreQueryModel ocQueryModel)
    {
        _logger.LogDebug("Executing Daily posting for date#"
            + ocQueryModel.ProcessDate.ToString("dd/mmm/yyy"));

        // Notify your clients that the process has started
        await _hubContext.Clients.All.ExcecutingDailyPost("START");

        var res = await _DailyPostingService.Execute(ocQueryModel);

        // Notify your clients that the process has ended
        await _hubContext.Clients.All.ExcecutingDailyPost("END");
        return res;
    }
}

Then on the client side you need to listen on the "ExcecutingDailyPost" channel and depending on the action, do what you would like.


来源: stackexchange

问:
How to have two dependent actions within an ActionListener?
I'm trying to write a checkers AI program with a GUI in java. I've managed to initialise and fill the board so far (with pieces written as "B" and "W" for now). I've created a 2D JButton panel for the board.

I don't know how to proceed when moving pieces. My current issue is I need the player to select a preexisting piece (action 1) and then an empty space to place the selected piece (action 2). Of course these actions are dependent, and I need action 1 to happen first.

Here's what I've got so far:

```<code>import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

public class Checkers implements ActionListener{

        private static final int BOARD_SIZE = 8;

        Random random = new Random();
        JFrame frame = new JFrame();
        JPanel title_panel = new JPanel();
        JPanel button_panel = new JPanel();
        JLabel textfield = new JLabel();
        JButton[][] buttons = new JButton[BOARD_SIZE][BOARD_SIZE];

        Checkers(){
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(800,800);
            frame.getContentPane().setBackground(new Color(50, 50, 50));
            frame.setLayout(new BorderLayout());
            frame.setVisible(true);

            textfield.setBackground(new Color(25,25,25));
            textfield.setForeground(new Color(25, 255, 0));
            textfield.setFont(new Font("Arial", Font.BOLD, 75));
            textfield.setHorizontalAlignment(JLabel.CENTER);
            textfield.setText("Checkers");
            textfield.setOpaque(true);

            title_panel.setLayout(new BorderLayout());
            title_panel.setBounds(0,0,800, 100);
            button_panel.setLayout(new GridLayout(BOARD_SIZE,BOARD_SIZE));
            button_panel.setBackground(new Color(150,150,150));

            for (int i=0; i<BOARD_SIZE; i++){
                for (int j=0; j<BOARD_SIZE; j++){
                    buttons[i][j] = new JButton();
                    button_panel.add(buttons[i][j]);
                    buttons[i][j].setFont(new Font("Arial",Font.BOLD, 30));
                    buttons[i][j].setFocusable(false);
                    buttons[i][j].addActionListener(this);
                }
            }

            title_panel.add(textfield);
            frame.add(title_panel, BorderLayout.NORTH);
            frame.add(button_panel);
            initialiseBoard(buttons);
        }

    @Override
    public void actionPerformed(ActionEvent e) {
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                if (e.getSource() == buttons[i][j]) {
                    String moving_piece = buttons[i][j].getText();
                }
                }
            }
        }

    // method that fills the initial board.
    public void initialiseBoard(JButton[][] buttons){
        for (int i=0; i<BOARD_SIZE; i++){
            for (int j=0; j<BOARD_SIZE; j++){

                if (i<3){
                    if (i%2==0){
                        if (j%2 != 0){
                            buttons[i][j].setText("W");
                        }
                    }
                    else {
                        if (j%2==0){
                            buttons[i][j].setText("W");
                        }
                    }
                }
                if (i>=BOARD_SIZE-3){
                    if (i%2 == 0){
                        if (j%2 != 0){
                            buttons[i][j].setText("B");
                        }
                    }
                    else {
                        if (j%2==0){
                            buttons[i][j].setText("B");
                        }
                    }
                }
            }
        }
    }
}
</code>```

答:
You need to memorize and manage the selection of a piece. You can do it by:

```<code>//Introduce a field to store selected button
private JButton selected = null ;
</code>```

And modify the ActionListener:

```<code>@Override
public void actionPerformed(ActionEvent e) {

    JButton clicked = (JButton) e.getSource();
    if(selected != null ){
        clicked.setText(selected.getText());
        selected.setText("");
        selected = null;
    }else{
        if( ! clicked.getText().isEmpty()) {
            selected = clicked;
        }
    }
}
</code>```

Consider using JToggleButtons instead of a JButtons .

ContentLicense: CC BY-SA 4.0

Body:
I'm trying to write a checkers AI program with a GUI in java. I've managed to initialise and fill the board so far (with pieces written as "B" and "W" for now). I've created a 2D JButton panel for the board.

I don't know how to proceed when moving pieces. My current issue is I need the player to select a preexisting piece (action 1) and then an empty space to place the selected piece (action 2). Of course these actions are dependent, and I need action 1 to happen first.

Here's what I've got so far:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

public class Checkers implements ActionListener{

        private static final int BOARD_SIZE = 8;

        Random random = new Random();
        JFrame frame = new JFrame();
        JPanel title_panel = new JPanel();
        JPanel button_panel = new JPanel();
        JLabel textfield = new JLabel();
        JButton[][] buttons = new JButton[BOARD_SIZE][BOARD_SIZE];

        Checkers(){
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(800,800);
            frame.getContentPane().setBackground(new Color(50, 50, 50));
            frame.setLayout(new BorderLayout());
            frame.setVisible(true);

            textfield.setBackground(new Color(25,25,25));
            textfield.setForeground(new Color(25, 255, 0));
            textfield.setFont(new Font("Arial", Font.BOLD, 75));
            textfield.setHorizontalAlignment(JLabel.CENTER);
            textfield.setText("Checkers");
            textfield.setOpaque(true);

            title_panel.setLayout(new BorderLayout());
            title_panel.setBounds(0,0,800, 100);
            button_panel.setLayout(new GridLayout(BOARD_SIZE,BOARD_SIZE));
            button_panel.setBackground(new Color(150,150,150));

            for (int i=0; i<BOARD_SIZE; i++){
                for (int j=0; j<BOARD_SIZE; j++){
                    buttons[i][j] = new JButton();
                    button_panel.add(buttons[i][j]);
                    buttons[i][j].setFont(new Font("Arial",Font.BOLD, 30));
                    buttons[i][j].setFocusable(false);
                    buttons[i][j].addActionListener(this);
                }
            }

            title_panel.add(textfield);
            frame.add(title_panel, BorderLayout.NORTH);
            frame.add(button_panel);
            initialiseBoard(buttons);
        }

    @Override
    public void actionPerformed(ActionEvent e) {
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                if (e.getSource() == buttons[i][j]) {
                    String moving_piece = buttons[i][j].getText();
                }
                }
            }
        }

    // method that fills the initial board.
    public void initialiseBoard(JButton[][] buttons){
        for (int i=0; i<BOARD_SIZE; i++){
            for (int j=0; j<BOARD_SIZE; j++){

                if (i<3){
                    if (i%2==0){
                        if (j%2 != 0){
                            buttons[i][j].setText("W");
                        }
                    }
                    else {
                        if (j%2==0){
                            buttons[i][j].setText("W");
                        }
                    }
                }
                if (i>=BOARD_SIZE-3){
                    if (i%2 == 0){
                        if (j%2 != 0){
                            buttons[i][j].setText("B");
                        }
                    }
                    else {
                        if (j%2==0){
                            buttons[i][j].setText("B");
                        }
                    }
                }
            }
        }
    }
}

Body:
You need to memorize and manage the selection of a piece. You can do it by:

//Introduce a field to store selected button
private JButton selected = null ;

And modify the ActionListener:

@Override
public void actionPerformed(ActionEvent e) {

    JButton clicked = (JButton) e.getSource();
    if(selected != null ){
        clicked.setText(selected.getText());
        selected.setText("");
        selected = null;
    }else{
        if( ! clicked.getText().isEmpty()) {
            selected = clicked;
        }
    }
}

Consider using JToggleButtons instead of a JButtons .


问:
how to refresh content of already open infowindow of google maps when marker position is refreshed?
I have a google map and markers on it. Markers can move like vehicle tracking.I succeeded moving the markers according to new location data.There is no problem here.When clicking a marker, a infowindow which has location info (lng & ltd) is opened.But If marker move another location while infowindow is open, content(location info) of infowindow dont change.

How to change infowindow's content with new location info while marker moves?

Please help me to overcome the problem?

creating markers firstly is as follows;

```<code> var mapOptions = {
        zoom: 10,
        center: new google.maps.LatLng(37.2312, 36.9041),
        mapTypeId: google.maps.MapTypeId.SATELLITE,
        disableDefaultUI: false,
        zoomControl: true
    };
 var map = new google.maps.Map(document.getElementById('pnlMap'), mapOptions);
 var latlng = new google.maps.LatLng(coordinateInfo[1].replace(',', '.'), coordinateInfo[0].replace(',', '.'));
                    bounds.extend(latlng);

                    var marker = new google.maps.Marker({
                        position: latlng,
                        map: map,
                        icon: '../images/ship_icon.png',
                        store_id: coordinateInfo[3],
                        title: coordinateInfo[2]
                    });
                    markerList.push(marker);

                    (function (marker, coordinateInfo) {
                        google.maps.event.addListener(marker, "click", function (e) {
                            infoWindow.setContent(
                        '<div id="iw-container">' +
                            '<div class="iw-title">' + coordinateInfo[2] +
                                '<div class="iw-content">' +
                        '<table class="zebra"> <tr> <td><b>Gemi Adı : </b></td> <td>' + coordinateInfo[2] + '</td> </tr> <tr> <td><b>Cihaz ID Numarası : </b></td> <td>' + coordinateInfo[3] + '</td> </tr> <tr> <td><b>Koordinat Bilgileri(X,Y) : </b></td> <td>' + coordinateInfo[0] + ' - ' + coordinateInfo[1] + '</td> </tr> <tr> <td><b>Telefon Numarası : </b></td> <td>' + coordinateInfo[9] + '</td> </tr> <tr> <td><b>Telsiz Numarası : </b></td> <td></td> </tr> <tr> <td><b>Hız : </b></td> <td>' + coordinateInfo[6] + '</td> </tr> <tr> <td><b>Gps Zamanı : </b></td> <td>' + coordinateInfo[10] + '</td> </tr> <tr> <td><b>Konum : </b></td> <td>' + coordinateInfo[11] + '</td> </tr> </table>' +
                            '</div>' +
                        '</div>');
                            infoWindow.maxWidth = 380;
                            infoWindow.maxWidth = 380;
                            infoWindow.open(map, marker);
                        });
                    })(marker, coordinateInfo);

                    google.maps.event.addListener(map, 'click', function () {
                        infoWindow.close();
                    });
</code>```

updating markers' new position is as follows;

```<code>  for (var k = 0; k < coordinateLength - 1; k++) {
                    var coordinateInfoTemp = coordinates[k].split("~");
                    for (var j = 0; j < markerList.length; j++) {
                        var markerTmp = markerList[j];
                        if (markerTmp.store_id === coordinateInfoTemp[3]) {
                            var latlngNew = new google.maps.LatLng(coordinateInfoTemp[1].replace(',', '.'), coordinateInfoTemp[0].replace(',', '.'));
                            markerTmp.setPosition(latlngNew);
                            (function (markerTmp, coordinateInfoTemp) {
                                google.maps.event.addListener(markerTmp, "click", function (e) {
                                    alert(coordinateInfoTemp[10]);
                                    infoWindow.setContent(
                                                            '<div id="iw-container">' +
                                                                '<div class="iw-title">' + coordinateInfoTemp[2] +
                                                                    '<div class="iw-content">' +
                                                            '<table class="zebra"> <tr> <td><b>Gemi Adı : </b></td> <td>' + coordinateInfoTemp[2] + '</td> </tr> <tr> <td><b>Cihaz ID Numarası : </b></td> <td>' + coordinateInfoTemp[3] + '</td> </tr> <tr> <td><b>Koordinat Bilgileri : </b></td> <td>' + coordinateInfoTemp[0] + ' - ' + coordinateInfoTemp[1] + '</td> </tr> <tr> <td><b>Telefon Numarası : </b></td> <td>' + coordinateInfoTemp[9] + '</td> </tr> <tr> <td><b>Telsiz Numarası : </b></td> <td></td> </tr> <tr> <td><b>Hız : </b></td> <td>' + coordinateInfoTemp[6] + '</td> </tr> <tr> <td><b>Gps Zamanı : </b></td> <td>' + coordinateInfoTemp[10] + '</td> </tr> </table>' +
                                                                '</div>' +
                                                            '</div>');
                                    infoWindow.maxWidth = 380;
                                    infoWindow.refresh();
                                });
                            })(markerTmp, coordinateInfoTemp);
                            break;
                        }
                    }
                }
</code>```

Thanks in advance.

SOLUTION

I found the solution by adding following control, when I clicked a marker I am setting markerTmp.store_id to selectedMarkerStoreId variable;

```<code>if (selectedMarkerStoreId != null && selectedMarkerStoreId === markerTmp.store_id) {
                                    infoWindow.setContent(markerTmp.htmlContent);
                                }
</code>```

答:
Putting my findings here for future dev:

I was trying to update marker data and reflect the updated data on infowindow.

I tried different ways and found simply opening the infowindow reloads the data itself.

so I just triggered a click event on marker and it worked:

```<code>google.maps.event.trigger(marker, 'click')
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I have a google map and markers on it. Markers can move like vehicle tracking.I succeeded moving the markers according to new location data.There is no problem here.When clicking a marker, a infowindow which has location info (lng & ltd) is opened.But If marker move another location while infowindow is open, content(location info) of infowindow dont change.

How to change infowindow's content with new location info while marker moves?

Please help me to overcome the problem?

creating markers firstly is as follows;

 var mapOptions = {
        zoom: 10,
        center: new google.maps.LatLng(37.2312, 36.9041),
        mapTypeId: google.maps.MapTypeId.SATELLITE,
        disableDefaultUI: false,
        zoomControl: true
    };
 var map = new google.maps.Map(document.getElementById('pnlMap'), mapOptions);
 var latlng = new google.maps.LatLng(coordinateInfo[1].replace(',', '.'), coordinateInfo[0].replace(',', '.'));
                    bounds.extend(latlng);

                    var marker = new google.maps.Marker({
                        position: latlng,
                        map: map,
                        icon: '../images/ship_icon.png',
                        store_id: coordinateInfo[3],
                        title: coordinateInfo[2]
                    });
                    markerList.push(marker);

                    (function (marker, coordinateInfo) {
                        google.maps.event.addListener(marker, "click", function (e) {
                            infoWindow.setContent(
                        '
' +
                            '
' + coordinateInfo[2] +
                                '
' +
                        '

 Gemi Adı : 	 ' + coordinateInfo[2] + '

 Cihaz ID Numarası : 	 ' + coordinateInfo[3] + '

 Koordinat Bilgileri(X,Y) : 	 ' + coordinateInfo[0] + ' - ' + coordinateInfo[1] + '

 Telefon Numarası : 	 ' + coordinateInfo[9] + '

 Telsiz Numarası :

 Hız : 	 ' + coordinateInfo[6] + '

 Gps Zamanı : 	 ' + coordinateInfo[10] + '

 Konum : 	 ' + coordinateInfo[11] + '

' +
                            '
' +
                        '
');
                            infoWindow.maxWidth = 380;
                            infoWindow.maxWidth = 380;
                            infoWindow.open(map, marker);
                        });
                    })(marker, coordinateInfo);

                    google.maps.event.addListener(map, 'click', function () {
                        infoWindow.close();
                    });

updating markers' new position is as follows;

  for (var k = 0; k < coordinateLength - 1; k++) {
                    var coordinateInfoTemp = coordinates[k].split("~");
                    for (var j = 0; j < markerList.length; j++) {
                        var markerTmp = markerList[j];
                        if (markerTmp.store_id === coordinateInfoTemp[3]) {
                            var latlngNew = new google.maps.LatLng(coordinateInfoTemp[1].replace(',', '.'), coordinateInfoTemp[0].replace(',', '.'));
                            markerTmp.setPosition(latlngNew);
                            (function (markerTmp, coordinateInfoTemp) {
                                google.maps.event.addListener(markerTmp, "click", function (e) {
                                    alert(coordinateInfoTemp[10]);
                                    infoWindow.setContent(
                                                            '
' +
                                                                '
' + coordinateInfoTemp[2] +
                                                                    '
' +
                                                            '

 Gemi Adı : 	 ' + coordinateInfoTemp[2] + '

 Cihaz ID Numarası : 	 ' + coordinateInfoTemp[3] + '

 Koordinat Bilgileri : 	 ' + coordinateInfoTemp[0] + ' - ' + coordinateInfoTemp[1] + '

 Telefon Numarası : 	 ' + coordinateInfoTemp[9] + '

 Telsiz Numarası :

 Hız : 	 ' + coordinateInfoTemp[6] + '

 Gps Zamanı : 	 ' + coordinateInfoTemp[10] + '

' +
                                                                '
' +
                                                            '
');
                                    infoWindow.maxWidth = 380;
                                    infoWindow.refresh();
                                });
                            })(markerTmp, coordinateInfoTemp);
                            break;
                        }
                    }
                }

Thanks in advance.

SOLUTION

I found the solution by adding following control, when I clicked a marker I am setting markerTmp.store_id to selectedMarkerStoreId variable;

if (selectedMarkerStoreId != null && selectedMarkerStoreId === markerTmp.store_id) {
                                    infoWindow.setContent(markerTmp.htmlContent);
                                }

Body:
Putting my findings here for future dev:

I was trying to update marker data and reflect the updated data on infowindow.

I tried different ways and found simply opening the infowindow reloads the data itself.

so I just triggered a click event on marker and it worked:

google.maps.event.trigger(marker, 'click')


问:
How do I create a single list of object pairs from two lists in C#?
I have two lists of objects. List A and List B. I need to create List C which combines List A and List B into pairs. For example:</p>

```<code>List A
object a1
object a2
object a3

List B
object b1
object b2
object b3

List C (creates pairs)
object c1 (object a1, object b1)
object c2 (object a2, object b2)
object c3 (object a3, object b3)
</code>```

答:
You could use the Enumerable.Zip() method in System.Linq.

```<code>IEnumerable<Tuple<A, B>> pairs = listA.Zip(listB, (a, b) => Tuple.Create(a, b));
</code>```

Example using this resultant enumerable:

```<code>foreach (Tuple<A, B> pair in pairs)
{
    A a = pair.Item1;
    B b = pair.Item2;
}
</code>```

Shame there's not an overload that automates the tupleation in .NET. Such an extension would look like this:

```<code>public static IEnumerable<Tuple<TFirst, TSecond>> Zip<TFirst, TSecond>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second)
{
    return first.Zip(second, Tuple.Create);
}
</code>```

Which would mean you could then write code that looks like:

```<code>IEnumerable<Tuple<A, B>> pairs = listA.Zip(listB);
</code>```

Note: Another option would be to create anonymous types instead of Tuple but the downside to this approach is that you would not be able to (usefully) pass the resultant IEnumerable out of the method it is created in owing to the type not having a name.

Body:
I have two lists of objects. List A and List B. I need to create List C which combines List A and List B into pairs. For example:

List A
object a1
object a2
object a3

List B
object b1
object b2
object b3

List C (creates pairs)
object c1 (object a1, object b1)
object c2 (object a2, object b2)
object c3 (object a3, object b3)

Body:
You could use the Enumerable.Zip() method in System.Linq.

IEnumerable<Tuple<A, B>> pairs = listA.Zip(listB, (a, b) => Tuple.Create(a, b));

Example using this resultant enumerable:

foreach (Tuple<A, B> pair in pairs)
{
    A a = pair.Item1;
    B b = pair.Item2;
}

Shame there's not an overload that automates the tupleation in .NET. Such an extension would look like this:

public static IEnumerable<Tuple<TFirst, TSecond>> Zip<TFirst, TSecond>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second)
{
    return first.Zip(second, Tuple.Create);
}

Which would mean you could then write code that looks like:

IEnumerable<Tuple<A, B>> pairs = listA.Zip(listB);

Note: Another option would be to create anonymous types instead of Tuple but the downside to this approach is that you would not be able to (usefully) pass the resultant IEnumerable out of the method it is created in owing to the type not having a name.


问:
Is the for loop in my code the speed bottleneck?
The following code looks through 2500 markdown files with a total of 76475 lines, to check each one for the presence of two strings.

#!/usr/bin/env python3
# encoding: utf-8

import re
import os

zettelkasten = '/Users/will/Dropbox/zettelkasten'

def zsearch(s, *args):
    for x in args:
        r = (r"(?=.* " + x + ")")
        p = re.search(r, s, re.IGNORECASE)
        if p is None:
            return None
    return s

for filename in os.listdir(zettelkasten):
    if filename.endswith('.md'):
        with open(os.path.join(zettelkasten, filename),"r") as fp:
            for line in fp:
                result_line = zsearch(line, "COVID", "vaccine")
                if result_line != None:
                    UUID = filename[-15:-3]
                    print(f'›[[{UUID}]] OR', end=" ")
```
<p>This correctly gives output like:</p>
```›[[202202121717]] OR ›[[202003311814]] OR
```

, but it takes almost two seconds to run on my machine, which I think is much too slow. What, if anything, can be done to make it faster?

答:
The main bottleneck is the regular expressions you're building.

If we print(f"{r=}") inside the zsearch function:

```<code>>>> zsearch("line line covid line", "COVID", "vaccine")
r='(?=.* COVID)'
r='(?=.* vaccine)'
</code>```

The (?=.*) lookahead is what is causing the slowdown - and it's also not needed.

You can achieve the same result by searching for:

```<code>r=' COVID'
r=' vaccine'
</code>```

Body:
The following code looks through 2500 markdown files with a total of 76475 lines, to check each one for the presence of two strings.

#!/usr/bin/env python3
# encoding: utf-8

import re
import os

zettelkasten = '/Users/will/Dropbox/zettelkasten'

def zsearch(s, *args):
    for x in args:
        r = (r"(?=.* " + x + ")")
        p = re.search(r, s, re.IGNORECASE)
        if p is None:
            return None
    return s

for filename in os.listdir(zettelkasten):
    if filename.endswith('.md'):
        with open(os.path.join(zettelkasten, filename),"r") as fp:
            for line in fp:
                result_line = zsearch(line, "COVID", "vaccine")
                if result_line != None:
                    UUID = filename[-15:-3]
                    print(f'›[[{UUID}]] OR', end=" ")

This correctly gives output like:

›[[202202121717]] OR ›[[202003311814]] OR

, but it takes almost two seconds to run on my machine, which I think is much too slow. What, if anything, can be done to make it faster?

Body:
The main bottleneck is the regular expressions you're building.

If we print(f"{r=}") inside the zsearch function:

>>> zsearch("line line covid line", "COVID", "vaccine")
r='(?=.* COVID)'
r='(?=.* vaccine)'

The (?=.*) lookahead is what is causing the slowdown - and it's also not needed.

You can achieve the same result by searching for:

r=' COVID'
r=' vaccine'


问:
Possible ways to do one hot encoding in scikit-learn?
I have a pandas data frame with some categorical columns. Some of these contains non-integer values.

I currently want to apply several machine learning models on this data. With some models, it is necessary to do normalization to get better result. For example, converting categorical variable into dummy/indicator variables. Indeed, pandas has a function called get_dummies for that purpose. However, this function returns the result depending on the data. So if I call get_dummies on training data, then call it again on test data, columns achieved in two cases can be different because a categorical column in test data can contains just a sub-set/different set of possible values compared to possible values in training data.

Therefore, I am looking for other methods to do one-hot coding.

What are possible ways to do one hot encoding in python (pandas/sklearn)?

答:
For the text columns, you can try this

```<code>from sklearn.feature_extraction.text import CountVectorizer

data = ['he is good','he is bad','he is strong']
vectorizer = CountVectorizer()
vectors = vectorizer.fit_transform(data)
</code>```

For Output:

```<code>for i in range(len(data)):
    print(vectors[i, :].toarray())
</code>```

Output:

```<code>[[0 1 1 1 0]]
[[1 0 1 1 0]]
[[0 0 1 1 1]]
</code>```

Body:
For the text columns, you can try this

from sklearn.feature_extraction.text import CountVectorizer

data = ['he is good','he is bad','he is strong']
vectorizer = CountVectorizer()
vectors = vectorizer.fit_transform(data)

For Output:

for i in range(len(data)):
    print(vectors[i, :].toarray())

Output:

[[0 1 1 1 0]]
[[1 0 1 1 0]]
[[0 0 1 1 1]]


问:
Build is not working in react using vite bundler

I use web-pack before and wanted to change it to vite I copied all the file from the web-pack version to the vite version
when I issue yarn dev it work but we I build it and run the build with serve dist it give me this error on the browser and it won't render any thing

答:
You need to use this config, (take a look at @vitejs/plugin-react which you probably need to install)

vite.config.js:

```<code>import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";

export default ({ mode }) => {
  return defineConfig({
    plugins: [
      react(),
    ],
  });
};
</code>```

The thing is that vite does not import React by default into jsx components, so you need to do it manually in every component or use this plugin.

Body:
You need to use this config, (take a look at @vitejs/plugin-react which you probably need to install)

vite.config.js:

import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";

export default ({ mode }) => {
  return defineConfig({
    plugins: [
      react(),
    ],
  });
};

The thing is that vite does not import React by default into jsx components, so you need to do it manually in every component or use this plugin.


问:
I cannot understand why this code is wrong
```<code>class Solution:

    def firstRepeated(self,A, n):

        #arr : given array
        #n : size of the array

        D={}
        for i in range(n):
            if A[i] not in D:
                D[A[i]]=[i]
            else:
                D[A[i]].append(i)
        c=0
        for i in D:
            if(len(D[i])>1):
                c+=1
                return (D[i][0]+1)

        if(c==0): return -1

A=[1 ,5 ,3, 4, 3, 5, 6]

n=len(A)

M=Solution()

print(M.firstRepeated(A,n))
</code>```

this is a problem from geeks for geeks.
" Given an array arr[] of size n, find the first repeating element. The element should occurs more than once and the index of its first occurrence should be the smallest"

the index positions(returned) are assumed to start from 1. If there is no
such element that has frequency more than 1 , we gotta return -1

This code is actually working correctly in VS code, but whenever I use
it in GFG IDE, it's failing(shows 3 as output instead of 2)

Kindly help, as I have no idea what's wrong here.

答:
I checked in https://www.onlinegdb.com/online_python_compiler and works correctly.
it works also in https://ide.geeksforgeeks.org/

Body:
class Solution:

    def firstRepeated(self,A, n):

        #arr : given array
        #n : size of the array

        D={}
        for i in range(n):
            if A[i] not in D:
                D[A[i]]=[i]
            else:
                D[A[i]].append(i)
        c=0
        for i in D:
            if(len(D[i])>1):
                c+=1
                return (D[i][0]+1)

        if(c==0): return -1

A=[1 ,5 ,3, 4, 3, 5, 6]

n=len(A)

M=Solution()

print(M.firstRepeated(A,n))

this is a problem from geeks for geeks.
" Given an array arr[] of size n, find the first repeating element. The element should occurs more than once and the index of its first occurrence should be the smallest"

the index positions(returned) are assumed to start from 1. If there is no
such element that has frequency more than 1 , we gotta return -1

This code is actually working correctly in VS code, but whenever I use
it in GFG IDE, it's failing(shows 3 as output instead of 2)

Kindly help, as I have no idea what's wrong here.


问:
Problems opening modal bottom sheet
```<code>import 'package:expenses_app/widgets/new_transaction.dart';
import 'package:expenses_app/widgets/transaction_list.dart';
import 'models/transactions.dart';
import 'package:flutter/material.dart';

main() => runApp(ExpensesApp());

class ExpensesApp extends StatefulWidget {
  @override
  State<ExpensesApp> createState() => _ExpensesAppState();
}

class _ExpensesAppState extends State<ExpensesApp> {
  final List<Transactions> userTransactions = [
    Transactions(
      id: "t1",
      title: "New Shoes",
      amount: 69.99,
      date: DateTime.now(),
    ),
    Transactions(
      id: "t2",
      title: "Weekly Groceries",
      amount: 13.56,
      date: DateTime.now(),
    ),
  ];

  void addNewTransaction(String txTitle, double txAmount) {
    final newTx = Transactions(
      id: DateTime.now().toString(),
      title: txTitle,
      amount: txAmount,
      date: DateTime.now(),
    );

    setState(() {
      userTransactions.add(newTx);
    });
  }

  void startAddNewTransaction(BuildContext ctx) {
    showModalBottomSheet(
      context: ctx,
      builder: (_) {
        return NewTransactions(addNewTransaction);
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Expenses App"),
          backgroundColor: Colors.pink[900],
          actions: [
            IconButton(
              icon: Icon(Icons.add),
              onPressed: () => startAddNewTransaction(context),
            ),
          ],
        ),
        body: SingleChildScrollView(
          child: Column(
            children: [
              Container(
                width: double.infinity,
                child: Card(
                  child: Text("Chart"),
                ),
              ),
              TransactionList(userTransactions),
            ],
          ),
        ),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: () => startAddNewTransaction(context),
        ),
      ),
    );
  }
}
</code>```

Guys, i'm having a problem trying to create a modal in the floating action button and in   the app bar, i've already created the list that displays the transactions, the function that add a new transaction, and the function that create a modal,plus i've already deployed that function in the floating action button and app bar, but it's not working. What i'm i doing wrong?

答:
We can't tell what this 'NewTransactions' methods return because you shared incomplete code. ShowModalBottomSheet functions, on the other hand, must never return null.

I tried returning conatiner from showModalBottomSheet, and it worked perfectly.

```<code>showModalBottomSheet(
  context: ctx,
  builder: (_) {
     return Container(
       child: Text('This is bottom sheet'),
     );
  },
);
</code>```

Title: Problems opening modal bottom sheet

Body:
import 'package:expenses_app/widgets/new_transaction.dart';
import 'package:expenses_app/widgets/transaction_list.dart';
import 'models/transactions.dart';
import 'package:flutter/material.dart';

main() => runApp(ExpensesApp());

class ExpensesApp extends StatefulWidget {
  @override
  State<ExpensesApp> createState() => _ExpensesAppState();
}

class _ExpensesAppState extends State<ExpensesApp> {
  final List<Transactions> userTransactions = [
    Transactions(
      id: "t1",
      title: "New Shoes",
      amount: 69.99,
      date: DateTime.now(),
    ),
    Transactions(
      id: "t2",
      title: "Weekly Groceries",
      amount: 13.56,
      date: DateTime.now(),
    ),
  ];

  void addNewTransaction(String txTitle, double txAmount) {
    final newTx = Transactions(
      id: DateTime.now().toString(),
      title: txTitle,
      amount: txAmount,
      date: DateTime.now(),
    );

    setState(() {
      userTransactions.add(newTx);
    });
  }

  void startAddNewTransaction(BuildContext ctx) {
    showModalBottomSheet(
      context: ctx,
      builder: (_) {
        return NewTransactions(addNewTransaction);
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Expenses App"),
          backgroundColor: Colors.pink[900],
          actions: [
            IconButton(
              icon: Icon(Icons.add),
              onPressed: () => startAddNewTransaction(context),
            ),
          ],
        ),
        body: SingleChildScrollView(
          child: Column(
            children: [
              Container(
                width: double.infinity,
                child: Card(
                  child: Text("Chart"),
                ),
              ),
              TransactionList(userTransactions),
            ],
          ),
        ),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: () => startAddNewTransaction(context),
        ),
      ),
    );
  }
}

Guys, i'm having a problem trying to create a modal in the floating action button and in   the app bar, i've already created the list that displays the transactions, the function that add a new transaction, and the function that create a modal,plus i've already deployed that function in the floating action button and app bar, but it's not working. What i'm i doing wrong?

Body:
We can't tell what this 'NewTransactions' methods return because you shared incomplete code. ShowModalBottomSheet functions, on the other hand, must never return null.

I tried returning conatiner from showModalBottomSheet, and it worked perfectly.

showModalBottomSheet(
  context: ctx,
  builder: (_) {
     return Container(
       child: Text('This is bottom sheet'),
     );
  },
);


问:
How can I setup multiple websites via Docker on a Raspberry Pi?
I have created a couple of C# .NET 5 websites and deployed them via Kestrel to my Raspberry Pi. I am using Docker and the setup I have is:
Website1 - uses port 5000 and port 5001 (https)
Website2 - uses port 5002 and port 5003 (https)

I configured port forwarding on my router with a range from 5000 to 5050. This must be setup correctly since Website1 is accessible from outside my network just fine and external IP works fine.

I can access Website2 from any machine on my local network (using raspberrypi:5002) but if I try to access from a device not connected to my network (using external IP address and port 5002) then it fails to load. I noticed this error on the Pi:

Microsoft.AspNetCore.Antiforgery.DefaultAntiforgery[7]
An exception was thrown while deserializing the token.
Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException: The antiforgery token could not be decrypted.
---> System.Security.Cryptography.CryptographicException: The key {b0a63215-b1e3-42f7-8d5b-921be6ed3d1a} was not found in the key ring.

It seems strange this error appears but I probably don't understand it to be honest as I normally just write code. Can anybody please advise what the problem might be?

答:
To preven this you need to automatically validate

```<code> public void ConfigureServices(IServiceCollection services)
  {
    services.AddMvc(options =>
    {
        options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
    });
  }
</code>```

Cross-site request forgery (also known as XSRF or CSRF) is an attack against web-hosted apps whereby a malicious web app can influence the interaction between a client browser and a web app that trusts that browser. These attacks are possible because web browsers send some types of authentication tokens automatically with every request to a website. This form of exploit is also known as a one-click attack or session riding because the attack takes advantage of the user's previously authenticated session.

More info here - https://learn.microsoft.com/en-us/aspnet/core/security/anti-request-forgery?view=aspnetcore-5.0

https://andrewlock.net/automatically-validating-anti-forgery-tokens-in-asp-net-core-with-the-autovalidateantiforgerytokenattribute/

Optionally you can auto validate only for certain namespace -

options.TokenCookie.Expiration = TimeSpan.FromDays(365);                options.AutoValidateIgnoredHttpMethods.Remove("GET");
options.AutoValidateFilter =type => !type.Namespace.StartsWith("App.Namespace.Name");

Body:
To preven this you need to automatically validate

 public void ConfigureServices(IServiceCollection services)
  {
    services.AddMvc(options =>
    {
        options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
    });
  }

Cross-site request forgery (also known as XSRF or CSRF) is an attack against web-hosted apps whereby a malicious web app can influence the interaction between a client browser and a web app that trusts that browser. These attacks are possible because web browsers send some types of authentication tokens automatically with every request to a website. This form of exploit is also known as a one-click attack or session riding because the attack takes advantage of the user's previously authenticated session.

More info here - https://learn.microsoft.com/en-us/aspnet/core/security/anti-request-forgery?view=aspnetcore-5.0

https://andrewlock.net/automatically-validating-anti-forgery-tokens-in-asp-net-core-with-the-autovalidateantiforgerytokenattribute/

Optionally you can auto validate only for certain namespace -

options.TokenCookie.Expiration = TimeSpan.FromDays(365);                options.AutoValidateIgnoredHttpMethods.Remove("GET");
options.AutoValidateFilter =type => !type.Namespace.StartsWith("App.Namespace.Name");


问:
How to round a Double to the nearest Int in swift?
I'm trying to make a calculator of growth rate (Double) that will round the result to the nearest Integer and recalculate from there, as such:

```<code>let firstUsers = 10.0
let growth = 0.1
var users = firstUsers
var week = 0

while users < 14 {
    println("week \(week) has \(users) users")
    users += users * growth
    week += 1
}
</code>```

but I've been unable so far.

EDIT
I kinda did it like so:

```<code>var firstUsers = 10.0
let growth = 0.1
var users:Int = Int(firstUsers)
var week = 0

while users <= 14 {
    println("week \(week) has \(users) users")
    firstUsers += firstUsers * growth
    users = Int(firstUsers)
    week += 1
}
</code>```

Although I don't mind that it is always rounding down, I don't like it because firstUsers had to become a variable and change throughout the program (in order to make the next calculation), which I don't want it to happen.

答:
This is the easiest way I came across

```<code>let weightValue = 143.69
print("Rounded off weight value = \(Int(weightValue))")
</code>```

Alternate method:

```<code>print("Rounded off weight value = \((String(format: "%.0f", sender.value)))")
</code>```

Body:
I'm trying to make a calculator of growth rate (Double) that will round the result to the nearest Integer and recalculate from there, as such:

let firstUsers = 10.0
let growth = 0.1
var users = firstUsers
var week = 0

while users < 14 {
    println("week \(week) has \(users) users")
    users += users * growth
    week += 1
}

but I've been unable so far.

EDIT
I kinda did it like so:

var firstUsers = 10.0
let growth = 0.1
var users:Int = Int(firstUsers)
var week = 0

while users <= 14 {
    println("week \(week) has \(users) users")
    firstUsers += firstUsers * growth
    users = Int(firstUsers)
    week += 1
}

Although I don't mind that it is always rounding down, I don't like it because firstUsers had to become a variable and change throughout the program (in order to make the next calculation), which I don't want it to happen.

Body:
This is the easiest way I came across

let weightValue = 143.69
print("Rounded off weight value = \(Int(weightValue))")

Alternate method:

print("Rounded off weight value = \((String(format: "%.0f", sender.value)))")


问:
Export screenshot of aws cloudwatch dasbhoard
I created a cloudwatch dashboard to monitor CPU and other stats. Is there a way how I can export a screenshot of the dashboard from the console or by API call? Below is a sample dashboard made by manual screenshot.

答:
If you need the raw png image, you'll need to decode the response by doing something like this:

```<code>aws cloudwatch get-metric-widget-image --metric-widget 'JSON_GOES_HERE' \
| grep MetricWidgetImage \
| awk '{split($0,a,"\""); print a[4]}' \
| base64 --decode > graph.png
</code>```

Ref - https://www.semicolonworld.com/question/79079/how-to-use-aws-cloudwatch-get-metric-widget-image

Body:
If you need the raw png image, you'll need to decode the response by doing something like this:

aws cloudwatch get-metric-widget-image --metric-widget 'JSON_GOES_HERE' \
| grep MetricWidgetImage \
| awk '{split($0,a,"\""); print a[4]}' \
| base64 --decode > graph.png

Ref - https://www.semicolonworld.com/question/79079/how-to-use-aws-cloudwatch-get-metric-widget-image


问:
How can I tail dmesg
I am using Ubuntu 20.04.3 LTS. I am trying to monitor the serial port connect with my Arduino.
I have seen my friend using the following command (he performed it in my laptop):

```<code>tail -f {dmesg,syslog} | grep -i tty
</code>```

And whenever I plugin and unplug the arduino, the terminal always keep up showing serial port name, its condition. But when I try it myself, it says that there is not such file or directory. I have search and tried following command:

```<code>tail -f var/log/dmesg
tail -f var/log/{dmesg,syslog}
</code>```

But it seems like it does not show up the serial port or keep up with condition. Would you help me with any ideas?

答:
You can use

```<code>dmesg -W | grep -i tty
</code>```

-w, --follow

Wait for new messages. This feature is supported only on systems with a readable /dev/kmsg (since kernel 3.5.0).

So Output will be something like this

```<code>rexter@rexter:/media/rexter/REXDRIVE$ dmesg -w | grep -i tty
[    0.112876] printk: console [tty0] enabled
[  332.500320] Bluetooth: RFCOMM TTY layer initialized
</code>```

If you want to get only new message and want to hide the old ones then use -W

-W, --follow-new

Wait and print only new messages.

Bonus:
Use -T to get the time stamp so that you can get the time when you receive the log.

Thank you :)

Title: How can I tail dmesg

Body:
I am using Ubuntu 20.04.3 LTS. I am trying to monitor the serial port connect with my Arduino.
I have seen my friend using the following command (he performed it in my laptop):

tail -f {dmesg,syslog} | grep -i tty

And whenever I plugin and unplug the arduino, the terminal always keep up showing serial port name, its condition. But when I try it myself, it says that there is not such file or directory. I have search and tried following command:

tail -f var/log/dmesg
tail -f var/log/{dmesg,syslog}

But it seems like it does not show up the serial port or keep up with condition. Would you help me with any ideas?

Body:
You can use

dmesg -W | grep -i tty

-w, --follow

Wait for new messages. This feature is supported only on systems with a readable /dev/kmsg (since kernel 3.5.0).

So Output will be something like this

rexter@rexter:/media/rexter/REXDRIVE$ dmesg -w | grep -i tty
[    0.112876] printk: console [tty0] enabled
[  332.500320] Bluetooth: RFCOMM TTY layer initialized

If you want to get only new message and want to hide the old ones then use -W

-W, --follow-new

Wait and print only new messages.

Bonus:
Use -T to get the time stamp so that you can get the time when you receive the log.

Thank you :)


问:
How to trigger click event of anchor tag via jQuery for dynamic data?
Trying to trigger click event of a tag with jQuery but the event is linked with data set by $.getJSON in a section.

Following is the code of HTML:

...

const page=1, dataList=[];
$.getJSON('https://api.punkapi.com/v2/beers?page=' + page + '&per_page=25', function (beerList) {
        console.log(beerList)
        dataList.push(beerList);
        currentElements = renderFuntion(beerList);
        $('#dynamicData').html(currentElements);
    });

 function renderFuntion(data) {
    var temp = '';
    data.forEach(element => {
        var item = `

${element.name}

${element.description.length > 220 ? element.description.substring(0, 220) + '...' : element.description}

`
        temp += item;
    });
    return temp;
}

//this is what's not working
 $('.card a').click(function () {
    var usersid = $(this).attr("id");
    favouritesList.push(usersid);
    console.log(favouritesList);

});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js"></script>
<section class="my-3 g-0" id="dynamicData">
</section></code>```

Please do guide if possible. Thanks.

答:
To access a dynamic element via click event you have to use something like this $(document).on('click','elementName',function(){})

I have made some minor changes and hope that they are what you are looking for. Happy coding!

var favouritesList = [];
const page=1, dataList=[];
$.getJSON('https://api.punkapi.com/v2/beers?page=' + page + '&per_page=25', function (beerList) {
        dataList.push(beerList);
        currentElements = renderFuntion(beerList);
        $('#dynamicData').html(currentElements);
    });

 function renderFuntion(data) {
    var temp = '';
    data.forEach(element => {
        var item = `

${element.name}

${element.description.length > 220 ? element.description.substring(0, 220) + '...' : element.description}

              User Icon

`
        temp += item;
    });
    return temp;
}

//I've changed the way you are trying to get that ID from the anchor tag
 $(document).on('click','a',function () {
    var usersid = $(this).attr("id");
    favouritesList.push(usersid);
    console.log(favouritesList);

});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="my-3 g-0" id="dynamicData">
</section></code>```

Body:
Trying to trigger click event of a tag with jQuery but the event is linked with data set by $.getJSON in a section.

Following is the code of HTML:

...

const page=1, dataList=[];
$.getJSON('https://api.punkapi.com/v2/beers?page=' + page + '&per_page=25', function (beerList) {
        console.log(beerList)
        dataList.push(beerList);
        currentElements = renderFuntion(beerList);
        $('#dynamicData').html(currentElements);
    });

 function renderFuntion(data) {
    var temp = '';
    data.forEach(element => {
        var item = `

${element.name}

${element.description.length > 220 ? element.description.substring(0, 220) + '...' : element.description}

`
        temp += item;
    });
    return temp;
}

//this is what's not working
 $('.card a').click(function () {
    var usersid = $(this).attr("id");
    favouritesList.push(usersid);
    console.log(favouritesList);

});

Please do guide if possible. Thanks.

Body:
To access a dynamic element via click event you have to use something like this $(document).on('click','elementName',function(){})

I have made some minor changes and hope that they are what you are looking for. Happy coding!

var favouritesList = [];
const page=1, dataList=[];
$.getJSON('https://api.punkapi.com/v2/beers?page=' + page + '&per_page=25', function (beerList) {
        dataList.push(beerList);
        currentElements = renderFuntion(beerList);
        $('#dynamicData').html(currentElements);
    });

 function renderFuntion(data) {
    var temp = '';
    data.forEach(element => {
        var item = `
        <div class="card col-xs-12 col-lg-4 my-2">
            <div class="card-body">
                   <figure> <img src=${element.image_url} class="img-fluid" alt=${element.name}></figure>
            <article class="ms-3">
                    <h5 class="card-title">${element.name}</h5>
                    <p class="card-text">${element.description.length > 220 ? element.description.substring(0, 220) + '...' : element.description}</p>
             </article>
<!--- This is what's suppose to give the event on click. --->
            <a href="javascript:void(0)"  id=${element.id}> <i class="fa fa-star-o usericon mt-3"></i> User Icon</a>
            </div>
        </div>`
        temp += item;
    });
    return temp;
}

//I've changed the way you are trying to get that ID from the anchor tag
 $(document).on('click','a',function () {
    var usersid = $(this).attr("id");
    favouritesList.push(usersid);
    console.log(favouritesList);

});

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="my-3 g-0" id="dynamicData">
</section>


问:
Share image on whatsapp from react native android app
I am currently working on react-native photo sharing app for Android. Used native share method but it only share message and title. No options to share an image.

Looking after so many questions here couldn't find any straight forward way.

Please provide help.

This is the message I am getting Share awesome status on whatsapp using Khela #imageurl. Download #urltoplaystore

答:
```<code>import Icon from 'react-native-vector-icons/Feather';
import Share from 'react-native-share';
import RNFetchBlob from 'rn-fetch-blob';
import React, {Component} from 'react';

const fs = RNFetchBlob.fs;
class ProductDetail extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

shareTheProductDetails(imagesPath) {
    let {productDetails} = this.state;
    let imagePath = null;
    RNFetchBlob.config({
      fileCache: true,
    })
      .fetch('GET', imagesPath.image)
      // the image is now dowloaded to device's storage
      .then((resp) => {
        // the image path you can use it directly with Image component
        imagePath = resp.path();
        return resp.readFile('base64');
      })
      .then((base64Data) => {
        // here's base64 encoded image
        var imageUrl = 'data:image/png;base64,' + base64Data;
        let shareImage = {
          title: productDetails.product_name, //string
          message:
            'Description ' +
            productDetails.product_description +
            ' http://beparr.com/', //string
          url: imageUrl,
          // urls: [imageUrl, imageUrl], // eg.'http://img.gemejo.com/product/8c/099/cf53b3a6008136ef0882197d5f5.jpg',
        };
        Share.open(shareImage)
          .then((res) => {
            console.log(res);
          })
          .catch((err) => {
            err && console.log(err);
          });
        // remove the file from storage
        return fs.unlink(imagePath);
      });
  }

render() {
return (
<TouchableOpacity
style={{
  borderWidth: 0,
  left:(5),
  top:(2),
}}
onPress={() =>
  this.shareTheProductDetails(images)
}>
<Icon
   style={{
     left: moderateScale(10),
   }}
  name="share-2"
  color={colors.colorBlack}
  size={(20)}
/>
</TouchableOpacity>
)}
}
</code>```


问:
woocommerce_add_to_cart_validation in ajax
I use this hook to add a custom field to woocommerce single products pages:

```<code>function ardv_display_product_custom_form() {

    echo '<input type="text" id="first-name" name="first-name" value="">';

}
add_action( 'woocommerce_before_add_to_cart_button', 'ardv_display_product_custom_form' );
</code>```

and then this hook to validate my input:

```<code>function ardv_custom_forms_inputs_validation( $passed, $product_id, $quantity ) {

    if( isset( $_POST['first-name'] ) && empty( $_POST['first-name'] ) ) {
        $passed = false;
        wc_add_notice( __( 'Please enter your first name.', 'simple' ), 'error' );
    }
    return $passed;

}
add_filter( 'woocommerce_add_to_cart_validation', 'ardv_custom_forms_inputs_validation', 10, 3 );
</code>```

It's working with no problem. But when I click on add to cart button the product page refresh and then the error massages appear. is there any way to do this in ajax without refreshing the page?

答:
In case somybody else face this problem:
I used jquery validate instead of using woocommerce_add_to_cart_validation hook.</p>

Body:
I use this hook to add a custom field to woocommerce single products pages:

function ardv_display_product_custom_form() {

    echo '<input type="text" id="first-name" name="first-name" value="">';

}
add_action( 'woocommerce_before_add_to_cart_button', 'ardv_display_product_custom_form' );

and then this hook to validate my input:

function ardv_custom_forms_inputs_validation( $passed, $product_id, $quantity ) {

    if( isset( $_POST['first-name'] ) && empty( $_POST['first-name'] ) ) {
        $passed = false;
        wc_add_notice( __( 'Please enter your first name.', 'simple' ), 'error' );
    }
    return $passed;

}
add_filter( 'woocommerce_add_to_cart_validation', 'ardv_custom_forms_inputs_validation', 10, 3 );

It's working with no problem. But when I click on add to cart button the product page refresh and then the error massages appear. is there any way to do this in ajax without refreshing the page?


问:
How to merge objects of arrays? mixed key
```<code>  [
        {
            "_id": "6205576aaa478f466cca3809",
            "age": 51,
            "createdAt": "2022-02-10T18:20:26.451Z",
        },
        {
            "score": [
                0,
                1,
                3,
                1,
                0,
                2
            ],
            "_id": "62081d1bc83c452ef8e34e47",
            "key_findings": "Lorem ipsum",
            "subject": "6205576aaa478f466cca3809",
            "createdAt": "2022-02-12T20:48:27.574Z",
        }
    ]
</code>```

What I want it to look like:

```<code>[
  {
    _id: 6205576aaa478f466cca3809,
    age: 51,
    createdAt: 2022-02-10T18:20:26.451Z,
    score: [ 0, 1, 3, 1, 0, 2 ],
    _id: 62081d1bc83c452ef8e34e47,
    description: 'XR CHEST AP PORTABLE',
    key_findings: 'Lorem impusm',
    subject: 6205576aaa478f466cca3809,
    createdAt: 2022-02-12T20:48:27.574Z,
  }
]
</code>```

I tried everything I can. There are many examples on the internet but that works only if the object's keys are the same.

答:
You would use object spread in the iteration of the array:

```<code>let merged={}
arr.map(item=> merged={...merged,...item})
</code>```

"arr" is your array and merged is your expected answer

Body:
  [
        {
            "_id": "6205576aaa478f466cca3809",
            "age": 51,
            "createdAt": "2022-02-10T18:20:26.451Z",
        },
        {
            "score": [
                0,
                1,
                3,
                1,
                0,
                2
            ],
            "_id": "62081d1bc83c452ef8e34e47",
            "key_findings": "Lorem ipsum",
            "subject": "6205576aaa478f466cca3809",
            "createdAt": "2022-02-12T20:48:27.574Z",
        }
    ]

What I want it to look like:

[
  {
    _id: 6205576aaa478f466cca3809,
    age: 51,
    createdAt: 2022-02-10T18:20:26.451Z,
    score: [ 0, 1, 3, 1, 0, 2 ],
    _id: 62081d1bc83c452ef8e34e47,
    description: 'XR CHEST AP PORTABLE',
    key_findings: 'Lorem impusm',
    subject: 6205576aaa478f466cca3809,
    createdAt: 2022-02-12T20:48:27.574Z,
  }
]

I tried everything I can. There are many examples on the internet but that works only if the object's keys are the same.

Body:
You would use object spread in the iteration of the array:

let merged={}
arr.map(item=> merged={...merged,...item})

"arr" is your array and merged is your expected answer


问:
Q: how to make use of Alpinejs and tailwindcss within Laravel?
I am trying to make use of Alpinejs using Adam Wathan's responsive navbar  using vuejs, but i am experimenting if i can get it to work with Alpinejs.

```<code>app.blade.php

<head>

  [...]

      <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>

  [...]

</head>
</code>```

In case you are wondering if Alpine is already loaded, it is working trying a simple dropdown toggle, but with this approach i find it hard to get it working.

```<code>Navbar.blade.php

@guest('applicant')
@else
<header class="bg-gray-900 sm:flex sm:items-center sm:justify-between xl:bg-white" x-data="dropdown()">
  <div class="flex justify-between px-4 py-3 xl:w-72 xl:bg-gray-900 xl:justify-center xl:py-5">
    <div>
      [...]
    </div>
    <div class="flex sm:hidden">
      <button x-on:click="open" type="button"
        class="px-2 text-gray-500 hover:text-white focus:outline-none focus:text-white">
        <svg class="h-6 w-6 fill-current" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
          <path x-if="isOpen" fill-rule="evenodd" clip-rule="evenodd"
            d="M18.278 16.864a1 1 0 0 1-1.414 1.414l-4.829-4.828-4.828 4.828a1 1 0 0 1-1.414-1.414l4.828-4.829-4.828-4.828a1 1 0 0 1 1.414-1.414l4.829 4.828 4.828-4.828a1 1 0 1 1 1.414 1.414l-4.828 4.829 4.828 4.828z" />
          <path x-if="!isOpen" fill-rule="evenodd"
            d="M4 5h16a1 1 0 0 1 0 2H4a1 1 0 1 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2z" />
        </svg>
      </button>
    </div>
  </div>
  <nav class="sm:flex sm:items-center sm:px-4 xl:flex-1 xl:justify-between"
    :class="{ 'hidden': !isOpen, 'block': isOpen }" x-show="open" x-on:click.away="close">
    <div class="hidden xl:block xl:relative xl:max-w-xs xl:w-full">
      [...]
    </div>
    <div class="sm:flex sm:items-center">
      [...]
      <div class="relative px-5 py-5 sm:py-0 sm:ml-4 sm:px-0">
        [...]
        <Dropdown class="hidden sm:block">
          <template #trigger="{ hasFocus, isOpen }">
            <span class="block h-8 w-8 overflow-hidden rounded-full border-2 "
              :class="[(hasFocus || isOpen) ? 'border-white xl:border-indigo-500' : 'border-gray-600 xl:border-gray-300']">
              <img class="h-full w-full object-cover"
                src="https://images.unsplash.com/photo-1487412720507-e7ab37603c6f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=256&q=80"
                alt="">
            </span>
          </template>
          <template #dropdown>
            <div class="mt-3 bg-white xl:border rounded-lg w-48 py-2 shadow-xl">
              <a href="#account" class="block hover:text-white text-gray-800 px-4 py-2 hover:bg-indigo-500">Account
                settings</a>
              <a href="#support"
                class="block hover:text-white text-gray-800 mt-0 px-4 py-2 hover:bg-indigo-500">Support</a>
              <a href="#sign-out" class="block hover:text-white text-gray-800 mt-0 px-4 py-2 hover:bg-indigo-500">Sign
                out</a>
            </div>
          </template>
        </Dropdown>
      </div>
    </div>
  </nav>
</header>

<script>
function dropdown() {
  return {
    open: false,
    open() {
      this.show = true
    },
    close() {
      this.show = false
    },
    toggle() {
      this.isOpen = !this.isOpen
    },
  }
}
</script>
@endguest

</code>```

答:
In my case i didn't my javascript nor installed it, i just used the cdn

```<code> {{-- scrip --}}
    <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
</code>```

and had installed tailwind css. my code is..

```<code>                    <div x-data="{dropdownMenu: false}" class="lg:inline-block relative">
                        <!-- Dropdown toggle button -->
                        <button @click="dropdownMenu = ! dropdownMenu"
                            class="text-base no-underline   hover:bg-indigo-300 hover:text-cool-gray-900 rounded-3xl  py-1 px-2 ">
                            <span class="sr-only">{{ Auth::user()->name }}</span>
                            <img class="h-8 w-8 rounded-full"
                                src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=4&w=256&h=256&q=60"
                                alt="avatar">
                        </button>
                        <!-- Dropdown list -->
                        <div x-show="dropdownMenu"
                            class="absolute right-0 py-2 mt-2 bg-white bg-gray-100 rounded-md shadow-xl w-44">
                            <a href="#"
                                class="block px-4 py-2 text-sm text-gray-300 text-gray-700 hover:bg-gray-400 hover:text-white">
                                Your Profile
                            </a>

                            <a href="#"
                                class="block px-4 py-2 text-sm text-gray-300 text-gray-700 hover:bg-gray-400 hover:text-white">
                                Settings
                            </a>
                            <a href="#"
                                class="block px-4 py-2 text-sm text-gray-300 text-gray-700 hover:bg-gray-400 hover:text-white">
                                Reports
                            </a>
                            <a href="{{ route('logout') }}"
                                class="block px-4 py-2 text-sm text-gray-300 text-gray-700 hover:bg-gray-400 hover:text-white"
                                onclick="event.preventDefault();document.getElementById('logout-form').submit();">{{ __('Logout') }}</a>
                            <form id="logout-form" action="{{ route('logout') }}" method="POST"
                                class="hidden">
                                {{ csrf_field() }}
                            </form>
                        </div>
                    </div>
</code>```

this was my result when i click the avatar..

i hope this will assist you solve your problem

Body:
I am trying to make use of Alpinejs using Adam Wathan's responsive navbar  using vuejs, but i am experimenting if i can get it to work with Alpinejs.

app.blade.php

  [...]

  [...]

In case you are wondering if Alpine is already loaded, it is working trying a simple dropdown toggle, but with this approach i find it hard to get it working.

Navbar.blade.php

@guest('applicant')
@else

      [...]

      <button x-on:click="open" type="button"
        class="px-2 text-gray-500 hover:text-white focus:outline-none focus:text-white">
        <svg class="h-6 w-6 fill-current" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
          <path x-if="isOpen" fill-rule="evenodd" clip-rule="evenodd"
            d="M18.278 16.864a1 1 0 0 1-1.414 1.414l-4.829-4.828-4.828 4.828a1 1 0 0 1-1.414-1.414l4.828-4.829-4.828-4.828a1 1 0 0 1 1.414-1.414l4.829 4.828 4.828-4.828a1 1 0 1 1 1.414 1.414l-4.828 4.829 4.828 4.828z" />
          <path x-if="!isOpen" fill-rule="evenodd"
            d="M4 5h16a1 1 0 0 1 0 2H4a1 1 0 1 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2z" />
        </svg>
      </button>

      [...]

      [...]

        [...]
        <Dropdown class="hidden sm:block">
          <template #trigger="{ hasFocus, isOpen }">

          </template>
          <template #dropdown>

              Account
                settings
              Support
              Sign
                out

          </template>
        </Dropdown>

@endguest

Body:
In my case i didn't my javascript nor installed it, i just used the cdn

 {{-- scrip --}}
    <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>

and had installed tailwind css. my code is..

                    <div x-data="{dropdownMenu: false}" class="lg:inline-block relative">
                        <!-- Dropdown toggle button -->
                        <button @click="dropdownMenu = ! dropdownMenu"
                            class="text-base no-underline   hover:bg-indigo-300 hover:text-cool-gray-900 rounded-3xl  py-1 px-2 ">
                            <span class="sr-only">{{ Auth::user()->name }}</span>
                            <img class="h-8 w-8 rounded-full"
                                src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&amp;ixid=eyJhcHBfaWQiOjEyMDd9&amp;auto=format&amp;fit=facearea&amp;facepad=4&amp;w=256&amp;h=256&amp;q=60"
                                alt="avatar">
                        </button>
                        <!-- Dropdown list -->
                        <div x-show="dropdownMenu"
                            class="absolute right-0 py-2 mt-2 bg-white bg-gray-100 rounded-md shadow-xl w-44">
                            <a href="#"
                                class="block px-4 py-2 text-sm text-gray-300 text-gray-700 hover:bg-gray-400 hover:text-white">
                                Your Profile
                            </a>

                            <a href="#"
                                class="block px-4 py-2 text-sm text-gray-300 text-gray-700 hover:bg-gray-400 hover:text-white">
                                Settings
                            </a>
                            <a href="#"
                                class="block px-4 py-2 text-sm text-gray-300 text-gray-700 hover:bg-gray-400 hover:text-white">
                                Reports
                            </a>
                            <a href="{{ route('logout') }}"
                                class="block px-4 py-2 text-sm text-gray-300 text-gray-700 hover:bg-gray-400 hover:text-white"
                                onclick="event.preventDefault();document.getElementById('logout-form').submit();">{{ __('Logout') }}</a>
                            <form id="logout-form" action="{{ route('logout') }}" method="POST"
                                class="hidden">
                                {{ csrf_field() }}
                            </form>
                        </div>
                    </div>

this was my result when i click the avatar..

i hope this will assist you solve your problem


问:
Jq strftime() to show time in a specific time zone
How to use jq to convert seconds since Unix epoch to a time string in human readable format but adjusted to Sydney, Australia time zone?

I tried filter:

```<code>now | strftime("%Y-%m-%dT%H:%M:%SZ")
</code>```

But I don't know how to adjust the time format string to convey Sydney, Australia time zone.

Possibly I need to replace "Z" with the relevant time zone?

答:
Both of the following convert to the time zone indicated by the TZ environment variable var:

```<code>localtime | strftime(...)
</code>```
```<code>strflocaltime(...)
</code>```

For example,

$ jq -nr 'now | strftime("%FT%T")'
2022-02-14T06:14:07

$ jq -nr 'now | gmtime | strftime("%FT%T")'
2022-02-14T06:14:07

$ jq -nr 'now | localtime | strftime("%FT%T")'
2022-02-14T02:14:07

$ jq -nr 'now | strflocaltime("%FT%T")'
2022-02-14T02:14:07
```
<p>That uses your local time, as determined by <code>TZ</code> environment variable. Adjust as needed.</p>
<pre class="lang-none prettyprint-override"><code>$ TZ=America/Halifax jq -nr 'now | strflocaltime("%FT%T")'
2022-02-14T02:14:07

$ TZ=America/Toronto jq -nr 'now | strflocaltime("%FT%T")'
2022-02-14T01:14:07

$ TZ=America/Vancouver jq -nr 'now | strflocaltime("%FT%T")'
2022-02-14T22:14:07
</code>```

If you want to convert to different time zones in a single run of jq, you're out of luck. jq doesn't support converting to/from time zones other than UTC and this time zone.

Tested with both 1.5 and 1.6.

Body:
How to use jq to convert seconds since Unix epoch to a time string in human readable format but adjusted to Sydney, Australia time zone?

I tried filter:

now | strftime("%Y-%m-%dT%H:%M:%SZ")

But I don't know how to adjust the time format string to convey Sydney, Australia time zone.

Possibly I need to replace "Z" with the relevant time zone?

Body:
Both of the following convert to the time zone indicated by the TZ environment variable var:

localtime | strftime(...)

strflocaltime(...)

For example,

$ jq -nr 'now | strftime("%FT%T")'
2022-02-14T06:14:07

$ jq -nr 'now | gmtime | strftime("%FT%T")'
2022-02-14T06:14:07

$ jq -nr 'now | localtime | strftime("%FT%T")'
2022-02-14T02:14:07

$ jq -nr 'now | strflocaltime("%FT%T")'
2022-02-14T02:14:07

That uses your local time, as determined by TZ environment variable. Adjust as needed.

$ TZ=America/Halifax jq -nr 'now | strflocaltime("%FT%T")'
2022-02-14T02:14:07

$ TZ=America/Toronto jq -nr 'now | strflocaltime("%FT%T")'
2022-02-14T01:14:07

$ TZ=America/Vancouver jq -nr 'now | strflocaltime("%FT%T")'
2022-02-14T22:14:07

If you want to convert to different time zones in a single run of jq, you're out of luck. jq doesn't support converting to/from time zones other than UTC and this time zone.

Tested with both 1.5 and 1.6.


问:
Match strings in two columns with the highest string similiarity ratio-pandas
I have two dataframes:

```<code>import pandas as pd
df1 = pd.DataFrame({'Index': [1, 2, 3, 4, 5],
                   'name1': ['A brewery', 'B fresh produce', '100 wines', 'C canzirri ', 'D company']})

df2 = pd.DataFrame({'Index': [1, 2, 3, 4, 5, 6, 7],
                   'name2': ['bvb breweries', 'A brewerIES', 'BBBB fresh produce', '100 wines', 'f C canzirri ', 'Dcompany', 'b fresh produce']})
</code>```

I want to generate new column df1.similar, for each df1.name1 value, the df1.similar is the corresponding value from df2.name2 with the highest similarity ratio.

The  df1.ratio  contains the highest similarity ratio.

For example:

```<code>from difflib import SequenceMatcher

def similiarity_ratio(a, b):
    return SequenceMatcher(None, a, b).ratio()

s=[]
for i in df2['name2']:
  s.append(similiarity_ratio('A brewery',i))
max(s)
</code>```

The desirable output will set 'A brewerIES' (in df2.name2) to df1.similar, 0.8 to df1.ratio.

How can I apply/lamda to do it cross all values in df1.name1 ?

答:
Hi i have had a try by myself. Silly but seems ok.

```<code>import pandas as pd
from difflib import SequenceMatcher

def compare(a):
    compare={}
    for i in df2['name2']:
        compare.update({i: SequenceMatcher(None, a, i).ratio()})
    item = max(compare, key=compare.get)
    max_ratio = max(compare.values())
    return pd.Series([item, max_ratio],
                     index=['matched name', 'highest_similarity ratio'])

df1[['matched name', 'highest_similarity ratio']] = df1['name1'].apply(lambda x: compare(x))
df1
</code>```

But I just learnt that it can be much easier if use difflib.get_close_matches.

Body:
I have two dataframes:

import pandas as pd
df1 = pd.DataFrame({'Index': [1, 2, 3, 4, 5],
                   'name1': ['A brewery', 'B fresh produce', '100 wines', 'C canzirri ', 'D company']})

df2 = pd.DataFrame({'Index': [1, 2, 3, 4, 5, 6, 7],
                   'name2': ['bvb breweries', 'A brewerIES', 'BBBB fresh produce', '100 wines', 'f C canzirri ', 'Dcompany', 'b fresh produce']})

I want to generate new column df1.similar, for each df1.name1 value, the df1.similar is the corresponding value from df2.name2 with the highest similarity ratio.

The  df1.ratio  contains the highest similarity ratio.

For example:

from difflib import SequenceMatcher

def similiarity_ratio(a, b):
    return SequenceMatcher(None, a, b).ratio()

s=[]
for i in df2['name2']:
  s.append(similiarity_ratio('A brewery',i))
max(s)

The desirable output will set 'A brewerIES' (in df2.name2) to df1.similar, 0.8 to df1.ratio.

How can I apply/lamda to do it cross all values in df1.name1 ?

Body:
Hi i have had a try by myself. Silly but seems ok.

import pandas as pd
from difflib import SequenceMatcher

def compare(a):
    compare={}
    for i in df2['name2']:
        compare.update({i: SequenceMatcher(None, a, i).ratio()})
    item = max(compare, key=compare.get)
    max_ratio = max(compare.values())
    return pd.Series([item, max_ratio],
                     index=['matched name', 'highest_similarity ratio'])

df1[['matched name', 'highest_similarity ratio']] = df1['name1'].apply(lambda x: compare(x))
df1

But I just learnt that it can be much easier if use difflib.get_close_matches.


答:
As there are two properties _id they will only be one property which will remain. You can not have multiple key inside of an object with the same name.

Here is the code to merge all object as a single object you can take advantage of Array.prototype.reduce

let data = [
    {
        "_id": "6205576aaa478f466cca3809",
        "age": 51,
        "createdAt": "2022-02-10T18:20:26.451Z",
    },
    {
        "score": [
            0,
            1,
            3,
            1,
            0,
            2
        ],
        "_id": "62081d1bc83c452ef8e34e47",
        "key_findings": "Lorem ipsum",
        "subject": "6205576aaa478f466cca3809",
        "createdAt": "2022-02-12T20:48:27.574Z",
    }
];

const result = data.reduce((accumulator, item) => {
  return [{...accumulator[0], ...item}];
}, []);

console.log(result);```

Title: How to merge objects of arrays? mixed key


问:
How to connect to a local Redis server from a Docker container?
I'm trying to connect from inside a Docker container to a local Redis server on my machine. What I did so far:

Redis is up an running on my machine (can connect to it via redis-cli)

started an interactive Docker container (from the Ubuntu image)

installed "redis-tool" inside the container

tried to connect to Redis via redis-cli:

> redis-cli -h 172.17.0.3 -p 6379

(got the IP address via ifconfig inside the container)

got an error saying "connection refused"

What's the trick I'm not thinking of in order to get a working connection?

I already tried to set "bind 0.0.0.0" in my redis.conf but that had no effect. I also tried to forward the port 6379 to 6379 when running the container but I get an error saying the address is already in use.

Thanks in advance!

答:
Just use this command

"docker run --network=host -p port:port IMAGE"

Not only Redis, All your service you run at your localhost you need on docker you can use with this.


问:
How do I select distinct count over multiple columns?
How to select distinct count over multiple columns?

```<code>SELECT COUNT(DISTINCT col1, col2, col3) FROM table;
</code>```

Is there a working equivalent of this in DB2?

答:
```<code>select count(distinct col1 || '^' || col2 || '^' || col3) from table
</code>```

to avoid problems during concatenation like between 1 || 11 which would be the same as 11 || 1.

Body:
How to select distinct count over multiple columns?

SELECT COUNT(DISTINCT col1, col2, col3) FROM table;

Is there a working equivalent of this in DB2?

Body:
select count(distinct col1 || '^' || col2 || '^' || col3) from table

to avoid problems during concatenation like between 1 || 11 which would be the same as 11 || 1.


问:
Installing ImageMagick extension with php/windows
Running PHP Version 5.2.5 on Windows Server 2003 with IIS.

Have virtually an identical server where we were able to install ImageMagick with no issues. It's running exactly the same version of php. Used the following steps to install, but it just won't seem to work on this server. ImageMagick itself is installed but php won't load the extension.

We've spent hours trying to get the extension installed. It just won't show up in phpinfo().

INSTALL STEPS TAKEN

To install IMagick on Windows XP (PHP 5.2.x)

download and install ImageMagick-6.5.8-7 Q16-windows-dll.exe
http://www.imagemagick.org/download/binaries/ImageMagick-6.5.8-7-Q16-windows-dll.exe

download php_imagick_dyn-Q16.dll from
http://valokuva.org/outside-blog-content/imagick-windows-builds/080709/

copy DLL to [PHP]/extension dir and rename it to php_imagick.dll

You have to edit your php.ini file and add the new extension:

```<code>extension=php_imagick.dll
</code>```

Save php.ini and restart Apache server. (If necessary, restart Windows)

phpinfo() should show imagick enabled.

答: In my case Windows restart (mentioned in step 4) did the trick.</p>

Body:
Running PHP Version 5.2.5 on Windows Server 2003 with IIS.

Have virtually an identical server where we were able to install ImageMagick with no issues. It's running exactly the same version of php. Used the following steps to install, but it just won't seem to work on this server. ImageMagick itself is installed but php won't load the extension.

We've spent hours trying to get the extension installed. It just won't show up in phpinfo().

INSTALL STEPS TAKEN

To install IMagick on Windows XP (PHP 5.2.x)

download and install ImageMagick-6.5.8-7 Q16-windows-dll.exe
http://www.imagemagick.org/download/binaries/ImageMagick-6.5.8-7-Q16-windows-dll.exe

download php_imagick_dyn-Q16.dll from
http://valokuva.org/outside-blog-content/imagick-windows-builds/080709/

copy DLL to [PHP]/extension dir and rename it to php_imagick.dll

You have to edit your php.ini file and add the new extension:

extension=php_imagick.dll

Save php.ini and restart Apache server. (If necessary, restart Windows)

phpinfo() should show imagick enabled.


问:
PEG rules fails to EOI
I am trying to use PEG expression to take parse the file.
My PEG expression is:

```<code>WHITESPACE = _{" "}
level = {ASCII_DIGIT*}
verb = {ASCII_ALPHA{,4}}
value = {ASCII_ALPHANUMERIC*}
structure = { level ~ verb ~ value }
file = { SOI ~ (structure? ~ NEWLINE)* ~ EOI }
</code>```

I parse this text:

```<code>0 HEAD
1 VERB test
2 STOP
</code>```

file parse text successfully only, if I have an extra \n at the end of the text. If I remove the \n, parse fails due to 'expected EOI'. I understood that this happens, because of my rule for file. I tried to use different rules for file and got infinite loop. So, practically I don't know how to solve this issue. I am using rust and latest pest.

答:
I changed the rules to

```<code>level = {ASCII_DIGIT+}
verb = {ASCII_ALPHA{1,4}}
file = { SOI ~ (structure? ~ NEWLINE)* ~ structure? ~ EOI }
</code>```

and that seemed to work just fine, regardless of the trailing newline. But maybe I overlooked something. If you could edit your question to show the rules and input that caused an infinite loop with this, that'd be great.

Title: PEG rules fails to EOI

Body:
I am trying to use PEG expression to take parse the file.
My PEG expression is:

WHITESPACE = _{" "}
level = {ASCII_DIGIT*}
verb = {ASCII_ALPHA{,4}}
value = {ASCII_ALPHANUMERIC*}
structure = { level ~ verb ~ value }
file = { SOI ~ (structure? ~ NEWLINE)* ~ EOI }

I parse this text:

0 HEAD
1 VERB test
2 STOP

file parse text successfully only, if I have an extra \n at the end of the text. If I remove the \n, parse fails due to 'expected EOI'. I understood that this happens, because of my rule for file. I tried to use different rules for file and got infinite loop. So, practically I don't know how to solve this issue. I am using rust and latest pest.

Body:
I changed the rules to

level = {ASCII_DIGIT+}
verb = {ASCII_ALPHA{1,4}}
file = { SOI ~ (structure? ~ NEWLINE)* ~ structure? ~ EOI }

and that seemed to work just fine, regardless of the trailing newline. But maybe I overlooked something. If you could edit your question to show the rules and input that caused an infinite loop with this, that'd be great.


问:
Is it good practice for a react component to have returned value of null?
I've got a portal at the bottom of the screen just for informational purposes. It is displayed on a redux state and this component is at App level. Problem is with re-render of the entire parent component if this portal component changes its state. In my case, if someone closes the portal. Here's how I close the portal on a click.

```<code>dispatch({
  type: 'close-portal',
  payload: {
    portalState: { display: false },
  },
});
</code>```

App component

```<code>const isPortalOpen = useSelector((state) => state.user.portalState.display);
<Switch>
    <Route path='/login' component={LoginPage} exact />
    <Route path='/error' component={PermissionErrorPage} exact />
</Switch>
{isPortalOpen && <InformativeMessage />}
</code>```

Now If I am on the Login page and I close the portal, the entire page re-renders.

Alternative

I removed the conditional rendering from the App component and moved that into the portal component itself.

App component

```<code><Switch>
    <Route path='/login' component={LoginPage} exact />
    <Route path='/error' component={PermissionErrorPage} exact />
</Switch>
<InformativeMessage />
</code>```

Portal component

```<code>return (
  <>
    {isPortalOpen ? (
      <EuiPortal>
        <EuiBottomBar
          style={{
            backgroundColor: showUnsavedWarningPortal ? "red" : "",
            padding: "20px",
          }}
        >
          <EuiFlexItem
            style={{
              display: "flex",
              flexDirection: "row",
              alignItems: "center",
            }}
          >
            <EuiFlexItem>
              <EuiButtonIcon
                onClick={closePortal}
                color="ghost"
                iconType="crossInACircleFilled"
              />
            </EuiFlexItem>
            <EuiFlexItem style={{ marginLeft: "10px" }}>
              <EuiText>{message}</EuiText>
            </EuiFlexItem>
          </EuiFlexItem>
        </EuiBottomBar>
      </EuiPortal>
    ) : null}
  </>
);

</code>```

Doubt

Now this will return null if the portal is closed but this component isn't completely removed. If I open up the Dev tools and head over to the Components tab I can able to see the portal component. Of course, there's nothing inside but is it a good practice to have this component through out the entire app is running?

答: I would say there is nothing wrong with it, and I have seen such technique being used a lot. Preferably, I like first approach more -  it puts the logic in the App component, and the InfoMessage only need to care about its presentation - it is a nice way to do a bit of separation of concern</p>

Body:
I've got a portal at the bottom of the screen just for informational purposes. It is displayed on a redux state and this component is at App level. Problem is with re-render of the entire parent component if this portal component changes its state. In my case, if someone closes the portal. Here's how I close the portal on a click.

dispatch({
  type: 'close-portal',
  payload: {
    portalState: { display: false },
  },
});

App component

const isPortalOpen = useSelector((state) => state.user.portalState.display);
<Switch>
    <Route path='/login' component={LoginPage} exact />
    <Route path='/error' component={PermissionErrorPage} exact />
</Switch>
{isPortalOpen && <InformativeMessage />}

Now If I am on the Login page and I close the portal, the entire page re-renders.

Alternative

I removed the conditional rendering from the App component and moved that into the portal component itself.

App component

<Switch>
    <Route path='/login' component={LoginPage} exact />
    <Route path='/error' component={PermissionErrorPage} exact />
</Switch>
<InformativeMessage />

Portal component

return (
  <>
    {isPortalOpen ? (
      <EuiPortal>
        <EuiBottomBar
          style={{
            backgroundColor: showUnsavedWarningPortal ? "red" : "",
            padding: "20px",
          }}
        >
          <EuiFlexItem
            style={{
              display: "flex",
              flexDirection: "row",
              alignItems: "center",
            }}
          >
            <EuiFlexItem>
              <EuiButtonIcon
                onClick={closePortal}
                color="ghost"
                iconType="crossInACircleFilled"
              />
            </EuiFlexItem>
            <EuiFlexItem style={{ marginLeft: "10px" }}>
              <EuiText>{message}</EuiText>
            </EuiFlexItem>
          </EuiFlexItem>
        </EuiBottomBar>
      </EuiPortal>
    ) : null}
  </>
);

Doubt

Now this will return null if the portal is closed but this component isn't completely removed. If I open up the Dev tools and head over to the Components tab I can able to see the portal component. Of course, there's nothing inside but is it a good practice to have this component through out the entire app is running?


问:
How to fix the issue "Ad.load to be called before AdWidget is inserted into the tree" issue with Flutter / Admob?
I am using google_mobile_ads: ^1.1.0 version on Flutter and following the video here:

https://www.youtube.com/watch?v=m0d_pbgeeG8

Apart some small changes respect to the video (I guess not fully up to date compare to the most recent API changes) I have now the following code:

```<code>void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final initFuture = MobileAds.instance.initialize();
  final adState = AdState(initFuture);
  await SystemChrome.setPreferredOrientations(<DeviceOrientation>[
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown
  ]).then((_) => runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => Something()),
        ...some other ChangeNotifierProvider...,
        Provider<AdState>(create: (_) =>  adState)
      ],
      child: const MyApp()
    ),
  ));
}
</code>```

with AdState:

```<code>import 'dart:io';

import 'package:google_mobile_ads/google_mobile_ads.dart';

class AdState {
  Future<InitializationStatus> initialisation;

  AdState(this.initialisation);

  String get bannerAdUnitId => Platform.isAndroid
      ? 'ca-app-pub-3940256099942544/6300978111'
      : 'ca-app-pub-3940256099942544/2934735716'; // ios

  BannerAdListener get adListener => _adListener;

  final BannerAdListener _adListener = BannerAdListener(

    // Called when an ad is successfully received.
    onAdLoaded: (Ad ad) => print('Ad loaded: ${ad.adUnitId}.'),

    onAdClosed: (Ad ad) {
      ad.dispose();
      print('Ad closed: ${ad.adUnitId}.');
    },

    // Called when an ad request failed.
    onAdFailedToLoad: (Ad ad, LoadAdError error) {
      ad.dispose();
      print('Ad failed to load: : ${ad.adUnitId}, $error');
    },

    // Called when an ad opens an overlay that covers the screen.
    onAdOpened: (Ad ad) => print('Ad opened: ${ad.adUnitId}.'),

    // Called when an impression occurs on the ad.
    onAdImpression: (Ad ad) => print('Ad impression: ${ad.adUnitId}.'),
  );
}
</code>```

then in the home page widget state class:

```<code>BannerAd? banner;

@override
  void didChangeDependencies() {
    super.didChangeDependencies();
    final adState = Provider.of<AdState>(context);
    adState.initialisation.then((status) {
      setState(() {
        banner = BannerAd(
            adUnitId: adState.bannerAdUnitId,
            size: AdSize.banner,
            request: const AdRequest(),
            listener: adState.adListener
        )..load();
      });
    });
  }

@override
Widget build(BuildContext context) {
...somewhere in the middle...
if (banner == null)
  const SizedBox(height: 50)
else
  SizedBox (height:50, child: AdWidget(ad: banner!)),
....
}
</code>```

The error I am getting is:

AdWidget requires Ad.load to be called before AdWidget is inserted
into the tree

load() method is called in the didChangeDependencies() method above but of course it returns a Future so I think it may still not being there when the build() is being run. How can I fix that?

答:
You can use the AdWidget only after BannerAd is loaded not aftar BannerAd is not null.

So, try using a flag for loaded state like in the following snippet:

```<code>BannerAd? banner;
bool _bannerIsLoaded = false;

@override
  void didChangeDependencies() {
    super.didChangeDependencies();
    final adState = Provider.of<AdState>(context);
    adState.initialisation.then((status) {
      setState(() {
        banner = BannerAd(
            adUnitId: adState.bannerAdUnitId,
            size: AdSize.banner,
            request: const AdRequest(),
            listener: adState.adListener
        )..load();

        _bannerIsLoaded = true;
      });
    });
  }

@override
Widget build(BuildContext context) {
...somewhere in the middle...
if (banner != null && _bannerIsLoaded)
  SizedBox (height:50, child: AdWidget(ad: banner!)),
else
  const SizedBox(height: 50)

....
}
</code>```

Body:
I am using google_mobile_ads: ^1.1.0 version on Flutter and following the video here:

https://www.youtube.com/watch?v=m0d_pbgeeG8

Apart some small changes respect to the video (I guess not fully up to date compare to the most recent API changes) I have now the following code:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final initFuture = MobileAds.instance.initialize();
  final adState = AdState(initFuture);
  await SystemChrome.setPreferredOrientations(<DeviceOrientation>[
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown
  ]).then((_) => runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => Something()),
        ...some other ChangeNotifierProvider...,
        Provider<AdState>(create: (_) =>  adState)
      ],
      child: const MyApp()
    ),
  ));
}

with AdState:

import 'dart:io';

import 'package:google_mobile_ads/google_mobile_ads.dart';

class AdState {
  Future<InitializationStatus> initialisation;

  AdState(this.initialisation);

  String get bannerAdUnitId => Platform.isAndroid
      ? 'ca-app-pub-3940256099942544/6300978111'
      : 'ca-app-pub-3940256099942544/2934735716'; // ios

  BannerAdListener get adListener => _adListener;

  final BannerAdListener _adListener = BannerAdListener(

    // Called when an ad is successfully received.
    onAdLoaded: (Ad ad) => print('Ad loaded: ${ad.adUnitId}.'),

    onAdClosed: (Ad ad) {
      ad.dispose();
      print('Ad closed: ${ad.adUnitId}.');
    },

    // Called when an ad request failed.
    onAdFailedToLoad: (Ad ad, LoadAdError error) {
      ad.dispose();
      print('Ad failed to load: : ${ad.adUnitId}, $error');
    },

    // Called when an ad opens an overlay that covers the screen.
    onAdOpened: (Ad ad) => print('Ad opened: ${ad.adUnitId}.'),

    // Called when an impression occurs on the ad.
    onAdImpression: (Ad ad) => print('Ad impression: ${ad.adUnitId}.'),
  );
}

then in the home page widget state class:

BannerAd? banner;

@override
  void didChangeDependencies() {
    super.didChangeDependencies();
    final adState = Provider.of<AdState>(context);
    adState.initialisation.then((status) {
      setState(() {
        banner = BannerAd(
            adUnitId: adState.bannerAdUnitId,
            size: AdSize.banner,
            request: const AdRequest(),
            listener: adState.adListener
        )..load();
      });
    });
  }

@override
Widget build(BuildContext context) {
...somewhere in the middle...
if (banner == null)
  const SizedBox(height: 50)
else
  SizedBox (height:50, child: AdWidget(ad: banner!)),
....
}

The error I am getting is:

AdWidget requires Ad.load to be called before AdWidget is inserted
into the tree

load() method is called in the didChangeDependencies() method above but of course it returns a Future so I think it may still not being there when the build() is being run. How can I fix that?

Body:
You can use the AdWidget only after BannerAd is loaded not aftar BannerAd is not null.

So, try using a flag for loaded state like in the following snippet:

BannerAd? banner;
bool _bannerIsLoaded = false;

@override
  void didChangeDependencies() {
    super.didChangeDependencies();
    final adState = Provider.of<AdState>(context);
    adState.initialisation.then((status) {
      setState(() {
        banner = BannerAd(
            adUnitId: adState.bannerAdUnitId,
            size: AdSize.banner,
            request: const AdRequest(),
            listener: adState.adListener
        )..load();

        _bannerIsLoaded = true;
      });
    });
  }

@override
Widget build(BuildContext context) {
...somewhere in the middle...
if (banner != null && _bannerIsLoaded)
  SizedBox (height:50, child: AdWidget(ad: banner!)),
else
  const SizedBox(height: 50)

....
}