问:
How to assign differents MouseListener to differents JTextField?
im trying to make a Sudoku game and I want to change the background color of the same box, same column and same row when I click on a JTextField. I'm trying to add multiple Mouse Listener, one for each JTextField but It doesnt work. I'm now testing changing the background color of just the JTextField that I click on.

The main problem is in here.

```<code>import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class Panel extends JPanel {

    public static final int ROWS = 3;
    public static final int COLUMNS = 3;
    public static JTextField[][] fields = new JTextField[ROWS * COLUMNS][ROWS * COLUMNS];

    for (int i = 0; i < ROWS*COLUMNS; i++) {
        for (int j = 0; j < ROWS*COLUMNS; j++) {
            fields[i][j] = new JTextField();
            int finalI = i;
            int finalJ = j;
            fields[i][j].addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    fields[finalI][finalJ].setBackground(Color.BLUE);
                }
            });
        }
    }
}
</code>```

I have also try with this but it doesn't work.

```<code>import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class Panel extends JPanel {

    public static final int ROWS = 3;
    public static final int COLUMNS = 3;
    public static JTextField[][] fields = new JTextField[ROWS * COLUMNS][ROWS * COLUMNS];

    for (int i = 0; i < ROWS*COLUMNS; i++) {
        for (int j = 0; j < ROWS*COLUMNS; j++) {
            fields[i][j] = new JTextField();
            addMouseActions(i, j);
        }
    }

    private void addMouseActions(int row, int col){
        fields[row][col].addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                fields[row][col].setBackground(Color.BLUE);
            }
        });

    }
}
</code>```

Here it's the full code that I have for the Panel class.

```<code>import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class Panel extends JPanel {

    static String[] levels = {"Easy", "Medium", "Hard"};
    public static final JComboBox<String> levelsBox = new JComboBox<>(levels);
    private final JButton playButton = new JButton("Play");
    private final JButton checkButton = new JButton("Check");
    private final JButton hintButton = new JButton("Hint");
    private final JButton solveButton = new JButton("Solve");
    private final JButton exitButton = new JButton("Exit");

    public static final int ROWS = 3;
    public static final int COLUMNS = 3;
    public static JTextField[][] fields = new JTextField[ROWS * COLUMNS][ROWS * COLUMNS];

    public Panel(JFrame frame) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {

                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLocation(600, 200);
                frame.setLayout(new BorderLayout());
                frame.add(new SudokuBoard());
                frame.add(new MenuPane(), BorderLayout.AFTER_LINE_ENDS);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }

    public class MenuPane extends JPanel {

        public MenuPane() {
            setBorder(new EmptyBorder(4, 4, 4, 4));
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 1;
            gbc.weightx = 0;
            gbc.fill = GridBagConstraints.HORIZONTAL;

            JLabel diff = new JLabel("Select the difficulty: ");
            diff.setFont(new Font("SansSerif",Font.BOLD,18));
            add(diff, gbc);
            gbc.gridx++;

            levelsBox.setFont(new Font("SansSerif",Font.BOLD,16));
            add(levelsBox,gbc);
            gbc.gridy++;

            playButton.setActionCommand("Play");
            add(playButton, gbc);
            gbc.gridy++;

            checkButton.setActionCommand("Check");
            checkButton.setEnabled(false);
            add(checkButton, gbc);
            gbc.gridy++;

            hintButton.setActionCommand("Hint");
            hintButton.setEnabled(false);
            add(hintButton, gbc);
            gbc.gridy++;

            solveButton.setActionCommand("Solve");
            solveButton.setEnabled(false);
            add(solveButton, gbc);
            gbc.gridy++;

            exitButton.setActionCommand("Exit");
            add(exitButton, gbc);
        }
    }

    public static class SudokuBoard extends JPanel {

        private SubBoard[] subBoards;

        public SudokuBoard() {
            setBorder(new EmptyBorder(30, 30, 30, 10));
            subBoards = new SubBoard[ROWS * COLUMNS];
            setLayout(new GridLayout(ROWS, COLUMNS));
            for (int row = 0; row < ROWS; row++) {
                for (int col = 0; col < COLUMNS; col++) {
                    int bigIndex = (row * COLUMNS) + col;
                    int index = (row * ROWS) + col;
                    SubBoard board = new SubBoard(bigIndex);
                    board.setBorder(new LineBorder(Color.GRAY, 3));
                    subBoards[index] = board;
                    add(board);
                }
            }
        }
    }

    public static class SubBoard extends JPanel {

        public SubBoard(int bigIndex) {
            setLayout(new GridLayout(ROWS, COLUMNS));
            for (int row = 0; row < ROWS; row++) {
                for (int col = 0; col < COLUMNS; col++) {
                    int index = (row * COLUMNS) + col;
                    JTextField field = new JTextField();
                    field.setPreferredSize(new Dimension(60, 60));
                    field.setHorizontalAlignment(JTextField.CENTER);
                    field.setFont(new Font("SansSerif", Font.BOLD, 25));
                    field.setDocument(new JTextFieldLimit(1));
                    //field.setEditable(false);
                    fields[bigIndex][index] = field;
                    add(field);
                }
            }
        }
    }

    public void addListeners(Controller controller) {
        playButton.addActionListener(controller);
        checkButton.addActionListener(controller);
        hintButton.addActionListener(controller);
        solveButton.addActionListener(controller);
        exitButton.addActionListener(controller);
        for (int i = 0; i < ROWS*COLUMNS; i++) {
            for (int j = 0; j < ROWS*COLUMNS; j++) {
                fields[i][j] = new JTextField();
                int finalI = i;
                int finalJ = j;
                fields[i][j].addMouseListener(new MouseAdapter() {
                    @Override
                    public void mousePressed(MouseEvent e) {
                        fields[finalI][finalJ].setBackground(Color.BLUE);
                    }
                });
            }
        }
    }

    public void enableButtons(boolean enabled){
        checkButton.setEnabled(enabled);
        hintButton.setEnabled(enabled);
        solveButton.setEnabled(enabled);
    }
}
</code>```

And this is the Controller Class that I'm using for Actions Events.

```<code>import pkgClient.MyClient;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Objects;

public class Controller implements ActionListener {
    Panel panel;
    JFrame frame;

    public Controller(Panel panel, JFrame frame) {
        this.frame = frame;
        this.panel = panel;
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        if (e.getActionCommand().equalsIgnoreCase("Play")){
            String level = Panel.levelsBox.getItemAt(Panel.levelsBox.getSelectedIndex());
            if(Objects.equals(level, "Easy")){
                MyClient.out.println("easyMode");
            }else if(Objects.equals(level, "Medium")){
                MyClient.out.println("mediumMode");
            }else if (Objects.equals(level, "Hard")){
                MyClient.out.println("hardMode");
            }
            panel.enableButtons(true);
            Panel.fields[0][0].setBackground(Color.WHITE);

        } else if(e.getActionCommand().equalsIgnoreCase("Check")){
            System.out.println("Comprobar");
            MyClient.out.println("check");
            panel.enableButtons(false);

        }else if(e.getActionCommand().equalsIgnoreCase("Hint")){
            System.out.println("Pista");
            MyClient.out.println("hint");

        } else if(e.getActionCommand().equalsIgnoreCase("Solve")){
            System.out.println("Resolver");
            MyClient.out.println("solve");
            panel.enableButtons(false);

        } else if(e.getActionCommand().equalsIgnoreCase("Exit")) {
            frame.dispose();
            MyClient.out.println("exit");
        }else if(e.getActionCommand().equalsIgnoreCase("Text")) {
            System.out.println("hola");
            Panel.fields[0][0].setBackground(Color.BLACK);

        }else{
            System.err.println("Error: unexpected event");
        }
    }
}
</code>```

Is there any way to set an unique Mouse Event to every single JTextField like I do with buttons and Actions in the Controller Class? Or how do I have to do it?

Thank you.

答: I finally could solve the problem, I just needed to use a FocusListener instead of a MouseListener. I can change the background color of a field int the FocusGained(FocusEvent event) method and each JTextField has an independent event. I can know which JTextField is being clicked with event.getComponent() inside of the FocusGained method.</p>

Body:
im trying to make a Sudoku game and I want to change the background color of the same box, same column and same row when I click on a JTextField. I'm trying to add multiple Mouse Listener, one for each JTextField but It doesnt work. I'm now testing changing the background color of just the JTextField that I click on.

The main problem is in here.

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class Panel extends JPanel {

    public static final int ROWS = 3;
    public static final int COLUMNS = 3;
    public static JTextField[][] fields = new JTextField[ROWS * COLUMNS][ROWS * COLUMNS];

    for (int i = 0; i < ROWS*COLUMNS; i++) {
        for (int j = 0; j < ROWS*COLUMNS; j++) {
            fields[i][j] = new JTextField();
            int finalI = i;
            int finalJ = j;
            fields[i][j].addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    fields[finalI][finalJ].setBackground(Color.BLUE);
                }
            });
        }
    }
}

I have also try with this but it doesn't work.

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class Panel extends JPanel {

    public static final int ROWS = 3;
    public static final int COLUMNS = 3;
    public static JTextField[][] fields = new JTextField[ROWS * COLUMNS][ROWS * COLUMNS];

    for (int i = 0; i < ROWS*COLUMNS; i++) {
        for (int j = 0; j < ROWS*COLUMNS; j++) {
            fields[i][j] = new JTextField();
            addMouseActions(i, j);
        }
    }

    private void addMouseActions(int row, int col){
        fields[row][col].addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                fields[row][col].setBackground(Color.BLUE);
            }
        });

    }
}

Here it's the full code that I have for the Panel class.

import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class Panel extends JPanel {

    static String[] levels = {"Easy", "Medium", "Hard"};
    public static final JComboBox<String> levelsBox = new JComboBox<>(levels);
    private final JButton playButton = new JButton("Play");
    private final JButton checkButton = new JButton("Check");
    private final JButton hintButton = new JButton("Hint");
    private final JButton solveButton = new JButton("Solve");
    private final JButton exitButton = new JButton("Exit");

    public static final int ROWS = 3;
    public static final int COLUMNS = 3;
    public static JTextField[][] fields = new JTextField[ROWS * COLUMNS][ROWS * COLUMNS];

    public Panel(JFrame frame) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {

                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLocation(600, 200);
                frame.setLayout(new BorderLayout());
                frame.add(new SudokuBoard());
                frame.add(new MenuPane(), BorderLayout.AFTER_LINE_ENDS);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }

    public class MenuPane extends JPanel {

        public MenuPane() {
            setBorder(new EmptyBorder(4, 4, 4, 4));
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 1;
            gbc.weightx = 0;
            gbc.fill = GridBagConstraints.HORIZONTAL;

            JLabel diff = new JLabel("Select the difficulty: ");
            diff.setFont(new Font("SansSerif",Font.BOLD,18));
            add(diff, gbc);
            gbc.gridx++;

            levelsBox.setFont(new Font("SansSerif",Font.BOLD,16));
            add(levelsBox,gbc);
            gbc.gridy++;

            playButton.setActionCommand("Play");
            add(playButton, gbc);
            gbc.gridy++;

            checkButton.setActionCommand("Check");
            checkButton.setEnabled(false);
            add(checkButton, gbc);
            gbc.gridy++;

            hintButton.setActionCommand("Hint");
            hintButton.setEnabled(false);
            add(hintButton, gbc);
            gbc.gridy++;

            solveButton.setActionCommand("Solve");
            solveButton.setEnabled(false);
            add(solveButton, gbc);
            gbc.gridy++;

            exitButton.setActionCommand("Exit");
            add(exitButton, gbc);
        }
    }

    public static class SudokuBoard extends JPanel {

        private SubBoard[] subBoards;

        public SudokuBoard() {
            setBorder(new EmptyBorder(30, 30, 30, 10));
            subBoards = new SubBoard[ROWS * COLUMNS];
            setLayout(new GridLayout(ROWS, COLUMNS));
            for (int row = 0; row < ROWS; row++) {
                for (int col = 0; col < COLUMNS; col++) {
                    int bigIndex = (row * COLUMNS) + col;
                    int index = (row * ROWS) + col;
                    SubBoard board = new SubBoard(bigIndex);
                    board.setBorder(new LineBorder(Color.GRAY, 3));
                    subBoards[index] = board;
                    add(board);
                }
            }
        }
    }

    public static class SubBoard extends JPanel {

        public SubBoard(int bigIndex) {
            setLayout(new GridLayout(ROWS, COLUMNS));
            for (int row = 0; row < ROWS; row++) {
                for (int col = 0; col < COLUMNS; col++) {
                    int index = (row * COLUMNS) + col;
                    JTextField field = new JTextField();
                    field.setPreferredSize(new Dimension(60, 60));
                    field.setHorizontalAlignment(JTextField.CENTER);
                    field.setFont(new Font("SansSerif", Font.BOLD, 25));
                    field.setDocument(new JTextFieldLimit(1));
                    //field.setEditable(false);
                    fields[bigIndex][index] = field;
                    add(field);
                }
            }
        }
    }

    public void addListeners(Controller controller) {
        playButton.addActionListener(controller);
        checkButton.addActionListener(controller);
        hintButton.addActionListener(controller);
        solveButton.addActionListener(controller);
        exitButton.addActionListener(controller);
        for (int i = 0; i < ROWS*COLUMNS; i++) {
            for (int j = 0; j < ROWS*COLUMNS; j++) {
                fields[i][j] = new JTextField();
                int finalI = i;
                int finalJ = j;
                fields[i][j].addMouseListener(new MouseAdapter() {
                    @Override
                    public void mousePressed(MouseEvent e) {
                        fields[finalI][finalJ].setBackground(Color.BLUE);
                    }
                });
            }
        }
    }

    public void enableButtons(boolean enabled){
        checkButton.setEnabled(enabled);
        hintButton.setEnabled(enabled);
        solveButton.setEnabled(enabled);
    }
}

And this is the Controller Class that I'm using for Actions Events.

import pkgClient.MyClient;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Objects;

public class Controller implements ActionListener {
    Panel panel;
    JFrame frame;

    public Controller(Panel panel, JFrame frame) {
        this.frame = frame;
        this.panel = panel;
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        if (e.getActionCommand().equalsIgnoreCase("Play")){
            String level = Panel.levelsBox.getItemAt(Panel.levelsBox.getSelectedIndex());
            if(Objects.equals(level, "Easy")){
                MyClient.out.println("easyMode");
            }else if(Objects.equals(level, "Medium")){
                MyClient.out.println("mediumMode");
            }else if (Objects.equals(level, "Hard")){
                MyClient.out.println("hardMode");
            }
            panel.enableButtons(true);
            Panel.fields[0][0].setBackground(Color.WHITE);

        } else if(e.getActionCommand().equalsIgnoreCase("Check")){
            System.out.println("Comprobar");
            MyClient.out.println("check");
            panel.enableButtons(false);

        }else if(e.getActionCommand().equalsIgnoreCase("Hint")){
            System.out.println("Pista");
            MyClient.out.println("hint");

        } else if(e.getActionCommand().equalsIgnoreCase("Solve")){
            System.out.println("Resolver");
            MyClient.out.println("solve");
            panel.enableButtons(false);

        } else if(e.getActionCommand().equalsIgnoreCase("Exit")) {
            frame.dispose();
            MyClient.out.println("exit");
        }else if(e.getActionCommand().equalsIgnoreCase("Text")) {
            System.out.println("hola");
            Panel.fields[0][0].setBackground(Color.BLACK);

        }else{
            System.err.println("Error: unexpected event");
        }
    }
}

Is there any way to set an unique Mouse Event to every single JTextField like I do with buttons and Actions in the Controller Class? Or how do I have to do it?

Thank you.


来源: stackexchange

问:
How to pass a formData object and another object inside array with Axios JS
Hello I have a simple problem. I have two objects in Javascript I am trying to pass together to my server using Axios.

First, a simple object with simple properties and values:

```<code>        var object1 = {
            type: {color: "red", variants: [1,2,4,5]},
            content: "xxx"
        }
</code>```

Also a second object which contains File images

```<code>        let imagesLocalForm = new FormData();
        this.imagesLocal.forEach(img => {
            imagesLocalForm.append("productPhotos[]", img[0]);
        });
</code>```

Sending either object by themselves will successfully transfer the data to the server. HOWEVER, once I combine the data into an array or another object then all the images from the form object will disappear. ex:

```<code>var data = [object1, imagesLocalForm];
</code>```

or

```<code>var data = {info: object1, images: imagesLocalForm};
</code>```

I use this Axios code to post the data:

```<code>        Axios.post(this.ADD_MULTI_PRODUCT_API_ENDPOINT, data)
        .then(function (response) {
            console.log(response);
        })
        .catch(function (error) {
            console.log(error);
        });
</code>```

When i dd() the data array, the response I receive is:

```<code>array:2 [
  0 => array:2 [
    "type" => array:2 [
      "color" => "red"
      "variants" => array:4 [
        0 => 1
        1 => 2
        2 => 4
        3 => 5
      ]
    ]
    "content" => "xxx"
  ]
  1 => []
]
</code>```

When i dd() from my php server i receive all of my object1 data but none of the imagesLocalForm data. Could someone explain this behavior to me?

答:
You cannot post JSON data and form data to the same endpoint, it'd simply be impossible because the request body can only have one content type. But you can add you additional data to your existing FormData object.

To do that:

let imagesLocalForm = new FormData();

this.imagesLocal.forEach(img => {
  imagesLocalForm.append("productPhotos[]", img[0]);
});

const object1 = {
  type: "big",
  content: "xxx"
}

for (const key of Object.keys(object1)) {
  imagesLocalForm.append(key, object1[key]);
}
```

Then you can just pass imagesLocalForm to your backend endpoint

ContentLicense: CC BY-SA 4.0

Body:
Hello I have a simple problem. I have two objects in Javascript I am trying to pass together to my server using Axios.

First, a simple object with simple properties and values:

        var object1 = {
            type: {color: "red", variants: [1,2,4,5]},
            content: "xxx"
        }

Also a second object which contains File images

        let imagesLocalForm = new FormData();
        this.imagesLocal.forEach(img => {
            imagesLocalForm.append("productPhotos[]", img[0]);
        });

Sending either object by themselves will successfully transfer the data to the server. HOWEVER, once I combine the data into an array or another object then all the images from the form object will disappear. ex:

var data = [object1, imagesLocalForm];

or

var data = {info: object1, images: imagesLocalForm};

I use this Axios code to post the data:

        Axios.post(this.ADD_MULTI_PRODUCT_API_ENDPOINT, data)
        .then(function (response) {
            console.log(response);
        })
        .catch(function (error) {
            console.log(error);
        });

When i dd() the data array, the response I receive is:

array:2 [
  0 => array:2 [
    "type" => array:2 [
      "color" => "red"
      "variants" => array:4 [
        0 => 1
        1 => 2
        2 => 4
        3 => 5
      ]
    ]
    "content" => "xxx"
  ]
  1 => []
]

When i dd() from my php server i receive all of my object1 data but none of the imagesLocalForm data. Could someone explain this behavior to me?

Body:
You cannot post JSON data and form data to the same endpoint, it'd simply be impossible because the request body can only have one content type. But you can add you additional data to your existing FormData object.

To do that:

let imagesLocalForm = new FormData();

this.imagesLocal.forEach(img => {
  imagesLocalForm.append("productPhotos[]", img[0]);
});

const object1 = {
  type: "big",
  content: "xxx"
}

for (const key of Object.keys(object1)) {
  imagesLocalForm.append(key, object1[key]);
}

Then you can just pass imagesLocalForm to your backend endpoint


问:
How to create nested JSON using first entry from from flat JSON as parent in javascript
I've tried various answers to this (same/similar) question here, and none have given the desired result.
I have a flat Json file that I need to convert to nested.
The first item in each chunk is the item that the data needs grouping on when converted to nested data.
The example data just shows two "types" but there are several more in the data, and a few more other elements along with colour and size as well - I kept it short for posting here.

Example data input:

```<code>[
  {
    "type": "Background",
    "colour": "Blue",
    "size": "5"
  },
  {
    "type": "Background",
    "colour": "Grey",
    "size": "3"
  },
  {
    "type": "Foreground",
    "colour": "Red",
    "size": "5"
  },
  {
    "type": "Foreground",
    "colour": "White",
    "size": "10"
  }
]
</code>```

Desired Output:

```<code>[
  {
    "type": "Background",
    "elements": [
      {
        "colour": "Blue",
        "size": "5"
      },
      {
        "colour": "Grey",
        "size": "3"
      }
    ]
  }
  {
    "type": "Foreground",
    "elements": [
      {
        "colour": "Red",
        "size": "5"
      },
      {
        "colour": "White",
        "size": "10"
      }
    ]
  }
]
</code>```

The closest I came to an answer for this was here:
Create nested json from flattened JSON in javascript

But the output I received from that (in VSCode) was this:

```<code>{
  type: { elements: [ [Object], [Object] ] }
}
</code>```

While I am trying to follow the code, it is beyond my javascript knowledge currently, so I don't know what's going wrong, or why I get [object] and not the actual elements?

Can anyone help me get this sorted out so my output looks like my above "Desired output"?

Cheers!

答:
You can use the forEach() method to loop over the array, in this case, result. If the type wasn't set in the result, then add the new type. But, if the item already has its type in the result, then just push the item's elements.

const items = [
  {
    type: 'Background',
    colour: 'Blue',
    size: '5',
  },
  {
    type: 'Background',
    colour: 'Grey',
    size: '3',
  },
  {
    type: 'Foreground',
    colour: 'Red',
    size: '5',
  },
  {
    type: 'Foreground',
    colour: 'White',
    size: '10',
  },
];

let result = [];

items.forEach((item) => {
  if (!result.find((x) => x.type === item.type)) {
    result.push({ type: item.type, elements: [] });
  }

  result
    .find((x) => x.type === item.type)
    .elements.push({
      color: item.colour,
      size: item.size,
    });
});

console.log(result);```

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

Body:
I've tried various answers to this (same/similar) question here, and none have given the desired result.
I have a flat Json file that I need to convert to nested.
The first item in each chunk is the item that the data needs grouping on when converted to nested data.
The example data just shows two "types" but there are several more in the data, and a few more other elements along with colour and size as well - I kept it short for posting here.

Example data input:

[
  {
    "type": "Background",
    "colour": "Blue",
    "size": "5"
  },
  {
    "type": "Background",
    "colour": "Grey",
    "size": "3"
  },
  {
    "type": "Foreground",
    "colour": "Red",
    "size": "5"
  },
  {
    "type": "Foreground",
    "colour": "White",
    "size": "10"
  }
]

Desired Output:

[
  {
    "type": "Background",
    "elements": [
      {
        "colour": "Blue",
        "size": "5"
      },
      {
        "colour": "Grey",
        "size": "3"
      }
    ]
  }
  {
    "type": "Foreground",
    "elements": [
      {
        "colour": "Red",
        "size": "5"
      },
      {
        "colour": "White",
        "size": "10"
      }
    ]
  }
]

The closest I came to an answer for this was here:
Create nested json from flattened JSON in javascript

But the output I received from that (in VSCode) was this:

{
  type: { elements: [ [Object], [Object] ] }
}

While I am trying to follow the code, it is beyond my javascript knowledge currently, so I don't know what's going wrong, or why I get [object] and not the actual elements?

Can anyone help me get this sorted out so my output looks like my above "Desired output"?

Cheers!

Body:
You can use the forEach() method to loop over the array, in this case, result. If the type wasn't set in the result, then add the new type. But, if the item already has its type in the result, then just push the item's elements.

const items = [
  {
    type: 'Background',
    colour: 'Blue',
    size: '5',
  },
  {
    type: 'Background',
    colour: 'Grey',
    size: '3',
  },
  {
    type: 'Foreground',
    colour: 'Red',
    size: '5',
  },
  {
    type: 'Foreground',
    colour: 'White',
    size: '10',
  },
];

let result = [];

items.forEach((item) => {
  if (!result.find((x) => x.type === item.type)) {
    result.push({ type: item.type, elements: [] });
  }

  result
    .find((x) => x.type === item.type)
    .elements.push({
      color: item.colour,
      size: item.size,
    });
});

console.log(result);

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach


问:
Files writable by PHP even though CHMOD is 555?
I've got a new server and when using my php script, I'm able to write files and detect them as being writable even though CHMOD has them as 555 or 755. Is there an apache module or php.ini that is making this possible? Is this a security problem?</p>

答:
You might want to read up on file permissions here:

http://www.zzee.com/solutions/unix-permissions.shtml

That should give you a clue about whats going on.

It doesn't have to be a security hole, file permissions are server side, but if people can upload files they can theoretically, potentially inflict harm by somehow getting their own code running on your server....

ContentLicense: CC BY-SA 3.0


问:
Why do I need to check if a file can be read twice (once with built in File method once with Scanner)
So I'm reviewing my professor's code for a project (my goal is to just understand everything) and she verifies that a file can be opened/read three times, and I'm not sure why all three are necessary.

1: if (!File.exists()) { }  Checks if the file exists using the built in exists method on a File object

2: if (!File.canRead()){ checks if the file can be read using the built in canRead method on the File object

3 (the part I don't understand):

```<code>Scanner blank = null;
try {
            blank = new Scanner(File) ;
        } catch (FileNotFoundException e) {
           do whatever
    }

</code>```

I don't understand why if we already checked if the file can be opened using the canRead method why we need to check AGAIN if it can be opened using a Scanner.

I would appreciate any insight. Thanks.

答:
In this example, you are not checking a second time if the file can be opened.

In the code snippet you have provided, there is a new Scanner object made, with the object colorFile passed to it through the parentheses.

The catch section simply is error handling if the file is to not exist on the drive, it will throw an error letting you know.

Body:
So I'm reviewing my professor's code for a project (my goal is to just understand everything) and she verifies that a file can be opened/read three times, and I'm not sure why all three are necessary.

1: if (!File.exists()) { }  Checks if the file exists using the built in exists method on a File object

2: if (!File.canRead()){ checks if the file can be read using the built in canRead method on the File object

3 (the part I don't understand):

Scanner blank = null;
try {
            blank = new Scanner(File) ;
        } catch (FileNotFoundException e) {
           do whatever
    }

I don't understand why if we already checked if the file can be opened using the canRead method why we need to check AGAIN if it can be opened using a Scanner.

I would appreciate any insight. Thanks.


答: Because Scanner(File) can throw FileNotFoundException. It's part of the API, and a checked Exception. Thus, you have to catch it (or add throws to your own method). Finally, you should always close() your Scanner(s) when they wrap a File. Else you leak a file handle. The best way, in my opinion, would be try-with-resources statement.

Title: Why do I need to check if a file can be read twice (once with built in File method once with Scanner)


问:
Git branching strategy - losing changes on merge
We've got a branching strategy with develop, release, and master branches.  Features/bugs branch off of release.
When complete, they merge into develop for QA testing.  Once QA passes, they merge (directly from the feature/bug branch) into release for release regression testing.  Release merges to master after final regression testing.  Hotfixes branch off master, merge back into master.

With all that said, we are sometimes losing changes in release and QA when merging branches in.  Developers are merging from release into their branches prior to merging into QA and release, but never merging in from QA.

Are there any conceptual issues with this strategy?  Any potential reasons why we may be losing those changes?

答:
We've got a branching strategy with develop, release, and master branches.

That sounds a bit like Gitflow. But the rest of your description does not. So I am assuming you are using something else on purpose and did not just misunderstand Gitflow. That is absolutely fine, but IMO your concept is flawed for some reasons. I am saying that because you directly asked:

Are there any conceptual issues with this strategy?

So yes, there are.

Features/bugs branch off of release. When complete, they merge into develop for QA testing.

That sounds a bit weird. Features should branch off of develop, be QA tested directly in their own branches and only merged back into develop after QA has passed, where subsequently you can do additional integration testing.

On a side note: In projects where I work as a coach, we usually have a rule that merges from subordinate (less stable) to higher-ranking (more stable) branches always have to be fast-forwards. I.e., if during feature development some other features happen to have been QA-tested and merged back into develop earlier than the currently tested ones, the feature branch must be refreshed from development, re-tested as much as necessary and only then fast-forwarded back into develop. That means, both feature QA testing and integration testing are done in the feature branch. A feature or bugfix is only merged back into development after it is clear that it does not only work in isolation but also integrated with all other work which was already accepted into development before. I call that the "no surprises" rule. The situation "oh, on the feature branch it was working, why does it not work on the development branch?" simply cannot occur and no additional post-merge integration testing is even necessary, because it was a fast-forward.

So this directly contradicts what VonC said in his answer:

No merge is ever made from release or master. Those are branches you merge to, not from.

I could not disagree more. Subordinate branches should be refreshed from higher-ranking ones regularly, because by definition on higher-ranking ones there is always work that was accepted to be merged (or fast-forwarded) there before, i.e. it is inevitable that you have to integrate with them. Merge conflicts or post-merge integration problems ought to be fixed in the feature or bugfix branch before accepting and merging them back into the higher-ranking branch. IMO it is an absolute no-no to mess up a higher-ranking branch with newly introduced instability and then clean up the mess there.

Once QA passes, they merge (directly from the feature/bug branch) into release for release regression testing.

Before, you said that you do integration testing on develop, i.e. you resolve merge conflicts there which might be completely different from the ones (if any) you will have when merging the feature back into release. Moreover, you are merging back something other than was integration-tested. So even if there are no conflicts and everything goes super smoothly, what you are merging and what you have been testing is not the same. That is very dangerous IMO. In your setup, the release branch contains other things than develop, and you seem to abuse - sorry for the opinionated term, but I indeed hold that opinion - develop as some kind of conflict-resolving and integration-testing sandbox, only not to merge back to the release branch from there later.

You have no clear hierarchy of branches like Gitflow or a simple feature branch workflow do. I think this is dangerous and calling for trouble.

Release merges to master after final regression testing.

See? That is another side effect: You QA-test the feature, then integration-test develop, merge something else, then have to re-test ("final regression testing") again, which should not even be necessary with a good, hierarchical branching and merging strategy.

Hotfixes branch off master, merge back into master.

I want to say more about that, but in this case it is not the source of the problem, because at least this is hierarchical. You merge back to where you branched off of. As long as you regularly refresh subordinate branches from master in order to also have the hotfixes there, OK, but only then.


问:
Javascript: how to send a file from to server with save as dialog box
I have a file which I generated through code on our Server. I would the user to save this new file to their computer by clicking on a button.

I have been searching for a way to do this in my code behind file or through javascript.

I have discovered the document.execCommand(....) javascript but I don't think is this is the right direction.

Any help for a novice would be a great help!

答: This shouldn't be a problem that you need fancy Javascript to solve. You should simply add a button to your page that connects to a specific url and contains an id of some sort to link it to the file that your server generated. It's up to the server to pick the right file and serve it back to the user with the appropriate headers.</p>


问:
Django redirect to DetailView From FormView
What I'm trying to do is to have a form with a single field that gets a primary key and redirects to DetailView of that primary key. While I can achieve this by having a ListView and then go to the DetailView from ListView that's an extra step I don't need as I already have a primary key. Any help would be appreciated.

models.py

```<code>class Book(models.model):
    book_id = models.TextField(primary_key=True)
    # some other fields
    def get_absolute_url(self):
        return reverse('book-detail', kwargs={'pk':self.pk})
</code>```

forms.py

```<code>class BookSearchForm(forms.ModelForm):
    class Meta:
        model = Book
        fields = ['book_id']
</code>```

views.py

```<code>class BookDetailView(DetailView):
    model = Book
    template_name = 'book-detail.html'
</code>```

with a ListView I can do it like below:

```<code>class BookListView(ListView):
    template_name = 'book-list.html'
    form_class = BookSearchForm

    def get_queryset(self, *args, **kwargs):
        qs = super().get_queryset(*args, **kwargs)
        book_id = self.request.Get.get('book_id', None)
        if book_id:
            qs=qs.filter(book_id=book_id).first()
        if not book_id:
            qs=qs.none()
        return qs
</code>```

How can I do it without a ListView??

```<code>class BookSearchView(FormView):
    template_name = 'book-search.html'
    form_class = BookSearchForm
    # what should I do here, form_valid, get?
</code>```

urls.py

```<code>urlpatterns = [
    path('book/search/',BookSearchView.as_view(),name='book-search'),
    path('book/<str:pk>/',BookDetailView.as_view(),name='book-detail')
]
</code>```

book-search.html

```<code><form action="." method="GET">
    {{form}}
</form>
</code>```

答:
Well to redirect to the DetailView you can specify a success url in your FormView like so:</p>
```<code>class BookSearchView(FormView):
    template_name = 'book-search.html'
    form_class = BookSearchForm
    success_url = '' # The url that you want to direct after form is validated

     def form_valid(self, form):
        # This method is called when valid form data has been POSTed.
        # It should return an HttpResponse.

        return super().form_valid(form)
</code>```

Body:
What I'm trying to do is to have a form with a single field that gets a primary key and redirects to DetailView of that primary key. While I can achieve this by having a ListView and then go to the DetailView from ListView that's an extra step I don't need as I already have a primary key. Any help would be appreciated.

models.py

class Book(models.model):
    book_id = models.TextField(primary_key=True)
    # some other fields
    def get_absolute_url(self):
        return reverse('book-detail', kwargs={'pk':self.pk})

forms.py

class BookSearchForm(forms.ModelForm):
    class Meta:
        model = Book
        fields = ['book_id']

views.py

class BookDetailView(DetailView):
    model = Book
    template_name = 'book-detail.html'

with a ListView I can do it like below:

class BookListView(ListView):
    template_name = 'book-list.html'
    form_class = BookSearchForm

    def get_queryset(self, *args, **kwargs):
        qs = super().get_queryset(*args, **kwargs)
        book_id = self.request.Get.get('book_id', None)
        if book_id:
            qs=qs.filter(book_id=book_id).first()
        if not book_id:
            qs=qs.none()
        return qs

How can I do it without a ListView??

class BookSearchView(FormView):
    template_name = 'book-search.html'
    form_class = BookSearchForm
    # what should I do here, form_valid, get?

urls.py

urlpatterns = [
    path('book/search/',BookSearchView.as_view(),name='book-search'),
    path('book/<str:pk>/',BookDetailView.as_view(),name='book-detail')
]

book-search.html

<form action="." method="GET">
    {{form}}
</form>

Body:
Well to redirect to the DetailView you can specify a success url in your FormView like so:

class BookSearchView(FormView):
    template_name = 'book-search.html'
    form_class = BookSearchForm
    success_url = '' # The url that you want to direct after form is validated

     def form_valid(self, form):
        # This method is called when valid form data has been POSTed.
        # It should return an HttpResponse.

        return super().form_valid(form)


问:
How can I change the left parameter as String while writing in my Firebase Realtime Database in Functions?
My Code to write into the database:

```<code>rdb.ref(`users/${userid}`).update({
            name : username,
            `${mystring}` : 1,
            `${mystring2}` : 2
        });
</code>```

The connection and the writing works, but only the first line.
In JavaScript the Syntax to pass a variable to a String should be :

```<code>`string${variable}`
</code>```

Am I wrong or is this a bug?

答:
Like @Jeremy said, Strings need brackets around:</p>
```<code>rdb.ref(`users/${userid}`).update({
            name : username,
            [`${mystring}`] : 1,
            [`${mystring2}`] : 2
        });
</code>```

Body:
My Code to write into the database:

rdb.ref(`users/${userid}`).update({
            name : username,
            `${mystring}` : 1,
            `${mystring2}` : 2
        });

The connection and the writing works, but only the first line.
In JavaScript the Syntax to pass a variable to a String should be :

`string${variable}`

Am I wrong or is this a bug?

Body:
Like @Jeremy said, Strings need brackets around:

rdb.ref(`users/${userid}`).update({
            name : username,
            [`${mystring}`] : 1,
            [`${mystring2}`] : 2
        });


问:
What happened to my matrix col, it shows NA
I am learning R now and I want to make a matrix to store scores. I don't know why the named_matrix can't show the Student_6. The picture as below shows the Student_NA.

```<code>scores <- c(58, 46, 50, 90, 42, 52, 62, 44, 96, 92, 54, 82)

scores_matrix <- matrix(scores, nrow = 2,ncol = length(scores)/2, byrow = TRUE)
scores_matrix

named_matrix <- scores_matrix
suffix <- seq(1:n)
rownames(named_matrix) <- paste("Quiz_",suffix[1:nrow(named_matrix)],seq=" ")
colnames(named_matrix)<- paste("Student_",suffix[1:ncol(named_matrix)],seq=" ")
named_matrix
</code>```

答:
n is undefined in your code. Also 1:n makes seq redundant.

Correcting your code -

```<code>scores <- c(58, 46, 50, 90, 42, 52, 62, 44, 96, 92, 54, 82)

scores_matrix <- matrix(scores, nrow = 2,ncol = length(scores)/2, byrow = TRUE)
scores_matrix

named_matrix <- scores_matrix
suffix <- 1:length(scores)
rownames(named_matrix) <- paste("Quiz_",suffix[1:nrow(named_matrix)],seq=" ")
colnames(named_matrix)<- paste("Student_",suffix[1:ncol(named_matrix)],seq=" ")
named_matrix

#            Student_ 1   Student_ 2   Student_ 3   Student_ 4   Student_ 5   Student_ 6
#Quiz_ 1             58           46           50           90           42           52
#Quiz_ 2             62           44           96           92           54           82
</code>```

However, you can also simplify this process.

```<code>scores <- c(58, 46, 50, 90, 42, 52, 62, 44, 96, 92, 54, 82)
n <- 2
m <- length(scores)/2
scores_matrix <- matrix(scores, nrow = n,ncol = m,byrow = TRUE,
                      dimnames = list(paste0('Quiz_', seq_len(n)),
                                      paste0('Student', seq_len(m))))
scores_matrix

#       Student1 Student2 Student3 Student4 Student5 Student6
#Quiz_1       58       46       50       90       42       52
#Quiz_2       62       44       96       92       54       82
</code>```

Body:
I am learning R now and I want to make a matrix to store scores. I don't know why the named_matrix can't show the Student_6. The picture as below shows the Student_NA.

scores <- c(58, 46, 50, 90, 42, 52, 62, 44, 96, 92, 54, 82)

scores_matrix <- matrix(scores, nrow = 2,ncol = length(scores)/2, byrow = TRUE)
scores_matrix

named_matrix <- scores_matrix
suffix <- seq(1:n)
rownames(named_matrix) <- paste("Quiz_",suffix[1:nrow(named_matrix)],seq=" ")
colnames(named_matrix)<- paste("Student_",suffix[1:ncol(named_matrix)],seq=" ")
named_matrix

Body:
n is undefined in your code. Also 1:n makes seq redundant.

Correcting your code -

scores <- c(58, 46, 50, 90, 42, 52, 62, 44, 96, 92, 54, 82)

scores_matrix <- matrix(scores, nrow = 2,ncol = length(scores)/2, byrow = TRUE)
scores_matrix

named_matrix <- scores_matrix
suffix <- 1:length(scores)
rownames(named_matrix) <- paste("Quiz_",suffix[1:nrow(named_matrix)],seq=" ")
colnames(named_matrix)<- paste("Student_",suffix[1:ncol(named_matrix)],seq=" ")
named_matrix

#            Student_ 1   Student_ 2   Student_ 3   Student_ 4   Student_ 5   Student_ 6
#Quiz_ 1             58           46           50           90           42           52
#Quiz_ 2             62           44           96           92           54           82

However, you can also simplify this process.

scores <- c(58, 46, 50, 90, 42, 52, 62, 44, 96, 92, 54, 82)
n <- 2
m <- length(scores)/2
scores_matrix <- matrix(scores, nrow = n,ncol = m,byrow = TRUE,
                      dimnames = list(paste0('Quiz_', seq_len(n)),
                                      paste0('Student', seq_len(m))))
scores_matrix

#       Student1 Student2 Student3 Student4 Student5 Student6
#Quiz_1       58       46       50       90       42       52
#Quiz_2       62       44       96       92       54       82


问:
why nested foreach within javascript loop not working?
I am trying to check if the answers from a user are correct. The answers of the user are stored in variable "stad". The correct options are stored in variable "collectie". However, this variable is an array with a nested array. So i first loop through the "collectie", check if the collectie element is not an array and if not, check that the submitted value is within this collectie element.

If the collectie element is an array, i have to alter a little bit the function so the variable checks whether the answer is within the nested array.

I have the following:

```<code>function nakijken() {
var collectie = ["parijs", "8", "ijsselmeer", ["Volkswagen", "Audi", "Opel", "Porsche", "BMW", "Mercedes", "Mercedes-Benz"],
["Texel", "Vlieland", "Terschelling", "Ameland", "Schiermonnikoog"]];
var stad = [];
var a = 0;
stad.push(document.getElementsByTagName("input"));
collectie.forEach(uitpakken);
function uitpakken(antwoord) {
    if (!Array.isArray(antwoord)) {
        stad.forEach(myfunction);
        function myfunction(item) {
            if (antwoord.includes(item.value.toLowerCase())) {
                item.style.background = "green";
                a++;
            } else {
                antwoord.style.background = "red";
            }
        }
    }
    else{
        antwoord.Foreach(uitpakken);
        function uitpakken(antwoord) {
        stad.forEach(mysecondfunction);
            function mysecondfunction(item) {
                if (antwoord.includes(item.value.toLowerCase())) {
                    item.style.background = "green";
                    a++;
                } else {
                    antwoord.style.background = "red";
                }
            }
        }
    }
}
</code>```

However, i get the error: item.value is not defined.
Within the console, i see that item is a collection of inputs, and not a single input.

Why is this not working?

答:
The main probelm seems to be in

```<code>stad.push(document.getElementsByTagName("input"));
</code>```

because that pushes the returned element collection into stad as a single reference (and also an HTML collection is not a real array). Instead, you can use

```<code>stad = Array.from(document.getElementsByTagName("input"));
</code>```

Second, in the first branch of the if statement, where antwoord is not an array, what does it mean if (antwoord.includes(item.value.toLowerCase())) ? You probably want to use a simple comparison like if (antwoord === item.value.toLowerCase()) .

Third, there is a typo Foreach instead of forEach in one place.

Fourth, are you sure you want to loop through all the input boxes for each entry in the main correct answers array? Isn't each input box corresponding to a specific question with a specific correct answer or set of correct answers?

Body:
I am trying to check if the answers from a user are correct. The answers of the user are stored in variable "stad". The correct options are stored in variable "collectie". However, this variable is an array with a nested array. So i first loop through the "collectie", check if the collectie element is not an array and if not, check that the submitted value is within this collectie element.

If the collectie element is an array, i have to alter a little bit the function so the variable checks whether the answer is within the nested array.

I have the following:

function nakijken() {
var collectie = ["parijs", "8", "ijsselmeer", ["Volkswagen", "Audi", "Opel", "Porsche", "BMW", "Mercedes", "Mercedes-Benz"],
["Texel", "Vlieland", "Terschelling", "Ameland", "Schiermonnikoog"]];
var stad = [];
var a = 0;
stad.push(document.getElementsByTagName("input"));
collectie.forEach(uitpakken);
function uitpakken(antwoord) {
    if (!Array.isArray(antwoord)) {
        stad.forEach(myfunction);
        function myfunction(item) {
            if (antwoord.includes(item.value.toLowerCase())) {
                item.style.background = "green";
                a++;
            } else {
                antwoord.style.background = "red";
            }
        }
    }
    else{
        antwoord.Foreach(uitpakken);
        function uitpakken(antwoord) {
        stad.forEach(mysecondfunction);
            function mysecondfunction(item) {
                if (antwoord.includes(item.value.toLowerCase())) {
                    item.style.background = "green";
                    a++;
                } else {
                    antwoord.style.background = "red";
                }
            }
        }
    }
}

However, i get the error: item.value is not defined.
Within the console, i see that item is a collection of inputs, and not a single input.

Why is this not working?

Body:
The main probelm seems to be in

stad.push(document.getElementsByTagName("input"));

because that pushes the returned element collection into stad as a single reference (and also an HTML collection is not a real array). Instead, you can use

stad = Array.from(document.getElementsByTagName("input"));

Second, in the first branch of the if statement, where antwoord is not an array, what does it mean if (antwoord.includes(item.value.toLowerCase())) ? You probably want to use a simple comparison like if (antwoord === item.value.toLowerCase()) .

Third, there is a typo Foreach instead of forEach in one place.

Fourth, are you sure you want to loop through all the input boxes for each entry in the main correct answers array? Isn't each input box corresponding to a specific question with a specific correct answer or set of correct answers?


问:
Request method 'POST' not supported]
I have a problem with updatePowerPlant() method, when I try to update powerPlant entity with given id and click the submit button in the update form under localhost:8080/updatePowerPlant adress I get redirected to this url http://localhost:8080/updatePowerPlant/savePowerPlant.

I don't know why. I should get redireted to /powerPlants, wethever entity with given id exists or not, instead /savePowerPlant is added as a last part of a url localhost:8080/updatePowerPlant and I get  Request method 'POST' not supported], I know that this is the message I should get afterall there is no GetController with such url but why do I get this weird url? Is it because I use GetController for update?

localhost:8080/updatePowerPlant this I enter in browser to get update form
http://localhost:8080/updatePowerPlant/savePowerPlant this I get when I clik submit in update form

Controller class

```<code>@RequiredArgsConstructor
@Controller
public class PowerPlantsController {

    private final PowerPlantRepository powerPlantRepository;
    private final EventRepository eventRepository;
    private final PlantService plantService;
    private final EventService eventService;

    @GetMapping("form")
    public String getForm(Model model) {
        model.addAttribute("plant", new PlantViewModel());
        return "save";
    }

    @PostMapping("savePowerPlant")
    public String addPowerPlant(@ModelAttribute("plant") @Valid PlantViewModel plant, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            if (plant.getId() == null) {
                return "save";
            } else return "updatePowerPlant";
        }
        if (plant.getId() == null){
            plantService.add(plant);
        }else {
            plantService.update(plant);
        }
        return "redirect:/powerPlants";
    }

    @GetMapping("updatePowerPlant/{id}")
    public String updatePowerPlant(@PathVariable(value = "id") Integer id, Model model) {
        var find = powerPlantRepository.getOne(id);
        var plants = plantService.powerPlantToViewModel(find);
        model.addAttribute("plant", plants);
        return "updatePowerPlant";
    }

    @ResponseBody
    @GetMapping("failures/{id}")
    public long failures(@PathVariable("id") int id) {
        return eventService.NumberOfFailureEventsForId(id);
    }

    @ResponseBody
    @GetMapping("powerPlants")
    public List<PowerPlant> findAll() {
        return powerPlantRepository.findAll();
    }

    @GetMapping("powerPlants/{id}")
    public String findById(@PathVariable("id") Integer id, Model model) {
        model.addAttribute("plant", powerPlantRepository.getOne(id));

        return "plant";
    }

    @GetMapping("delete/powerPlants")
    public String deleteById(@RequestParam(value = "id") Integer id) {
        powerPlantRepository.deleteById(id);
        return "redirect:/powerPlants";
    }

    @GetMapping("addEventToPlant")
    public String addEventToPlant(@RequestParam(value = "plantId") Long plantId, @RequestParam(value = "eventId")
            Long eventId, Model model) {

        if (powerPlantRepository.findById(Math.toIntExact(plantId)).isPresent()
                && eventRepository.findById(Math.toIntExact(eventId)).isPresent()) {
            var pl = powerPlantRepository.getOne(Math.toIntExact(plantId));
            var ev = eventRepository.getOne(Math.toIntExact(eventId));

            var eventsForPlant = pl.getEvents();
            eventsForPlant.add(ev);
            pl.setEvents(eventsForPlant);

            powerPlantRepository.save(pl);
        }

        var t = powerPlantRepository.getOne(Math.toIntExact(plantId)).getEvents();
        model.addAttribute("plant", t);

        return "plant_events";
    }
}
</code>```

Service class

```<code>@org.springframework.stereotype.Service
@RequiredArgsConstructor
public class PlantService implements powerForPowerPlantPerDay, Add, PlantServiceToViewModel {

    private final EventRepository eventRepository;
    private final PowerPlantRepository powerPlantRepository;

    public Map<Integer, String> powerForPowerPlantPerDay(Timestamp date) {
        List<Event> list = new ArrayList<>(getAllEvents());
        Map<Integer, String> map = new HashMap<>();
        list.stream()
                .filter(e -> e.startDate.equals(date))
                .forEach(e -> map.put(e.id, e.typeOfEvent));
        return map;
    }

    public Collection<Event> getAllEvents() {
        return eventRepository.findAll();
    }

    public void add(PlantViewModel plantViewModel) {
        var p = PowerPlant.builder().
                name(plantViewModel.getName())
                .power(plantViewModel.getPower())
                .events(plantViewModel.getListOfEventsForPlant())
                .build();
        powerPlantRepository.save(p);
    }

    public PlantViewModel powerPlantToViewModel(PowerPlant powerPlant) {
        return PlantViewModel.builder()
                .id(powerPlant.getId())
                .name(powerPlant.getName())
                .power(powerPlant.getPower())
                .build();

    }

    public PowerPlant update(PlantViewModel plantViewModel) {
        var plant = powerPlantRepository.getOne(plantViewModel.getId());

        plant.setName(plantViewModel.getName());
        plant.setPower(plantViewModel.getPower());

        return powerPlantRepository.save(plant);
    }
}

</code>```

update html

```<code><!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"/>
</head>
<body>
<div class="container">
    <h1>Update</h1>
    <hr>
    <h2>Update powerPlant</h2>

    <form action="#" th:action="@{savePowerPlant}" th:object="${plant}" method="POST">
        <input id="studentId" th:value="${plant.id}" type="hidden" th:field="*{id}">
        <div th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Invalid Name</div>
        <input type="text" th:field="*{name}" placeholder="Name" class="form-control mb-4 col-4">

        <div th:if="${#fields.hasErrors('power')}" th:errors="*{power}">Invalid power</div>
        <input type="text" th:field="*{power}" placeholder="power" class="form-control mb-4 col-4">

        <button type="submit" class="btn btn-info col-2">Save</button>
    </form>
    <hr>
</div>
</body>
</html>
</code>```

save html

```<code><!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>New Student</title>

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"/>
</head>
<body>
<div class="container">
    <h1>Save</h1>
    <hr>
    <h2>Save powerPlant</h2>

    <form action="#" th:action="@{savePowerPlant}" th:object="${plant}" method="POST">
        <div th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Invalid Name</div>
        <input type="text" th:field="*{name}" placeholder="Name" class="form-control mb-4 col-4">

        <div th:if="${#fields.hasErrors('power')}" th:errors="*{power}">Invalid power</div>
        <input type="text" th:field="*{power}" placeholder="power" class="form-control mb-4 col-4">

        <button type="submit" class="btn btn-info col-2">Save</button>
    </form>
    <hr>
</div>
</body>
</html>
</code>```

答:
As you can see here in the documentation you are using relative URLs in your th:action. These get appended to the current URL in the address bar.

So th:action="@{savePowerPlant}" results in current/URL/savePowerPlant.

Simple solution is to switch to absolute URLs either by typing it out completely (http://localhost:portNumber/savePowerPlant) or perhaps even better use server relative URL: th:href="@{~/savePowerPlant}.

Title: Request method 'POST' not supported]

Body:
I have a problem with updatePowerPlant() method, when I try to update powerPlant entity with given id and click the submit button in the update form under localhost:8080/updatePowerPlant adress I get redirected to this url http://localhost:8080/updatePowerPlant/savePowerPlant.

I don't know why. I should get redireted to /powerPlants, wethever entity with given id exists or not, instead /savePowerPlant is added as a last part of a url localhost:8080/updatePowerPlant and I get  Request method 'POST' not supported], I know that this is the message I should get afterall there is no GetController with such url but why do I get this weird url? Is it because I use GetController for update?

localhost:8080/updatePowerPlant this I enter in browser to get update form
http://localhost:8080/updatePowerPlant/savePowerPlant this I get when I clik submit in update form

Controller class

@RequiredArgsConstructor
@Controller
public class PowerPlantsController {

    private final PowerPlantRepository powerPlantRepository;
    private final EventRepository eventRepository;
    private final PlantService plantService;
    private final EventService eventService;

    @GetMapping("form")
    public String getForm(Model model) {
        model.addAttribute("plant", new PlantViewModel());
        return "save";
    }

    @PostMapping("savePowerPlant")
    public String addPowerPlant(@ModelAttribute("plant") @Valid PlantViewModel plant, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            if (plant.getId() == null) {
                return "save";
            } else return "updatePowerPlant";
        }
        if (plant.getId() == null){
            plantService.add(plant);
        }else {
            plantService.update(plant);
        }
        return "redirect:/powerPlants";
    }

    @GetMapping("updatePowerPlant/{id}")
    public String updatePowerPlant(@PathVariable(value = "id") Integer id, Model model) {
        var find = powerPlantRepository.getOne(id);
        var plants = plantService.powerPlantToViewModel(find);
        model.addAttribute("plant", plants);
        return "updatePowerPlant";
    }

    @ResponseBody
    @GetMapping("failures/{id}")
    public long failures(@PathVariable("id") int id) {
        return eventService.NumberOfFailureEventsForId(id);
    }

    @ResponseBody
    @GetMapping("powerPlants")
    public List<PowerPlant> findAll() {
        return powerPlantRepository.findAll();
    }

    @GetMapping("powerPlants/{id}")
    public String findById(@PathVariable("id") Integer id, Model model) {
        model.addAttribute("plant", powerPlantRepository.getOne(id));

        return "plant";
    }

    @GetMapping("delete/powerPlants")
    public String deleteById(@RequestParam(value = "id") Integer id) {
        powerPlantRepository.deleteById(id);
        return "redirect:/powerPlants";
    }

    @GetMapping("addEventToPlant")
    public String addEventToPlant(@RequestParam(value = "plantId") Long plantId, @RequestParam(value = "eventId")
            Long eventId, Model model) {

        if (powerPlantRepository.findById(Math.toIntExact(plantId)).isPresent()
                && eventRepository.findById(Math.toIntExact(eventId)).isPresent()) {
            var pl = powerPlantRepository.getOne(Math.toIntExact(plantId));
            var ev = eventRepository.getOne(Math.toIntExact(eventId));

            var eventsForPlant = pl.getEvents();
            eventsForPlant.add(ev);
            pl.setEvents(eventsForPlant);

            powerPlantRepository.save(pl);
        }

        var t = powerPlantRepository.getOne(Math.toIntExact(plantId)).getEvents();
        model.addAttribute("plant", t);

        return "plant_events";
    }
}

Service class

@org.springframework.stereotype.Service
@RequiredArgsConstructor
public class PlantService implements powerForPowerPlantPerDay, Add, PlantServiceToViewModel {

    private final EventRepository eventRepository;
    private final PowerPlantRepository powerPlantRepository;

    public Map<Integer, String> powerForPowerPlantPerDay(Timestamp date) {
        List<Event> list = new ArrayList<>(getAllEvents());
        Map<Integer, String> map = new HashMap<>();
        list.stream()
                .filter(e -> e.startDate.equals(date))
                .forEach(e -> map.put(e.id, e.typeOfEvent));
        return map;
    }

    public Collection<Event> getAllEvents() {
        return eventRepository.findAll();
    }

    public void add(PlantViewModel plantViewModel) {
        var p = PowerPlant.builder().
                name(plantViewModel.getName())
                .power(plantViewModel.getPower())
                .events(plantViewModel.getListOfEventsForPlant())
                .build();
        powerPlantRepository.save(p);
    }

    public PlantViewModel powerPlantToViewModel(PowerPlant powerPlant) {
        return PlantViewModel.builder()
                .id(powerPlant.getId())
                .name(powerPlant.getName())
                .power(powerPlant.getPower())
                .build();

    }

    public PowerPlant update(PlantViewModel plantViewModel) {
        var plant = powerPlantRepository.getOne(plantViewModel.getId());

        plant.setName(plantViewModel.getName());
        plant.setPower(plantViewModel.getPower());

        return powerPlantRepository.save(plant);
    }
}

update html

<!DOCTYPE html>

    <meta charset="UTF-8">

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"/>

Update

Update powerPlant

    <form action="#" th:action="@{savePowerPlant}" th:object="${plant}" method="POST">
        <input id="studentId" th:value="${plant.id}" type="hidden" th:field="*{id}">

Invalid Name

        <input type="text" th:field="*{name}" placeholder="Name" class="form-control mb-4 col-4">

Invalid power

        <input type="text" th:field="*{power}" placeholder="power" class="form-control mb-4 col-4">

        <button type="submit" class="btn btn-info col-2">Save</button>
    </form>

save html

<!DOCTYPE html>

    <meta charset="UTF-8">
    <title>New Student</title>

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"/>

Save

Save powerPlant

    <form action="#" th:action="@{savePowerPlant}" th:object="${plant}" method="POST">

Invalid Name

        <input type="text" th:field="*{name}" placeholder="Name" class="form-control mb-4 col-4">

Invalid power

        <input type="text" th:field="*{power}" placeholder="power" class="form-control mb-4 col-4">

        <button type="submit" class="btn btn-info col-2">Save</button>
    </form>


问:
Dynamically remove mixin ancestor from class
I am trying to develop a simple card game console application in ruby as a pet project. One of the interactions I would like to add to this card game is something along the lines of "During your turn, you can buy cards as if they cost X less". Now, I thought about modelling this behaviour with the help of mixin decorators. Assuming the following class:

```<code>class Card
  attr_reader :cost

  def initialize(cost)
    self.cost = cost
  end

  def play(*_args)
    raise NotImplementedError, "Override me!"
  end

  private

  attr_writer :cost
end
</code>```

I thought a simple solution would be something like this:

```<code>class CardThatDiscounts < Card
  def play(*_args)
    @mod = Module.new do
      def cost
        super - 1
      end
    end

    Card.prepend(@mod)
  end
end
</code>```

This would give me the flexibility to target either the class itself, or specific instances of the cards. However, I am unsure of how to reverse this effect, at the end of the turn. I saw a few questions similar to this one, the answers of which said something along the lines of:

Remove the defined method manually.

This approach won't really work for me, since I am decorating existing methods instead of adding new ones. I could maybe rename the existing method when I prepend the module, and then return it back, but what happens in case I want to chain multiple such decorators?

Use gem mixology

Mixology is an old gem, and seems no longer maintained. Though, according to the documentation, it is exactly what I need. However, the implementation mostly deals with ruby internals, that I unfortunately do not understand. Is it not possible to modify a class ancestor chain from within Ruby, or do I need c/Java extension for this?

I considered other alternatives, such as SimpleDelegator or DelegateClass, but both of these require that I instantiate new objects, and then somehow replace references to existing Card objects with these new wrapped objects, and back again, at the end of turn. Which seemed a bit more involved than modifying the ancestry chain directly.

I suppose my question has 2 parts. Is it possible to remove a specific ancestor from a class's ancestor chain using pure ruby (since mixology gem already suggests it is possible to do with c/Java extensions)? If not, what would be a suitable workaround to get a similar behaviour?

答:
What you are trying to achieve is a very bad pattern. You should almost never use prepend or include dynamically, but model your code around the concepts you (and people possibly reading your code) do understand.

What you probably want to do is to create (some kind of) a Delegator called CardAffectedByEnvironment - and then instead of doing Card.new(x), you will always do CardAffectedByEnvironment.new(Card.new(x), env), where env will keep all your state changes, or add a method real_cost that would calculate things based on your cost and environment and use this method.

Below is a code with CardAffectedByEnvironment that would maybe describe better how I would assume it would work:

class Environment
  def initialize
    @modifiers = []
  end

  attr_reader :modifiers

  def next_round
    @modifiers = []
  end

  def modifiers_for(method)
    @modifiers.select { |i| i.first == method }
  end
end

class CardAffectedByEnvironment
  def initialize(card, env)
    @card, @env = card, env
  end

  # Since Ruby 3.0 you can write `...` instead of `*args, **kwargs, &block`
  def method_missing(method, *args, **kwargs, &block)
    value = @card.public_send(method, *args, **kwargs, &block)
    @env.modifiers_for(method).each do |_, modifier|
      value = modifier.call(value)
    end
    value
  end
end

class Joker
  def cost
    10
  end
end

env = Environment.new
card = CardAffectedByEnvironment.new(Joker.new, env)

p card.cost # => 10

env.modifiers << [:cost, ->(i) { i - 1 }]

p card.cost # => 9

env.next_round

p card.cost # => 10
```

Body:
I am trying to develop a simple card game console application in ruby as a pet project. One of the interactions I would like to add to this card game is something along the lines of "During your turn, you can buy cards as if they cost X less". Now, I thought about modelling this behaviour with the help of mixin decorators. Assuming the following class:

class Card
  attr_reader :cost

  def initialize(cost)
    self.cost = cost
  end

  def play(*_args)
    raise NotImplementedError, "Override me!"
  end

  private

  attr_writer :cost
end

I thought a simple solution would be something like this:

class CardThatDiscounts < Card
  def play(*_args)
    @mod = Module.new do
      def cost
        super - 1
      end
    end

    Card.prepend(@mod)
  end
end

This would give me the flexibility to target either the class itself, or specific instances of the cards. However, I am unsure of how to reverse this effect, at the end of the turn. I saw a few questions similar to this one, the answers of which said something along the lines of:

Remove the defined method manually.

This approach won't really work for me, since I am decorating existing methods instead of adding new ones. I could maybe rename the existing method when I prepend the module, and then return it back, but what happens in case I want to chain multiple such decorators?

Use gem mixology

Mixology is an old gem, and seems no longer maintained. Though, according to the documentation, it is exactly what I need. However, the implementation mostly deals with ruby internals, that I unfortunately do not understand. Is it not possible to modify a class ancestor chain from within Ruby, or do I need c/Java extension for this?

I considered other alternatives, such as SimpleDelegator or DelegateClass, but both of these require that I instantiate new objects, and then somehow replace references to existing Card objects with these new wrapped objects, and back again, at the end of turn. Which seemed a bit more involved than modifying the ancestry chain directly.

I suppose my question has 2 parts. Is it possible to remove a specific ancestor from a class's ancestor chain using pure ruby (since mixology gem already suggests it is possible to do with c/Java extensions)? If not, what would be a suitable workaround to get a similar behaviour?


问:
Very slow join query on large table (machine = Xeon 2.4 GHz, 16 core, 64 GB RAM)
Here is my query :

```<code>SELECT  email_data.id, email_data.source_file, email_data.report_id,
        email_data.filePath, email_data.fileName, email_data.size,
        email_data.emailID, email_data.msgID, email_data.cus, email_data.subject,
        email_data.sentto, email_data.emailFrom, email_data.hdrs, email_data.cc,
        email_data.bcc, email_data.extracted, email_data.DateTime,
        email_data.TimeStamp, email_data.OriginalDateTime, email_data.ParentID,
        email_data.reply_to, email_data.MD5Hash, email_data.duplicated,
        email_data.TimeZone, email_data.AttachName, email_data.fqdn,
        attach_data.id, attach_data.source_file, attach_data.report_id,
        attach_data.filePath, attach_data.fileName, attach_data.size, attach_data.ext,
        attach_data.emailID, attach_data.cus, attach_data.extracted,
        attach_data.MD5Hash, attach_data.duplicated
FROM email_data
LEFT JOIN attach_data
ON (email_data.emailID = attach_data.emailID);
</code>```

Combination of both of the table has 50k + records (email_data have 22k records and other have 30K + records).

Above query takes over 90 mins and still not finished.

This one :

```<code>SELECT email_data.id, attach_data.id
FROM email_data
LEFT JOIN attach_data
ON (email_data.emailID = attach_data.emailID);
</code>```

takes 2 mins 22 sec:

What am I doing wrong? It seems that MySQL do not using enough memory to speed things up, and it only uses 1 core out of 16 cores.

How can I configure it to use all available resources?

Or should I query IDs (as in 2nd query) and loop + select each of them back in my code? Will it cause same result?

I needs all those fields and all the row, I am converting them into Custom CSV-Like format so it can be exported to other software.

Columns :

```<code>mysql> show columns from email_data;
+------------------+----------+------+-----+---------+----------------+
| Field            | Type     | Null | Key | Default | Extra          |
+------------------+----------+------+-----+---------+----------------+
| id               | int(11)  | NO   | PRI | NULL    | auto_increment |
| source_file      | longtext | YES  |     | NULL    |                |
| report_id        | int(11)  | YES  |     | NULL    |                |
| filePath         | longtext | YES  |     | NULL    |                |
| fileName         | longtext | YES  |     | NULL    |                |
| size             | int(11)  | YES  |     | NULL    |                |
| emailID          | longtext | YES  |     | NULL    |                |
| msgID            | longtext | YES  |     | NULL    |                |
| cus              | longtext | YES  |     | NULL    |                |
| subject          | longtext | YES  |     | NULL    |                |
| sentto           | longtext | YES  |     | NULL    |                |
| emailFrom        | longtext | YES  |     | NULL    |                |
| hdrs             | longtext | YES  |     | NULL    |                |
| cc               | longtext | YES  |     | NULL    |                |
| bcc              | longtext | YES  |     | NULL    |                |
| extracted        | longtext | YES  |     | NULL    |                |
| DateTime         | char(1)  | YES  |     | NULL    |                |
| TimeStamp        | int(11)  | YES  |     | NULL    |                |
| OriginalDateTime | char(1)  | YES  |     | NULL    |                |
| ParentID         | longtext | YES  |     | NULL    |                |
| reply_to         | longtext | YES  |     | NULL    |                |
| MD5Hash          | longtext | YES  |     | NULL    |                |
| duplicated       | char(1)  | YES  |     | NULL    |                |
| TimeZone         | char(1)  | YES  |     | NULL    |                |
| AttachName       | longtext | YES  |     | NULL    |                |
| fqdn             | longtext | YES  |     | NULL    |                |
+------------------+----------+------+-----+---------+----------------+
</code>```

Almost same for attach_data

答: I think that you are confusing the optimizer. Try adding an index for attach_data.emailID. You can use EXPLAIN statement to figure out what's going on.

Body:
Here is my query :

SELECT  email_data.id, email_data.source_file, email_data.report_id,
        email_data.filePath, email_data.fileName, email_data.size,
        email_data.emailID, email_data.msgID, email_data.cus, email_data.subject,
        email_data.sentto, email_data.emailFrom, email_data.hdrs, email_data.cc,
        email_data.bcc, email_data.extracted, email_data.DateTime,
        email_data.TimeStamp, email_data.OriginalDateTime, email_data.ParentID,
        email_data.reply_to, email_data.MD5Hash, email_data.duplicated,
        email_data.TimeZone, email_data.AttachName, email_data.fqdn,
        attach_data.id, attach_data.source_file, attach_data.report_id,
        attach_data.filePath, attach_data.fileName, attach_data.size, attach_data.ext,
        attach_data.emailID, attach_data.cus, attach_data.extracted,
        attach_data.MD5Hash, attach_data.duplicated
FROM email_data
LEFT JOIN attach_data
ON (email_data.emailID = attach_data.emailID);

Combination of both of the table has 50k + records (email_data have 22k records and other have 30K + records).

Above query takes over 90 mins and still not finished.

This one :

SELECT email_data.id, attach_data.id
FROM email_data
LEFT JOIN attach_data
ON (email_data.emailID = attach_data.emailID);

takes 2 mins 22 sec:

What am I doing wrong? It seems that MySQL do not using enough memory to speed things up, and it only uses 1 core out of 16 cores.

How can I configure it to use all available resources?

Or should I query IDs (as in 2nd query) and loop + select each of them back in my code? Will it cause same result?

I needs all those fields and all the row, I am converting them into Custom CSV-Like format so it can be exported to other software.

Columns :

mysql> show columns from email_data;
+------------------+----------+------+-----+---------+----------------+
| Field            | Type     | Null | Key | Default | Extra          |
+------------------+----------+------+-----+---------+----------------+
| id               | int(11)  | NO   | PRI | NULL    | auto_increment |
| source_file      | longtext | YES  |     | NULL    |                |
| report_id        | int(11)  | YES  |     | NULL    |                |
| filePath         | longtext | YES  |     | NULL    |                |
| fileName         | longtext | YES  |     | NULL    |                |
| size             | int(11)  | YES  |     | NULL    |                |
| emailID          | longtext | YES  |     | NULL    |                |
| msgID            | longtext | YES  |     | NULL    |                |
| cus              | longtext | YES  |     | NULL    |                |
| subject          | longtext | YES  |     | NULL    |                |
| sentto           | longtext | YES  |     | NULL    |                |
| emailFrom        | longtext | YES  |     | NULL    |                |
| hdrs             | longtext | YES  |     | NULL    |                |
| cc               | longtext | YES  |     | NULL    |                |
| bcc              | longtext | YES  |     | NULL    |                |
| extracted        | longtext | YES  |     | NULL    |                |
| DateTime         | char(1)  | YES  |     | NULL    |                |
| TimeStamp        | int(11)  | YES  |     | NULL    |                |
| OriginalDateTime | char(1)  | YES  |     | NULL    |                |
| ParentID         | longtext | YES  |     | NULL    |                |
| reply_to         | longtext | YES  |     | NULL    |                |
| MD5Hash          | longtext | YES  |     | NULL    |                |
| duplicated       | char(1)  | YES  |     | NULL    |                |
| TimeZone         | char(1)  | YES  |     | NULL    |                |
| AttachName       | longtext | YES  |     | NULL    |                |
| fqdn             | longtext | YES  |     | NULL    |                |
+------------------+----------+------+-----+---------+----------------+

Almost same for attach_data


问:
Powershell assignment in expression?
Does Powershell have an operator like Python's :=, which can assign a variable within an expression? (e.g., if (match := pattern.search(data)) is not None)

Suppose I want to store a value in Powershell as a variable, but also pass it down the pipeline. Is there a more elegant way than ...| ForEach-Object { $foo = $_.split(': ')[1]; $foo } |...?

答:
You can use (...), the grouping operator to turn an assignment statement into an expression that passes the value being assigned through:

This allows you to simplify:

...| ForEach-Object { $foo = $_.split(': ')[1]; $foo }
```
<p>to:</p>
<pre class="lang-sh prettyprint-override"><code>...| ForEach-Object { ($foo = $_.split(': ')[1]) }
</code>```

The above technique works in all contexts; notably:

conditionals:

if ($files = Get-ChildItem *.txt) {
  "$($files.Count) text file(s) found."
} else {
  "No text file(s) found."
}
```
</li>
<li><p>inside a <em>single</em> expression:</p>
<pre class="lang-sh prettyprint-override"><code>($x = 2) * $x # -> 4
</code>```

For use across multiple script blocks in the context of a  single pipeline (as your example suggests), the use of the common -PipelineVariable (-pv) parameter may offer a more elegant solution, as shown in zett42's helpful answer.

Title: Powershell assignment in expression?

Body:
You can use (...), the grouping operator to turn an assignment statement into an expression that passes the value being assigned through:

This allows you to simplify:

...| ForEach-Object { $foo = $_.split(': ')[1]; $foo }

to:

...| ForEach-Object { ($foo = $_.split(': ')[1]) }

The above technique works in all contexts; notably:

conditionals:

if ($files = Get-ChildItem *.txt) {
  "$($files.Count) text file(s) found."
} else {
  "No text file(s) found."
}

inside a single expression:

($x = 2) * $x # -> 4

For use across multiple script blocks in the context of a  single pipeline (as your example suggests), the use of the common -PipelineVariable (-pv) parameter may offer a more elegant solution, as shown in zett42's helpful answer.


问:
Can`t unsubscribe and stop work of event hendler on C# in Windows Forms
enter image description here

I load some text in textbox, than it disapears, when I write in textbox("Tb" in code), than I can change text with buttons(S by one button, S1 by enother), but after some changes handler ”main_change” eats mostly all the text.

I wanted previous text disapear when I input but not mostly all. What I have triyed I can`t stop handler “main_change”.

More readeble code:

```<code>   this.Load+= S;
    }

    //запускаеться кнопкой 1(button1 на скрине)
    public void S(object sender, EventArgs e)
    {
        textbox.Text="Привіт";
        textbox.TextChanged+=main_change;
    }

    //после ввода удаляет текст и виводит в textbox последнюю букву
    public void main_change(object sender, EventArgs e){

        t=textbox.Text;
        textbox.Text=t[t.Length-1].ToString();
        }
        textbox.Select(textbox.Text.Length, 0);

        // пробую остановить обработчик
        textbox.TextChanged-=main_change;
    }

    void S1(object sender, EventArgs e)
    {
        //запускаеться собитие нажатием кнопки 2(button1 на скрине)
        this.Back.Click+=S;

        textbox.Text="Тест";

        ////тоже пробую остановить обработчик
        textbox.TextChanged-=main_change;
    }
</code>```

Actual version of the code:

```<code>   int s1 = 0;
   int s2 = 0;
   int s3 = 0;
   int s4 = 0;
   string ss = " ";
  string ss1 = " ";
  string ss2 = " ";
  int t1 = 0;
 string t = " ";

 public MainForm()
 {
InitializeComponent();

//добавляю сюда
this.Load += S;
//S(null,null);
 }

 public void S(object sender, EventArgs e)
 {
//this.Load -= main_change;
Tb.Text = "Hello";
t1++;
Tb.TextChanged += main_change;
//main_change(null, null);

l.Text = t1.ToString();
  }

  public void main_change(object sender, EventArgs e)
{
if (t1 == 1)
{
    t = Tb.Text;
    Tb.Text = t[t.Length - 1].ToString();
    t1 = 0;
}
Tb.Select(Tb.Text.Length, 0);

l.Text = t1.ToString();
return;
//Tb.TextChanged -= main_change;
//this.Back.Click += S;
//Tb.TextChanged -= main_change;
}

  void S1(object sender, EventArgs e)
 {
this.Back.Click += S;
//if(s2 == 0){
Tb.Text = "Text";
l.Text = t1.ToString();
this.Load += S;
//s2 = 0;

Tb.TextChanged -= main_change;
 }
</code>```

答:
Correct me if I am wrong but you are trying to remove a few characters from the textbox by clicking on the buttons, right ?

Perhaps you can achieve this by setting the focus and the selection at the end of the textbox, and then use the SendKeys.Send("{BS}") (since .Net 1.1) each time you want to remove a character. This method works as if you typed the backspace key on your keyboard.

Also in the private event handler method main_changed, try during debug to spy on the sender parameter, so that you will determine which control send the event.
Then by surrounding the body of the event handler with a condition that tests if the sender is one of the two buttons, you can decide to do something or not.

```<code>public void main_change(object sender, EventArgs e)
{
    if(sender is Button &&
        ((Button)sender).Name == "button1" || ((Button)sender).Name == "button2" )
    {
        // Do something here.
    }
    else
    {
        // Do something else here.
    }
}
</code>```

Read: https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.sendkeys.send?view=windowsdesktop-6.0

Body:
enter image description here

I load some text in textbox, than it disapears, when I write in textbox("Tb" in code), than I can change text with buttons(S by one button, S1 by enother), but after some changes handler ”main_change” eats mostly all the text.

I wanted previous text disapear when I input but not mostly all. What I have triyed I can`t stop handler “main_change”.

More readeble code:

   this.Load+= S;
    }

    //запускаеться кнопкой 1(button1 на скрине)
    public void S(object sender, EventArgs e)
    {
        textbox.Text="Привіт";
        textbox.TextChanged+=main_change;
    }

    //после ввода удаляет текст и виводит в textbox последнюю букву
    public void main_change(object sender, EventArgs e){

        t=textbox.Text;
        textbox.Text=t[t.Length-1].ToString();
        }
        textbox.Select(textbox.Text.Length, 0);

        // пробую остановить обработчик
        textbox.TextChanged-=main_change;
    }

    void S1(object sender, EventArgs e)
    {
        //запускаеться собитие нажатием кнопки 2(button1 на скрине)
        this.Back.Click+=S;

        textbox.Text="Тест";

        ////тоже пробую остановить обработчик
        textbox.TextChanged-=main_change;
    }

Actual version of the code:

   int s1 = 0;
   int s2 = 0;
   int s3 = 0;
   int s4 = 0;
   string ss = " ";
  string ss1 = " ";
  string ss2 = " ";
  int t1 = 0;
 string t = " ";

 public MainForm()
 {
InitializeComponent();

//добавляю сюда
this.Load += S;
//S(null,null);
 }

 public void S(object sender, EventArgs e)
 {
//this.Load -= main_change;
Tb.Text = "Hello";
t1++;
Tb.TextChanged += main_change;
//main_change(null, null);

l.Text = t1.ToString();
  }

  public void main_change(object sender, EventArgs e)
{
if (t1 == 1)
{
    t = Tb.Text;
    Tb.Text = t[t.Length - 1].ToString();
    t1 = 0;
}
Tb.Select(Tb.Text.Length, 0);

l.Text = t1.ToString();
return;
//Tb.TextChanged -= main_change;
//this.Back.Click += S;
//Tb.TextChanged -= main_change;
}

  void S1(object sender, EventArgs e)
 {
this.Back.Click += S;
//if(s2 == 0){
Tb.Text = "Text";
l.Text = t1.ToString();
this.Load += S;
//s2 = 0;

Tb.TextChanged -= main_change;
 }

Body:
Correct me if I am wrong but you are trying to remove a few characters from the textbox by clicking on the buttons, right ?

Perhaps you can achieve this by setting the focus and the selection at the end of the textbox, and then use the SendKeys.Send("{BS}") (since .Net 1.1) each time you want to remove a character. This method works as if you typed the backspace key on your keyboard.

Also in the private event handler method main_changed, try during debug to spy on the sender parameter, so that you will determine which control send the event.
Then by surrounding the body of the event handler with a condition that tests if the sender is one of the two buttons, you can decide to do something or not.

public void main_change(object sender, EventArgs e)
{
    if(sender is Button &&
        ((Button)sender).Name == "button1" || ((Button)sender).Name == "button2" )
    {
        // Do something here.
    }
    else
    {
        // Do something else here.
    }
}

Read: https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.sendkeys.send?view=windowsdesktop-6.0


问:
First Discord Bot
I am literally just trying to get this bot online first. It keeps throwing bitfield error. I am guessing I need to add permissions but not sure the best way to go about it.I am brand new to this.

require('dotenv').config();

const { Client,Intents,BitField} = require('discord.js'); const
client= new Client({ intents: Intents.FLAGS.GUILDS});
client.login(process.env.DISCORDJS_BOT_TOKEN);

ERROR:

RangeError [BITFIELD_INVALID]: Invalid bitfield flag or number: undefined.
at Function.resolve (C:\Users\tayla\documents\discord-bot\node_modules\discord.js\src\util\BitField.js:152:11)

at C:\Users\tayla\documents\discord-bot\node_modules\discord.js\src\util\BitField.js:147:54
at Array.map ()
at Function.resolve (C:\Users\tayla\documents\discord-bot\node_modules\discord.js\src\util\BitField.js:147:40)

at Client._validateOptions (C:\Users\tayla\documents\discord-bot\node_modules\discord.js\src\client\Client.js:550:33)
at new Client (C:\Users\tayla\documents\discord-bot\node_modules\discord.js\src\client\Client.js:76:10)
at Object. (C:\Users\tayla\documents\discord-bot\src\bot.js:4:15)
at Module._compile (node:internal/modules/cjs/loader:1101:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32) {
[Symbol(code)]: 'BITFIELD_INVALID'
}

答: Try putting Intents.FLAGS.GUILDS into an array as shown in the documentation. intents: [Intents.FLAGS.GUILDS]

Title: First Discord Bot


问:
EF 4.1, POCO: Reference type properties are not updated in case AutoDetectChanges=false
EF 4.1, POCO: I turned off AutoDetectChanges (Configuration.AutoDetectChangesEnabled = false) to speed up data update. Then I run Add or Attach with entity state changed to EntityState.Modified. All this causes references to other objects not being updated in database. However all scalar properties are updated successfully.

Profiler shown EF generates SQL update operation for every scalar property, but not for reference type, though I really changed its value in my code. This issue reproduced for every type of entity in my model.

Add operation or Attach with EntityState.Added both work fine. If I turn AutoDetectChanges back on, everything works fine as expected for updated records too.

Help me please to figure out what's wrong. I can not find any good comprehensive documentation on EF's Detect Changes.

UPDATE

I was asked to put some example of code to reproduce the issue. Domain:

```<code>public class Client
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual Address Address { get; set; }
}

public class Address
{
    public int Id { get; set; }
    public virtual string City { get; set; }
}
</code>```

DataContext:

```<code>public class DataContext : DbContext
{

    public DbSet<Client> Clients { get; set; }
    public DbSet<Address> Address { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Client>().HasOptional(c => c.Address);
    }
}
</code>```

Add one record to Clint table and one to Address. Point Client to the Address. Then run the following code:

```<code>using (var cntx = new DataContext())
{
    cntx.Configuration.AutoDetectChangesEnabled = false; // Reason of problem
    var client = cntx.Clients.First();
    client.Name = "Anna"; // This property will be updated
    client.Address = null;  // This property will not be updated
    cntx.Clients.Attach(client);
    cntx.Entry(client).State = EntityState.Modified;
    cntx.SaveChanges();
}
</code>```

This code does generates SQL script like this:

```<code>update [dbo].[Clients] set [Name] = 'Anna'
where ([Id] = 1)
</code>```

Set AutoDetectChangesEnabled to true and run the code again, this time everything alright:

```<code>update [dbo].[Clients]
set [Name] = 'Anna', [Address_Id] = null
where (([Id] = 1) and [Address_Id]=1)
</code>```

Note it does not matter if you change Address's value from specific value to null, or back to specific value, or one concrete value to other concrete value, any change is not tracked while AutoDetectChanges=false. Seems like EF bug.

答:
Well, I found out the way to set Reference property values that works even with AutoDetectChangesEnabled=false:

```<code>cntx.Entry(client).Reference(c => c.Address).CurrentValue = null;
</code>```

However I definitely do not like it. 1) Code looks ugly; 2) You have to have access to context to make it work, which is not my case, I'd like this property being set outside of repository which only has access to DbContext. Is any other simpler way to let EF know the property value is changed?

Updated: Ok, I found simpler workaround: just run cntx.ChangeTracker.DetectChanges() before running cntx.SaveChanges(). It helps EF generate correct SQL update script

Body:
EF 4.1, POCO: I turned off AutoDetectChanges (Configuration.AutoDetectChangesEnabled = false) to speed up data update. Then I run Add or Attach with entity state changed to EntityState.Modified. All this causes references to other objects not being updated in database. However all scalar properties are updated successfully.

Profiler shown EF generates SQL update operation for every scalar property, but not for reference type, though I really changed its value in my code. This issue reproduced for every type of entity in my model.

Add operation or Attach with EntityState.Added both work fine. If I turn AutoDetectChanges back on, everything works fine as expected for updated records too.

Help me please to figure out what's wrong. I can not find any good comprehensive documentation on EF's Detect Changes.

UPDATE

I was asked to put some example of code to reproduce the issue. Domain:

public class Client
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual Address Address { get; set; }
}

public class Address
{
    public int Id { get; set; }
    public virtual string City { get; set; }
}

DataContext:

public class DataContext : DbContext
{

    public DbSet<Client> Clients { get; set; }
    public DbSet<Address> Address { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Client>().HasOptional(c => c.Address);
    }
}

Add one record to Clint table and one to Address. Point Client to the Address. Then run the following code:

using (var cntx = new DataContext())
{
    cntx.Configuration.AutoDetectChangesEnabled = false; // Reason of problem
    var client = cntx.Clients.First();
    client.Name = "Anna"; // This property will be updated
    client.Address = null;  // This property will not be updated
    cntx.Clients.Attach(client);
    cntx.Entry(client).State = EntityState.Modified;
    cntx.SaveChanges();
}

This code does generates SQL script like this:

update [dbo].[Clients] set [Name] = 'Anna'
where ([Id] = 1)

Set AutoDetectChangesEnabled to true and run the code again, this time everything alright:

update [dbo].[Clients]
set [Name] = 'Anna', [Address_Id] = null
where (([Id] = 1) and [Address_Id]=1)

Note it does not matter if you change Address's value from specific value to null, or back to specific value, or one concrete value to other concrete value, any change is not tracked while AutoDetectChanges=false. Seems like EF bug.

Body:
Well, I found out the way to set Reference property values that works even with AutoDetectChangesEnabled=false:

cntx.Entry(client).Reference(c => c.Address).CurrentValue = null;

However I definitely do not like it. 1) Code looks ugly; 2) You have to have access to context to make it work, which is not my case, I'd like this property being set outside of repository which only has access to DbContext. Is any other simpler way to let EF know the property value is changed?

Updated: Ok, I found simpler workaround: just run cntx.ChangeTracker.DetectChanges() before running cntx.SaveChanges(). It helps EF generate correct SQL update script